summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/fluxbox.cc157
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
355static Window last_bad_window = None;
356
357
358static 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
356Fluxbox *Fluxbox::s_singleton=0; 375Fluxbox *Fluxbox::s_singleton=0;
357 376
@@ -361,7 +380,7 @@ Fluxbox::Titlebar Fluxbox::s_titlebar_left[] = {STICK};
361Fluxbox::Titlebar Fluxbox::s_titlebar_right[] = {MINIMIZE, MAXIMIZE, CLOSE}; 380Fluxbox::Titlebar Fluxbox::s_titlebar_right[] = {MINIMIZE, MAXIMIZE, CLOSE};
362 381
363Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfilename) 382Fluxbox::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
541void 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
566bool 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
576void Fluxbox::grab() {
577 if (! m_server_grabs++)
578 XGrabServer(display());
579}
580
581void 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
1643void Fluxbox::shutdown() { 1707void 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
2335void Fluxbox::watchKeyRelease(BScreen *screen, unsigned int mods) { 2414void 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}