diff options
Diffstat (limited to 'src/fluxbox.cc')
-rw-r--r-- | src/fluxbox.cc | 157 |
1 files changed, 118 insertions, 39 deletions
diff --git a/src/fluxbox.cc b/src/fluxbox.cc index 2d7922a..dbcc950 100644 --- a/src/fluxbox.cc +++ b/src/fluxbox.cc | |||
@@ -22,7 +22,7 @@ | |||
22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | 22 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
23 | // DEALINGS IN THE SOFTWARE. | 23 | // DEALINGS IN THE SOFTWARE. |
24 | 24 | ||
25 | // $Id: fluxbox.cc,v 1.130 2003/05/07 23:17:38 fluxgen Exp $ | 25 | // $Id: fluxbox.cc,v 1.131 2003/05/10 14:32:35 fluxgen Exp $ |
26 | 26 | ||
27 | #include "fluxbox.hh" | 27 | #include "fluxbox.hh" |
28 | 28 | ||
@@ -352,6 +352,25 @@ getString() { | |||
352 | } | 352 | } |
353 | } | 353 | } |
354 | 354 | ||
355 | static Window last_bad_window = None; | ||
356 | |||
357 | |||
358 | static int handleXErrors(Display *d, XErrorEvent *e) { | ||
359 | #ifdef DEBUG | ||
360 | char errtxt[128]; | ||
361 | |||
362 | XGetErrorText(d, e->error_code, errtxt, 128); | ||
363 | cerr<<"Fluxbox: X Error: "<<errtxt<<"("<<e->error_code<<") opcodes "<< | ||
364 | e->request_code<<"/"<<e->minor_code<<" resource 0x"<<hex<<e->resourceid<<dec<<endl; | ||
365 | #endif // !DEBUG | ||
366 | |||
367 | if (e->error_code == BadWindow) | ||
368 | last_bad_window = e->resourceid; | ||
369 | |||
370 | return False; | ||
371 | } | ||
372 | |||
373 | |||
355 | //static singleton var | 374 | //static singleton var |
356 | Fluxbox *Fluxbox::s_singleton=0; | 375 | Fluxbox *Fluxbox::s_singleton=0; |
357 | 376 | ||
@@ -361,7 +380,7 @@ Fluxbox::Titlebar Fluxbox::s_titlebar_left[] = {STICK}; | |||
361 | Fluxbox::Titlebar Fluxbox::s_titlebar_right[] = {MINIMIZE, MAXIMIZE, CLOSE}; | 380 | Fluxbox::Titlebar Fluxbox::s_titlebar_right[] = {MINIMIZE, MAXIMIZE, CLOSE}; |
362 | 381 | ||
363 | Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfilename) | 382 | Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfilename) |
364 | : BaseDisplay(argv[0], dpy_name), | 383 | : FbTk::App(dpy_name), |
365 | m_fbatoms(new FbAtoms()), | 384 | m_fbatoms(new FbAtoms()), |
366 | m_resourcemanager(), m_screen_rm(), | 385 | m_resourcemanager(), m_screen_rm(), |
367 | m_rc_tabs(m_resourcemanager, true, "session.tabs", "Session.Tabs"), | 386 | m_rc_tabs(m_resourcemanager, true, "session.tabs", "Session.Tabs"), |
@@ -388,14 +407,20 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile | |||
388 | m_last_time(0), | 407 | m_last_time(0), |
389 | m_masked(0), | 408 | m_masked(0), |
390 | m_rc_file(rcfilename ? rcfilename : ""), | 409 | m_rc_file(rcfilename ? rcfilename : ""), |
391 | m_argv(argv), m_argc(argc) { | 410 | m_argv(argv), m_argc(argc), |
411 | m_starting(true), | ||
412 | m_shutdown(false), | ||
413 | m_server_grabs(0) { | ||
392 | 414 | ||
393 | 415 | ||
394 | if (s_singleton != 0) { | 416 | if (s_singleton != 0) { |
395 | cerr<<"Fatal! There can only one instance of fluxbox class."<<endl; | 417 | cerr<<"Fatal! There can only one instance of fluxbox class."<<endl; |
396 | abort(); | 418 | abort(); |
397 | } | 419 | } |
398 | 420 | ||
421 | // setup X error handler | ||
422 | XSetErrorHandler((XErrorHandler) handleXErrors); | ||
423 | |||
399 | //catch system signals | 424 | //catch system signals |
400 | SignalHandler *sigh = SignalHandler::instance(); | 425 | SignalHandler *sigh = SignalHandler::instance(); |
401 | 426 | ||
@@ -445,10 +470,9 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile | |||
445 | m_fluxbox_pid = XInternAtom(disp, "_BLACKBOX_PID", False); | 470 | m_fluxbox_pid = XInternAtom(disp, "_BLACKBOX_PID", False); |
446 | #endif // HAVE_GETPID | 471 | #endif // HAVE_GETPID |
447 | 472 | ||
448 | int i; | ||
449 | load_rc(); | 473 | load_rc(); |
450 | //allocate screens | 474 | // Allocate screens |
451 | for (i = 0; i < getNumberOfScreens(); i++) { | 475 | for (int i = 0; i < ScreenCount(display()); i++) { |
452 | char scrname[128], altscrname[128]; | 476 | char scrname[128], altscrname[128]; |
453 | sprintf(scrname, "session.screen%d", i); | 477 | sprintf(scrname, "session.screen%d", i); |
454 | sprintf(altscrname, "session.Screen%d", i); | 478 | sprintf(altscrname, "session.Screen%d", i); |
@@ -496,6 +520,7 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile | |||
496 | m_key.reset(new Keys(StringUtil::expandFilename(*m_rc_keyfile).c_str())); | 520 | m_key.reset(new Keys(StringUtil::expandFilename(*m_rc_keyfile).c_str())); |
497 | 521 | ||
498 | ungrab(); | 522 | ungrab(); |
523 | m_starting = false; | ||
499 | } | 524 | } |
500 | 525 | ||
501 | 526 | ||
@@ -513,6 +538,53 @@ Fluxbox::~Fluxbox() { | |||
513 | 538 | ||
514 | } | 539 | } |
515 | 540 | ||
541 | void Fluxbox::eventLoop() { | ||
542 | while (m_shutdown) { | ||
543 | if (XPending(display())) { | ||
544 | XEvent e; | ||
545 | XNextEvent(display(), &e); | ||
546 | |||
547 | if (last_bad_window != None && e.xany.window == last_bad_window) { | ||
548 | #ifdef DEBUG | ||
549 | fprintf(stderr, | ||
550 | I18n::instance()-> | ||
551 | getMessage( | ||
552 | FBNLS::BaseDisplaySet, FBNLS::BaseDisplayBadWindowRemove, | ||
553 | "Fluxbox::eventLoop(): removing bad window " | ||
554 | "from event queue\n")); | ||
555 | #endif // DEBUG | ||
556 | } else { | ||
557 | last_bad_window = None; | ||
558 | handleEvent(&e); | ||
559 | } | ||
560 | } else { | ||
561 | FbTk::Timer::updateTimers(ConnectionNumber(display())); //handle all timers | ||
562 | } | ||
563 | } | ||
564 | } | ||
565 | |||
566 | bool Fluxbox::validateWindow(Window window) const { | ||
567 | XEvent event; | ||
568 | if (XCheckTypedWindowEvent(display(), window, DestroyNotify, &event)) { | ||
569 | XPutBackEvent(display(), &event); | ||
570 | return false; | ||
571 | } | ||
572 | |||
573 | return true; | ||
574 | } | ||
575 | |||
576 | void Fluxbox::grab() { | ||
577 | if (! m_server_grabs++) | ||
578 | XGrabServer(display()); | ||
579 | } | ||
580 | |||
581 | void Fluxbox::ungrab() { | ||
582 | if (! --m_server_grabs) | ||
583 | XUngrabServer(display()); | ||
584 | if (m_server_grabs < 0) | ||
585 | m_server_grabs = 0; | ||
586 | } | ||
587 | |||
516 | /** | 588 | /** |
517 | setup the configutation files in | 589 | setup the configutation files in |
518 | home directory | 590 | home directory |
@@ -779,18 +851,8 @@ void Fluxbox::handleEvent(XEvent * const e) { | |||
779 | handleClientMessage(e->xclient); | 851 | handleClientMessage(e->xclient); |
780 | break; | 852 | break; |
781 | default: { | 853 | default: { |
782 | |||
783 | #ifdef SHAPE | ||
784 | if (e->type == getShapeEventBase()) { | ||
785 | XShapeEvent *shape_event = (XShapeEvent *) e; | ||
786 | FluxboxWindow *win = (FluxboxWindow *) 0; | ||
787 | |||
788 | if ((win = searchWindow(e->xany.window)) || | ||
789 | (shape_event->kind != ShapeBounding)) | ||
790 | win->shapeEvent(shape_event); | ||
791 | } | ||
792 | #endif // SHAPE | ||
793 | } | 854 | } |
855 | |||
794 | } | 856 | } |
795 | } | 857 | } |
796 | 858 | ||
@@ -961,7 +1023,7 @@ void Fluxbox::handleClientMessage(XClientMessageEvent &ce) { | |||
961 | FluxboxWindow *win = searchWindow(ce.window); | 1023 | FluxboxWindow *win = searchWindow(ce.window); |
962 | 1024 | ||
963 | if (win && win->validateClient()) { | 1025 | if (win && win->validateClient()) { |
964 | BlackboxHints net; | 1026 | FluxboxWindow::BlackboxHints net; |
965 | net.flags = ce.data.l[0]; | 1027 | net.flags = ce.data.l[0]; |
966 | net.attrib = ce.data.l[1]; | 1028 | net.attrib = ce.data.l[1]; |
967 | net.workspace = ce.data.l[2]; | 1029 | net.workspace = ce.data.l[2]; |
@@ -1105,9 +1167,10 @@ void Fluxbox::handleKeyEvent(XKeyEvent &ke) { | |||
1105 | m_focused_window->getClientWindow()); | 1167 | m_focused_window->getClientWindow()); |
1106 | } | 1168 | } |
1107 | break; | 1169 | break; |
1108 | case Keys::NEXTWINDOW: //activate next window | 1170 | case Keys::NEXTWINDOW: { //activate next window |
1109 | { | ||
1110 | unsigned int mods = Keys::cleanMods(ke.state); | 1171 | unsigned int mods = Keys::cleanMods(ke.state); |
1172 | if (mousescreen == 0) | ||
1173 | break; | ||
1111 | if (mods == 0) { // can't stacked cycle unless there is a mod to grab | 1174 | if (mods == 0) { // can't stacked cycle unless there is a mod to grab |
1112 | mousescreen->nextFocus(m_key->getParam() | BScreen::CYCLELINEAR); | 1175 | mousescreen->nextFocus(m_key->getParam() | BScreen::CYCLELINEAR); |
1113 | break; | 1176 | break; |
@@ -1115,14 +1178,15 @@ void Fluxbox::handleKeyEvent(XKeyEvent &ke) { | |||
1115 | if (!m_watching_screen && !(m_key->getParam() & BScreen::CYCLELINEAR)) { | 1178 | if (!m_watching_screen && !(m_key->getParam() & BScreen::CYCLELINEAR)) { |
1116 | // if stacked cycling, then set a watch for | 1179 | // if stacked cycling, then set a watch for |
1117 | // the release of exactly these modifiers | 1180 | // the release of exactly these modifiers |
1118 | watchKeyRelease(mousescreen, mods); | 1181 | watchKeyRelease(*mousescreen, mods); |
1119 | } | 1182 | } |
1120 | mousescreen->nextFocus(m_key->getParam()); | 1183 | mousescreen->nextFocus(m_key->getParam()); |
1121 | break; | 1184 | break; |
1122 | } | 1185 | } |
1123 | case Keys::PREVWINDOW: //activate prev window | 1186 | case Keys::PREVWINDOW: {//activate prev window |
1124 | { | ||
1125 | unsigned int mods = Keys::cleanMods(ke.state); | 1187 | unsigned int mods = Keys::cleanMods(ke.state); |
1188 | if (mousescreen == 0) | ||
1189 | break; | ||
1126 | if (mods == 0) { // can't stacked cycle unless there is a mod to grab | 1190 | if (mods == 0) { // can't stacked cycle unless there is a mod to grab |
1127 | mousescreen->prevFocus(m_key->getParam() | BScreen::CYCLELINEAR); | 1191 | mousescreen->prevFocus(m_key->getParam() | BScreen::CYCLELINEAR); |
1128 | break; | 1192 | break; |
@@ -1130,7 +1194,7 @@ void Fluxbox::handleKeyEvent(XKeyEvent &ke) { | |||
1130 | if (!m_watching_screen && !(m_key->getParam() & BScreen::CYCLELINEAR)) { | 1194 | if (!m_watching_screen && !(m_key->getParam() & BScreen::CYCLELINEAR)) { |
1131 | // if stacked cycling, then set a watch for | 1195 | // if stacked cycling, then set a watch for |
1132 | // the release of exactly these modifiers | 1196 | // the release of exactly these modifiers |
1133 | watchKeyRelease(mousescreen, mods); | 1197 | watchKeyRelease(*mousescreen, mods); |
1134 | } | 1198 | } |
1135 | mousescreen->prevFocus(m_key->getParam()); | 1199 | mousescreen->prevFocus(m_key->getParam()); |
1136 | break; | 1200 | break; |
@@ -1422,9 +1486,9 @@ void Fluxbox::handleSignal(int signum) { | |||
1422 | i18n->getMessage( | 1486 | i18n->getMessage( |
1423 | FBNLS::BaseDisplaySet, FBNLS::BaseDisplaySignalCaught, | 1487 | FBNLS::BaseDisplaySet, FBNLS::BaseDisplaySignalCaught, |
1424 | "%s: signal %d caught\n"), | 1488 | "%s: signal %d caught\n"), |
1425 | getApplicationName(), signum); | 1489 | m_argv[0], signum); |
1426 | 1490 | ||
1427 | if (! isStartup() && ! re_enter) { | 1491 | if (! m_starting && ! re_enter) { |
1428 | re_enter = 1; | 1492 | re_enter = 1; |
1429 | fprintf(stderr, | 1493 | fprintf(stderr, |
1430 | i18n->getMessage( | 1494 | i18n->getMessage( |
@@ -1630,7 +1694,7 @@ void Fluxbox::restart(const char *prog) { | |||
1630 | shutdown(); | 1694 | shutdown(); |
1631 | 1695 | ||
1632 | if (prog) { | 1696 | if (prog) { |
1633 | execlp(prog, prog, NULL); | 1697 | execlp(prog, prog, 0); |
1634 | perror(prog); | 1698 | perror(prog); |
1635 | } | 1699 | } |
1636 | 1700 | ||
@@ -1641,7 +1705,6 @@ void Fluxbox::restart(const char *prog) { | |||
1641 | 1705 | ||
1642 | /// prepares fluxbox for a shutdown | 1706 | /// prepares fluxbox for a shutdown |
1643 | void Fluxbox::shutdown() { | 1707 | void Fluxbox::shutdown() { |
1644 | BaseDisplay::shutdown(); | ||
1645 | 1708 | ||
1646 | XSetInputFocus(FbTk::App::instance()->display(), PointerRoot, None, CurrentTime); | 1709 | XSetInputFocus(FbTk::App::instance()->display(), PointerRoot, None, CurrentTime); |
1647 | 1710 | ||
@@ -1652,7 +1715,7 @@ void Fluxbox::shutdown() { | |||
1652 | if(*it) | 1715 | if(*it) |
1653 | (*it)->shutdown(); | 1716 | (*it)->shutdown(); |
1654 | } | 1717 | } |
1655 | 1718 | m_shutdown = true; | |
1656 | XSync(FbTk::App::instance()->display(), False); | 1719 | XSync(FbTk::App::instance()->display(), False); |
1657 | 1720 | ||
1658 | } | 1721 | } |
@@ -2236,14 +2299,30 @@ void Fluxbox::setFocusedWindow(FluxboxWindow *win) { | |||
2236 | Workspace *old_wkspc = 0, *wkspc = 0; | 2299 | Workspace *old_wkspc = 0, *wkspc = 0; |
2237 | 2300 | ||
2238 | if (m_focused_window != 0) { | 2301 | if (m_focused_window != 0) { |
2239 | old_win = m_focused_window; | 2302 | // check if m_focused_window is valid |
2240 | old_screen = &old_win->getScreen(); | 2303 | bool found = false; |
2304 | std::map<Window, FluxboxWindow *>::iterator it = m_window_search.begin(); | ||
2305 | std::map<Window, FluxboxWindow *>::iterator it_end = m_window_search.end(); | ||
2306 | for (; it != it_end; ++it) { | ||
2307 | if (it->second == m_focused_window) { | ||
2308 | // we found it, end loop | ||
2309 | found = true; | ||
2310 | break; | ||
2311 | } | ||
2312 | } | ||
2241 | 2313 | ||
2242 | old_tbar = old_screen->getToolbar(); | 2314 | if (!found) { |
2243 | old_wkspc = old_screen->getWorkspace(old_win->getWorkspaceNumber()); | 2315 | m_focused_window = 0; |
2316 | } else { | ||
2317 | old_win = m_focused_window; | ||
2318 | old_screen = &old_win->getScreen(); | ||
2244 | 2319 | ||
2245 | old_win->setFocusFlag(false); | 2320 | old_tbar = old_screen->getToolbar(); |
2246 | old_wkspc->menu().setItemSelected(old_win->getWindowNumber(), false); | 2321 | old_wkspc = old_screen->getWorkspace(old_win->getWorkspaceNumber()); |
2322 | |||
2323 | old_win->setFocusFlag(false); | ||
2324 | old_wkspc->menu().setItemSelected(old_win->getWindowNumber(), false); | ||
2325 | } | ||
2247 | } | 2326 | } |
2248 | 2327 | ||
2249 | if (win && ! win->isIconic()) { | 2328 | if (win && ! win->isIconic()) { |
@@ -2332,14 +2411,14 @@ void Fluxbox::revertFocus(BScreen *screen) { | |||
2332 | 2411 | ||
2333 | 2412 | ||
2334 | 2413 | ||
2335 | void Fluxbox::watchKeyRelease(BScreen *screen, unsigned int mods) { | 2414 | void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) { |
2336 | if (mods == 0) { | 2415 | if (mods == 0) { |
2337 | cerr<<"WARNING: attempt to grab without modifiers!"<<endl; | 2416 | cerr<<"WARNING: attempt to grab without modifiers!"<<endl; |
2338 | return; | 2417 | return; |
2339 | } | 2418 | } |
2340 | m_watching_screen = screen; | 2419 | m_watching_screen = &screen; |
2341 | m_watch_keyrelease = mods; | 2420 | m_watch_keyrelease = mods; |
2342 | XGrabKeyboard(FbTk::App::instance()->display(), | 2421 | XGrabKeyboard(FbTk::App::instance()->display(), |
2343 | screen->getRootWindow(), True, | 2422 | screen.getRootWindow(), True, |
2344 | GrabModeAsync, GrabModeAsync, CurrentTime); | 2423 | GrabModeAsync, GrabModeAsync, CurrentTime); |
2345 | } | 2424 | } |