aboutsummaryrefslogtreecommitdiff
path: root/src/fluxbox.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/fluxbox.cc')
-rw-r--r--src/fluxbox.cc162
1 files changed, 68 insertions, 94 deletions
diff --git a/src/fluxbox.cc b/src/fluxbox.cc
index 015bb62..3658e50 100644
--- a/src/fluxbox.cc
+++ b/src/fluxbox.cc
@@ -168,11 +168,38 @@ int handleXErrors(Display *d, XErrorEvent *e) {
168// kill(0, 2); 168// kill(0, 2);
169 } 169 }
170#endif // !DEBUG 170#endif // !DEBUG
171
172 return False; 171 return False;
173} 172}
174 173
175 174
175int handleXIOErrors(Display* d) {
176 cerr << "Fluxbox: XIOError: lost connection to display.\n";
177 exit(1);
178}
179
180
181
182class KeyReloadHelper {
183public:
184 void reload() {
185 Fluxbox* f = Fluxbox::instance();
186 Keys* k = (f ? f->keys() : 0);
187 if (k) {
188 XRefreshKeyboardMapping(&(this->xmapping));
189 FbTk::KeyUtil::instance().init();
190 k->regrab();
191 }
192 }
193
194 XMappingEvent xmapping;
195};
196
197KeyReloadHelper s_key_reloader;
198
199typedef FbTk::SimpleCommand<KeyReloadHelper> KeyReloadHelperCmd;
200typedef FbTk::SimpleCommand<Fluxbox> FluxboxCmd;
201
202
176 203
177/* functor to call a memberfunction with by a reference argument 204/* functor to call a memberfunction with by a reference argument
178 other places needs this helper as well it should be moved 205 other places needs this helper as well it should be moved
@@ -281,21 +308,8 @@ Fluxbox::Fluxbox(int argc, char **argv,
281 s_kwm2_dockwindow = XInternAtom(disp, 308 s_kwm2_dockwindow = XInternAtom(disp,
282 "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False); 309 "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", False);
283 // setup X error handler 310 // setup X error handler
284 XSetErrorHandler((XErrorHandler) handleXErrors); 311 XSetErrorHandler(handleXErrors);
285 312 XSetIOErrorHandler(handleXIOErrors);
286 //catch system signals
287 SignalHandler &sigh = SignalHandler::instance();
288 sigh.registerHandler(SIGSEGV, this);
289 sigh.registerHandler(SIGFPE, this);
290 sigh.registerHandler(SIGTERM, this);
291 sigh.registerHandler(SIGINT, this);
292#ifndef _WIN32
293 sigh.registerHandler(SIGPIPE, this); // e.g. output sent to grep
294 sigh.registerHandler(SIGCHLD, this);
295 sigh.registerHandler(SIGHUP, this);
296 sigh.registerHandler(SIGUSR1, this);
297 sigh.registerHandler(SIGUSR2, this);
298#endif
299 313
300 // 314 //
301 // setup timer 315 // setup timer
@@ -303,11 +317,21 @@ Fluxbox::Fluxbox(int argc, char **argv,
303 // Because when the command is executed we shouldn't do reconfig directly 317 // Because when the command is executed we shouldn't do reconfig directly
304 // because it could affect ongoing menu stuff so we need to reconfig in 318 // because it could affect ongoing menu stuff so we need to reconfig in
305 // the next event "round". 319 // the next event "round".
306 FbTk::RefCount<FbTk::Command<void> > reconfig_cmd(new FbTk::SimpleCommand<Fluxbox>(*this, &Fluxbox::timed_reconfigure)); 320 FluxboxCmd* reconfig_cmd = new FluxboxCmd(*this, &Fluxbox::timed_reconfigure);
307 m_reconfig_timer.setTimeout(1); 321 m_reconfig_timer.setTimeout(1);
308 m_reconfig_timer.setCommand(reconfig_cmd); 322 m_reconfig_timer.setCommand(FbTk::RefCount<FbTk::Command<void> >(reconfig_cmd));
309 m_reconfig_timer.fireOnce(true); 323 m_reconfig_timer.fireOnce(true);
310 324
325 // xmodmap and other tools send a lot of MappingNotify events under some
326 // circumstances ("keysym comma = comma semicolon" creates 4 or 5).
327 // reloading the keys-file for every one of them is unclever. we postpone
328 // the reload() via a timer.
329 KeyReloadHelperCmd* rh_cmd =
330 new KeyReloadHelperCmd(s_key_reloader, &KeyReloadHelper::reload);
331 m_key_reload_timer.setTimeout(250 * FbTk::FbTime::IN_MILLISECONDS);
332 m_key_reload_timer.setCommand(FbTk::RefCount<FbTk::Command<void> >(rh_cmd));
333 m_key_reload_timer.fireOnce(true);
334
311 if (xsync) 335 if (xsync)
312 XSynchronize(disp, True); 336 XSynchronize(disp, True);
313 337
@@ -638,20 +662,12 @@ void Fluxbox::handleEvent(XEvent * const e) {
638 662
639 if (! winclient) { 663 if (! winclient) {
640 BScreen *screen = 0; 664 BScreen *screen = 0;
641 int screen_num;
642 XWindowAttributes attr; 665 XWindowAttributes attr;
643 // find screen 666 // find screen
644 if (XGetWindowAttributes(display(), 667 if (XGetWindowAttributes(display(),
645 e->xmaprequest.window, 668 e->xmaprequest.window,
646 &attr) && attr.screen != 0) { 669 &attr) && attr.screen != 0) {
647 screen_num = XScreenNumberOfScreen(attr.screen); 670 screen = findScreen(XScreenNumberOfScreen(attr.screen));
648
649 // find screen
650 ScreenList::iterator screen_it = find_if(m_screen_list.begin(),
651 m_screen_list.end(),
652 FbTk::CompareEqual<BScreen>(&BScreen::screenNumber, screen_num));
653 if (screen_it != m_screen_list.end())
654 screen = *screen_it;
655 } 671 }
656 // try with parent if we failed to find screen num 672 // try with parent if we failed to find screen num
657 if (screen == 0) 673 if (screen == 0)
@@ -675,21 +691,18 @@ void Fluxbox::handleEvent(XEvent * const e) {
675 break; 691 break;
676 case UnmapNotify: 692 case UnmapNotify:
677 handleUnmapNotify(e->xunmap); 693 handleUnmapNotify(e->xunmap);
678 break; 694 break;
679 case MappingNotify: 695 case MappingNotify: // Update stored modifier mapping
680 // Update stored modifier mapping
681 fbdbg<<"MappingNotify"<<endl;
682 696
683 if (e->xmapping.request == MappingKeyboard 697 if (e->xmapping.request == MappingKeyboard
684 || e->xmapping.request == MappingModifier) { 698 || e->xmapping.request == MappingModifier) {
685 XRefreshKeyboardMapping(&e->xmapping); 699
686 FbTk::KeyUtil::instance().init(); // reinitialise the key utils 700 s_key_reloader.xmapping = e->xmapping;
687 // reconfigure keys (if the mapping changes, they don't otherwise update 701 m_key_reload_timer.start();
688 m_key->regrab();
689 } 702 }
690 break; 703 break;
691 case CreateNotify: 704 case CreateNotify:
692 break; 705 break;
693 case DestroyNotify: { 706 case DestroyNotify: {
694 WinClient *winclient = searchWindow(e->xdestroywindow.window); 707 WinClient *winclient = searchWindow(e->xdestroywindow.window);
695 if (winclient != 0) { 708 if (winclient != 0) {
@@ -887,58 +900,6 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) {
887 } 900 }
888} 901}
889 902
890/// handle system signals
891void Fluxbox::handleSignal(int signum) {
892 _FB_USES_NLS;
893
894 static int re_enter = 0;
895
896 switch (signum) {
897#ifndef _WIN32
898 case SIGCHLD: // we don't want the child process to kill us
899 // more than one process may have terminated
900 while (waitpid(-1, 0, WNOHANG | WUNTRACED) > 0);
901 break;
902 case SIGHUP:
903 restart();
904 break;
905 case SIGUSR1:
906 load_rc();
907 break;
908 case SIGUSR2:
909 reconfigure();
910 break;
911#endif
912 case SIGSEGV:
913 abort();
914 break;
915 case SIGFPE:
916 case SIGINT:
917#ifndef _WIN32
918 case SIGPIPE:
919#endif
920 case SIGTERM:
921 shutdown();
922 break;
923 default:
924 fprintf(stderr,
925 _FB_CONSOLETEXT(BaseDisplay, SignalCaught, "%s: signal %d caught\n", "signal catch debug message. Include %s for Command<void> and %d for signal number").c_str(),
926 m_argv[0], signum);
927
928 if (! m_starting && ! re_enter) {
929 re_enter = 1;
930 cerr<<_FB_CONSOLETEXT(BaseDisplay, ShuttingDown, "Shutting Down\n", "Quitting because of signal, end with newline");
931 shutdown();
932 }
933
934
935 cerr<<_FB_CONSOLETEXT(BaseDisplay, Aborting, "Aborting... dumping core\n", "Aboring and dumping core, end with newline");
936 abort();
937 break;
938 }
939}
940
941
942void Fluxbox::windowDied(Focusable &focusable) { 903void Fluxbox::windowDied(Focusable &focusable) {
943 FluxboxWindow *fbwin = focusable.fbwindow(); 904 FluxboxWindow *fbwin = focusable.fbwindow();
944 905
@@ -1113,18 +1074,30 @@ void Fluxbox::restart(const char *prog) {
1113 } 1074 }
1114} 1075}
1115 1076
1116/// prepares fluxbox for a shutdown 1077// prepares fluxbox for a shutdown. when x_wants_down is != 0 we assume that
1117void Fluxbox::shutdown() { 1078// the xserver is about to shutdown or is in the midst of shutting down
1079// already. trying to cleanup over a shaky xserver connection is pointless and
1080// might lead to hangups.
1081void Fluxbox::shutdown(int x_wants_down) {
1118 if (m_shutdown) 1082 if (m_shutdown)
1119 return; 1083 return;
1120 1084
1085 Display *dpy = FbTk::App::instance()->display();
1121 m_shutdown = true; 1086 m_shutdown = true;
1122 1087
1123 XSetInputFocus(FbTk::App::instance()->display(), PointerRoot, None, CurrentTime); 1088#ifdef HAVE_ALARM
1089 // give ourself 2 seconds (randomly picked randon number) to shutdown
1090 // and then try to reenter signal handling. a bad race condition might
1091 // lead to an inifite loop and this is some kind of last resort
1092 alarm(2);
1093#endif
1124 1094
1125 STLUtil::forAll(m_screen_list, mem_fun(&BScreen::shutdown)); 1095 XSetInputFocus(dpy, PointerRoot, None, CurrentTime);
1126 1096
1127 sync(false); 1097 if (x_wants_down == 0) {
1098 STLUtil::forAll(m_screen_list, mem_fun(&BScreen::shutdown));
1099 sync(false);
1100 }
1128} 1101}
1129 1102
1130/// saves resources 1103/// saves resources
@@ -1279,6 +1252,7 @@ void Fluxbox::load_rc(BScreen &screen) {
1279} 1252}
1280 1253
1281void Fluxbox::reconfigure() { 1254void Fluxbox::reconfigure() {
1255 m_key_reload_timer.stop();
1282 load_rc(); 1256 load_rc();
1283 m_reconfigure_wait = true; 1257 m_reconfigure_wait = true;
1284 m_reconfig_timer.start(); 1258 m_reconfig_timer.start();
@@ -1350,7 +1324,7 @@ bool Fluxbox::validateClient(const WinClient *client) const {
1350 WinClientMap::const_iterator it = 1324 WinClientMap::const_iterator it =
1351 find_if(m_window_search.begin(), 1325 find_if(m_window_search.begin(),
1352 m_window_search.end(), 1326 m_window_search.end(),
1353 Compose(bind2nd(equal_to<WinClient *>(), client), 1327 Compose(bind2nd(equal_to<const WinClient *>(), client),
1354 Select2nd<WinClientMap::value_type>())); 1328 Select2nd<WinClientMap::value_type>()));
1355 return it != m_window_search.end(); 1329 return it != m_window_search.end();
1356} 1330}