summaryrefslogtreecommitdiff
path: root/src/fluxbox.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/fluxbox.cc')
-rw-r--r--src/fluxbox.cc228
1 files changed, 88 insertions, 140 deletions
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index 8b9e39a..80d055b 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -206,7 +206,6 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
206 m_rc_menufile(m_resourcemanager, DEFAULTMENU, "session.menuFile", "Session.MenuFile"), 206 m_rc_menufile(m_resourcemanager, DEFAULTMENU, "session.menuFile", "Session.MenuFile"),
207 m_rc_keyfile(m_resourcemanager, DEFAULTKEYSFILE, "session.keyFile", "Session.KeyFile"), 207 m_rc_keyfile(m_resourcemanager, DEFAULTKEYSFILE, "session.keyFile", "Session.KeyFile"),
208 m_rc_slitlistfile(m_resourcemanager, "~/." + realProgramName("fluxbox") + "/slitlist", "session.slitlistFile", "Session.SlitlistFile"), 208 m_rc_slitlistfile(m_resourcemanager, "~/." + realProgramName("fluxbox") + "/slitlist", "session.slitlistFile", "Session.SlitlistFile"),
209 m_rc_groupfile(m_resourcemanager, "~/." + realProgramName("fluxbox") + "/groups", "session.groupFile", "Session.GroupFile"),
210 m_rc_appsfile(m_resourcemanager, "~/." + realProgramName("fluxbox") + "/apps", "session.appsFile", "Session.AppsFile"), 209 m_rc_appsfile(m_resourcemanager, "~/." + realProgramName("fluxbox") + "/apps", "session.appsFile", "Session.AppsFile"),
211 m_rc_tabs_attach_area(m_resourcemanager, ATTACH_AREA_WINDOW, "session.tabsAttachArea", "Session.TabsAttachArea"), 210 m_rc_tabs_attach_area(m_resourcemanager, ATTACH_AREA_WINDOW, "session.tabsAttachArea", "Session.TabsAttachArea"),
212 m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"), 211 m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"),
@@ -320,6 +319,11 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
320#endif // HAVE_GETPID 319#endif // HAVE_GETPID
321 320
322 321
322 // Create keybindings handler and load keys file
323 // Note: this needs to be done before creating screens
324 m_key.reset(new Keys);
325 m_key->load(StringUtil::expandFilename(*m_rc_keyfile).c_str());
326
323 vector<int> screens; 327 vector<int> screens;
324 int i; 328 int i;
325 329
@@ -415,10 +419,6 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile
415 419
416 m_reconfigure_wait = m_reread_menu_wait = false; 420 m_reconfigure_wait = m_reread_menu_wait = false;
417 421
418 // Create keybindings handler and load keys file
419 m_key.reset(new Keys);
420 m_key->load(StringUtil::expandFilename(*m_rc_keyfile).c_str());
421
422 m_resourcemanager.unlock(); 422 m_resourcemanager.unlock();
423 ungrab(); 423 ungrab();
424 424
@@ -545,8 +545,11 @@ void Fluxbox::eventLoop() {
545 545
546 if (last_bad_window != None && e.xany.window == last_bad_window && 546 if (last_bad_window != None && e.xany.window == last_bad_window &&
547 e.type != DestroyNotify) { // we must let the actual destroys through 547 e.type != DestroyNotify) { // we must let the actual destroys through
548 if (e.type == FocusOut)
549 m_revert_timer.start();
548#ifdef DEBUG 550#ifdef DEBUG
549 cerr<<"Fluxbox::eventLoop(): removing bad window from event queue"<<endl; 551 else
552 cerr<<"Fluxbox::eventLoop(): removing bad window from event queue"<<endl;
550#endif // DEBUG 553#endif // DEBUG
551 } else { 554 } else {
552 last_bad_window = None; 555 last_bad_window = None;
@@ -640,7 +643,7 @@ void Fluxbox::setupConfigFiles() {
640 if (create_init) 643 if (create_init)
641 FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str()); 644 FbTk::FileUtil::copyFile(DEFAULT_INITFILE, init_file.c_str());
642 645
643#define CONFIG_VERSION 1 646#define CONFIG_VERSION 3
644 FbTk::Resource<int> config_version(m_resourcemanager, 0, 647 FbTk::Resource<int> config_version(m_resourcemanager, 0,
645 "session.configVersion", "Session.ConfigVersion"); 648 "session.configVersion", "Session.ConfigVersion");
646 if (*config_version < CONFIG_VERSION) { 649 if (*config_version < CONFIG_VERSION) {
@@ -1019,41 +1022,6 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) {
1019 winclient->fbwindow()->iconify(); 1022 winclient->fbwindow()->iconify();
1020 if (ce.data.l[0] == NormalState) 1023 if (ce.data.l[0] == NormalState)
1021 winclient->fbwindow()->deiconify(); 1024 winclient->fbwindow()->deiconify();
1022 } else if (ce.message_type == m_fbatoms->getFluxboxChangeWorkspaceAtom()) {
1023 BScreen *screen = searchScreen(ce.window);
1024
1025 if (screen && ce.data.l[0] >= 0 &&
1026 ce.data.l[0] < (signed)screen->numberOfWorkspaces())
1027 screen->changeWorkspaceID(ce.data.l[0]);
1028
1029 } else if (ce.message_type == m_fbatoms->getFluxboxChangeWindowFocusAtom()) {
1030 WinClient *winclient = searchWindow(ce.window);
1031 if (winclient) {
1032 FluxboxWindow *win = winclient->fbwindow();
1033 if (win && win->isVisible())
1034 win->setCurrentClient(*winclient, true);
1035 }
1036 } else if (ce.message_type == m_fbatoms->getFluxboxCycleWindowFocusAtom()) {
1037 BScreen *screen = searchScreen(ce.window);
1038
1039 if (screen) {
1040 if (! ce.data.l[0])
1041 screen->focusControl().prevFocus();
1042 else
1043 screen->focusControl().nextFocus();
1044 }
1045 } else if (ce.message_type == m_fbatoms->getFluxboxChangeAttributesAtom()) {
1046 WinClient *winclient = searchWindow(ce.window);
1047 FluxboxWindow *win = 0;
1048 if (winclient && (win = winclient->fbwindow()) && winclient->validateClient()) {
1049 FluxboxWindow::BlackboxHints net;
1050 net.flags = ce.data.l[0];
1051 net.attrib = ce.data.l[1];
1052 net.workspace = ce.data.l[2];
1053 net.stack = ce.data.l[3];
1054 net.decoration = static_cast<int>(ce.data.l[4]);
1055 win->changeBlackboxHints(net);
1056 }
1057 } else { 1025 } else {
1058 WinClient *winclient = searchWindow(ce.window); 1026 WinClient *winclient = searchWindow(ce.window);
1059 BScreen *screen = searchScreen(ce.window); 1027 BScreen *screen = searchScreen(ce.window);
@@ -1117,73 +1085,92 @@ void Fluxbox::handleSignal(int signum) {
1117 1085
1118void Fluxbox::update(FbTk::Subject *changedsub) { 1086void Fluxbox::update(FbTk::Subject *changedsub) {
1119 //TODO: fix signaling, this does not look good 1087 //TODO: fix signaling, this does not look good
1088 FluxboxWindow *fbwin = 0;
1089 WinClient *client = 0;
1090
1120 if (typeid(*changedsub) == typeid(FluxboxWindow::WinSubject)) { 1091 if (typeid(*changedsub) == typeid(FluxboxWindow::WinSubject)) {
1121 FluxboxWindow::WinSubject *winsub = dynamic_cast<FluxboxWindow::WinSubject *>(changedsub); 1092 FluxboxWindow::WinSubject *winsub = dynamic_cast<FluxboxWindow::WinSubject *>(changedsub);
1122 FluxboxWindow &win = winsub->win(); 1093 fbwin = &winsub->win();
1123 if ((&(win.hintSig())) == changedsub) { // hint signal 1094 } else if (typeid(*changedsub) == typeid(Focusable::FocusSubject)) {
1124 for (AtomHandlerContainerIt it= m_atomhandler.begin(); 1095 Focusable::FocusSubject *winsub = dynamic_cast<Focusable::FocusSubject *>(changedsub);
1125 it != m_atomhandler.end(); ++it) { 1096 fbwin = winsub->win().fbwindow();
1126 if ( (*it).first->update()) 1097 if (typeid(winsub->win()) == typeid(WinClient))
1127 (*it).first->updateHints(win); 1098 client = dynamic_cast<WinClient *>(&winsub->win());
1128 } 1099 }
1129 } else if ((&(win.stateSig())) == changedsub) { // state signal
1130 for (AtomHandlerContainerIt it= m_atomhandler.begin();
1131 it != m_atomhandler.end(); ++it) {
1132 if ((*it).first->update())
1133 (*it).first->updateState(win);
1134 }
1135 // if window changed to iconic state
1136 // add to icon list
1137 if (win.isIconic()) {
1138 win.screen().addIcon(&win);
1139 Workspace *space = win.screen().getWorkspace(win.workspaceNumber());
1140 if (space != 0)
1141 space->removeWindow(&win, true);
1142 }
1143 1100
1144 if (win.isStuck()) { 1101 if (fbwin && &fbwin->stateSig() == changedsub) { // state signal
1145 // if we're sticky then reassociate window 1102 for (AtomHandlerContainerIt it= m_atomhandler.begin();
1146 // to all workspaces 1103 it != m_atomhandler.end(); ++it) {
1147 BScreen &scr = win.screen(); 1104 if ((*it).first->update())
1148 if (scr.currentWorkspaceID() != win.workspaceNumber()) { 1105 (*it).first->updateState(*fbwin);
1149 scr.reassociateWindow(&win, 1106 }
1150 scr.currentWorkspaceID(), 1107 // if window changed to iconic state
1151 true); 1108 // add to icon list
1152 } 1109 if (fbwin->isIconic()) {
1153 } 1110 fbwin->screen().addIcon(fbwin);
1154 } else if ((&(win.layerSig())) == changedsub) { // layer signal 1111 Workspace *space = fbwin->screen().getWorkspace(fbwin->workspaceNumber());
1112 if (space != 0)
1113 space->removeWindow(fbwin, true);
1114 }
1155 1115
1156 for (AtomHandlerContainerIt it= m_atomhandler.begin(); 1116 if (fbwin->isStuck()) {
1157 it != m_atomhandler.end(); ++it) { 1117 // if we're sticky then reassociate window
1158 if ((*it).first->update()) 1118 // to all workspaces
1159 (*it).first->updateLayer(win); 1119 BScreen &scr = fbwin->screen();
1120 if (scr.currentWorkspaceID() != fbwin->workspaceNumber()) {
1121 scr.reassociateWindow(fbwin,
1122 scr.currentWorkspaceID(),
1123 true);
1160 } 1124 }
1161 } else if ((&(win.dieSig())) == changedsub) { // window death signal 1125 }
1126 } else if (fbwin && &fbwin->layerSig() == changedsub) { // layer signal
1127 AtomHandlerContainerIt it= m_atomhandler.begin();
1128 for (; it != m_atomhandler.end(); ++it) {
1129 if ((*it).first->update())
1130 (*it).first->updateLayer(*fbwin);
1131 }
1132 } else if (fbwin && &fbwin->dieSig() == changedsub) { // window death signal
1133 AtomHandlerContainerIt it= m_atomhandler.begin();
1134 for (; it != m_atomhandler.end(); ++it) {
1135 if ((*it).first->update())
1136 (*it).first->updateFrameClose(*fbwin);
1137 }
1162 1138
1163 for (AtomHandlerContainerIt it= m_atomhandler.begin(); 1139 // make sure each workspace get this
1164 it != m_atomhandler.end(); ++it) { 1140 BScreen &scr = fbwin->screen();
1165 if ((*it).first->update()) 1141 scr.removeWindow(fbwin);
1166 (*it).first->updateFrameClose(win); 1142 if (FocusControl::focusedFbWindow() == fbwin)
1167 } 1143 FocusControl::setFocusedFbWindow(0);
1144 } else if (fbwin && &fbwin->workspaceSig() == changedsub) { // workspace signal
1145 for (AtomHandlerContainerIt it= m_atomhandler.begin();
1146 it != m_atomhandler.end(); ++it) {
1147 if ((*it).first->update())
1148 (*it).first->updateWorkspace(*fbwin);
1149 }
1150 } else if (client && &client->dieSig() == changedsub) { // client death
1151 for (AtomHandlerContainerIt it= m_atomhandler.begin();
1152 it != m_atomhandler.end(); ++it) {
1153 if ((*it).first->update())
1154 (*it).first->updateClientClose(*client);
1155 }
1168 1156
1169 // make sure each workspace get this 1157 BScreen &screen = client->screen();
1170 BScreen &scr = win.screen();
1171 scr.removeWindow(&win);
1172 if (FocusControl::focusedFbWindow() == &win)
1173 FocusControl::setFocusedFbWindow(0);
1174 1158
1175 } else if ((&(win.workspaceSig())) == changedsub) { // workspace signal 1159 screen.removeClient(*client);
1176 for (AtomHandlerContainerIt it= m_atomhandler.begin(); 1160
1177 it != m_atomhandler.end(); ++it) { 1161 // At this point, we trust that this client is no longer in the
1178 if ((*it).first->update()) 1162 // client list of its frame (but it still has reference to the frame)
1179 (*it).first->updateWorkspace(win); 1163 // We also assume that any remaining active one is the last focused one
1180 }
1181 } else {
1182#ifdef DEBUG
1183 cerr<<__FILE__<<"("<<__LINE__<<"): WINDOW uncought signal from "<<&win<<endl;
1184#endif // DEBUG
1185 }
1186 1164
1165 // This is where we revert focus on window close
1166 // NOWHERE ELSE!!!
1167 if (FocusControl::focusedWindow() == client) {
1168 FocusControl::unfocusWindow(*client);
1169 // make sure nothing else uses this window before focus reverts
1170 FocusControl::setFocusedWindow(0);
1171 m_revert_screen = &screen;
1172 m_revert_timer.start();
1173 }
1187 } else if (typeid(*changedsub) == typeid(BScreen::ScreenSubject)) { 1174 } else if (typeid(*changedsub) == typeid(BScreen::ScreenSubject)) {
1188 BScreen::ScreenSubject *subj = dynamic_cast<BScreen::ScreenSubject *>(changedsub); 1175 BScreen::ScreenSubject *subj = dynamic_cast<BScreen::ScreenSubject *>(changedsub);
1189 BScreen &screen = subj->screen(); 1176 BScreen &screen = subj->screen();
@@ -1218,37 +1205,6 @@ void Fluxbox::update(FbTk::Subject *changedsub) {
1218 (*it).first->updateClientList(screen); 1205 (*it).first->updateClientList(screen);
1219 } 1206 }
1220 } 1207 }
1221 } else if (typeid(*changedsub) == typeid(WinClient::WinClientSubj)) {
1222
1223 WinClient::WinClientSubj *subj = dynamic_cast<WinClient::WinClientSubj *>(changedsub);
1224 WinClient &client = subj->winClient();
1225
1226 // TODO: don't assume it is diesig (need to fix as soon as another signal appears)
1227 for (AtomHandlerContainerIt it= m_atomhandler.begin();
1228 it != m_atomhandler.end(); ++it) {
1229 if ((*it).first->update())
1230 (*it).first->updateClientClose(client);
1231 }
1232
1233 BScreen &screen = client.screen();
1234
1235 screen.removeClient(client);
1236 // finaly send notify signal
1237 screen.updateNetizenWindowDel(client.window());
1238
1239 // At this point, we trust that this client is no longer in the
1240 // client list of its frame (but it still has reference to the frame)
1241 // We also assume that any remaining active one is the last focused one
1242
1243 // This is where we revert focus on window close
1244 // NOWHERE ELSE!!!
1245 if (FocusControl::focusedWindow() == &client) {
1246 FocusControl::unfocusWindow(client);
1247 // make sure nothing else uses this window before focus reverts
1248 FocusControl::setFocusedWindow(0);
1249 m_revert_screen = &screen;
1250 m_revert_timer.start();
1251 }
1252 } 1208 }
1253} 1209}
1254 1210
@@ -1450,7 +1406,7 @@ string Fluxbox::getRcFilename() {
1450} 1406}
1451 1407
1452/// Provides default filename of data file 1408/// Provides default filename of data file
1453void Fluxbox::getDefaultDataFilename(const char *name, string &filename) { 1409void Fluxbox::getDefaultDataFilename(const char *name, string &filename) const {
1454 filename = string(getenv("HOME") + string("/.") + m_RC_PATH + string("/") + name); 1410 filename = string(getenv("HOME") + string("/.") + m_RC_PATH + string("/") + name);
1455} 1411}
1456 1412
@@ -1492,12 +1448,6 @@ void Fluxbox::load_rc() {
1492 1448
1493 if (m_rc_stylefile->empty()) 1449 if (m_rc_stylefile->empty())
1494 *m_rc_stylefile = DEFAULTSTYLE; 1450 *m_rc_stylefile = DEFAULTSTYLE;
1495
1496 if (!Workspace::loadGroups(*m_rc_groupfile)) {
1497#ifdef DEBUG
1498 cerr<<_FB_CONSOLETEXT(Fluxbox, CantLoadGroupFile, "Failed to load groupfile", "Couldn't load the groupfile")<<": "<<*m_rc_groupfile<<endl;
1499#endif // DEBUG
1500 }
1501} 1451}
1502 1452
1503void Fluxbox::load_rc(BScreen &screen) { 1453void Fluxbox::load_rc(BScreen &screen) {
@@ -1735,7 +1685,6 @@ bool Fluxbox::validateClient(const WinClient *client) const {
1735 1685
1736void Fluxbox::updateFocusedWindow(BScreen *screen, BScreen *old_screen) { 1686void Fluxbox::updateFocusedWindow(BScreen *screen, BScreen *old_screen) {
1737 if (screen != 0) { 1687 if (screen != 0) {
1738 screen->updateNetizenWindowFocus();
1739 for (AtomHandlerContainerIt it= m_atomhandler.begin(); 1688 for (AtomHandlerContainerIt it= m_atomhandler.begin();
1740 it != m_atomhandler.end(); it++) { 1689 it != m_atomhandler.end(); it++) {
1741 (*it).first->updateFocusedWindow(*screen, (FocusControl::focusedWindow() ? 1690 (*it).first->updateFocusedWindow(*screen, (FocusControl::focusedWindow() ?
@@ -1745,7 +1694,6 @@ void Fluxbox::updateFocusedWindow(BScreen *screen, BScreen *old_screen) {
1745 } 1694 }
1746 1695
1747 if (old_screen && old_screen != screen) { 1696 if (old_screen && old_screen != screen) {
1748 old_screen->updateNetizenWindowFocus();
1749 for (AtomHandlerContainerIt it= m_atomhandler.begin(); 1697 for (AtomHandlerContainerIt it= m_atomhandler.begin();
1750 it != m_atomhandler.end(); it++) 1698 it != m_atomhandler.end(); it++)
1751 (*it).first->updateFocusedWindow(*old_screen, 0); 1699 (*it).first->updateFocusedWindow(*old_screen, 0);