diff options
author | rathnor <rathnor> | 2003-10-05 02:31:23 (GMT) |
---|---|---|
committer | rathnor <rathnor> | 2003-10-05 02:31:23 (GMT) |
commit | fa4328d8620959dce8a53b40c743fba691cfe471 (patch) | |
tree | 5de11bd0460300b817698bdd547e5b2fec783bae /src/fluxbox.cc | |
parent | 35fe2d5e128c1b13d34a5152945a1b8979401d6f (diff) | |
download | fluxbox-fa4328d8620959dce8a53b40c743fba691cfe471.zip fluxbox-fa4328d8620959dce8a53b40c743fba691cfe471.tar.bz2 |
make doFocusLast work for sloppy focus as well
Diffstat (limited to 'src/fluxbox.cc')
-rw-r--r-- | src/fluxbox.cc | 131 |
1 files changed, 115 insertions, 16 deletions
diff --git a/src/fluxbox.cc b/src/fluxbox.cc index bd02cee..1045200 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.193 2003/09/14 12:03:40 fluxgen Exp $ | 25 | // $Id: fluxbox.cc,v 1.194 2003/10/05 02:31:23 rathnor Exp $ |
26 | 26 | ||
27 | #include "fluxbox.hh" | 27 | #include "fluxbox.hh" |
28 | 28 | ||
@@ -403,12 +403,11 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile | |||
403 | "session.titlebar.right", "Session.Titlebar.Right"), | 403 | "session.titlebar.right", "Session.Titlebar.Right"), |
404 | m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"), | 404 | m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"), |
405 | m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"), | 405 | m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"), |
406 | m_focused_window(0), m_masked_window(0), | 406 | m_focused_window(0), |
407 | m_mousescreen(0), | 407 | m_mousescreen(0), |
408 | m_keyscreen(0), | 408 | m_keyscreen(0), |
409 | m_watching_screen(0), m_watch_keyrelease(0), | 409 | m_watching_screen(0), m_watch_keyrelease(0), |
410 | m_last_time(0), | 410 | m_last_time(0), |
411 | m_masked(0), | ||
412 | m_rc_file(rcfilename ? rcfilename : ""), | 411 | m_rc_file(rcfilename ? rcfilename : ""), |
413 | m_argv(argv), m_argc(argc), | 412 | m_argv(argv), m_argc(argc), |
414 | m_starting(true), | 413 | m_starting(true), |
@@ -416,7 +415,9 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile | |||
416 | m_server_grabs(0), | 415 | m_server_grabs(0), |
417 | m_randr_event_type(0), | 416 | m_randr_event_type(0), |
418 | m_RC_PATH("fluxbox"), | 417 | m_RC_PATH("fluxbox"), |
419 | m_RC_INIT_FILE("init") { | 418 | m_RC_INIT_FILE("init"), |
419 | m_focus_revert_screen(0) | ||
420 | { | ||
420 | 421 | ||
421 | 422 | ||
422 | if (s_singleton != 0) | 423 | if (s_singleton != 0) |
@@ -610,6 +611,10 @@ void Fluxbox::eventLoop() { | |||
610 | } else { | 611 | } else { |
611 | last_bad_window = None; | 612 | last_bad_window = None; |
612 | handleEvent(&e); | 613 | handleEvent(&e); |
614 | if (m_focus_revert_screen != 0) { | ||
615 | revertFocus(*m_focus_revert_screen, false); | ||
616 | m_focus_revert_screen = 0; | ||
617 | } | ||
613 | } | 618 | } |
614 | } else { | 619 | } else { |
615 | FbTk::Timer::updateTimers(ConnectionNumber(display())); //handle all timers | 620 | FbTk::Timer::updateTimers(ConnectionNumber(display())); //handle all timers |
@@ -700,17 +705,52 @@ void Fluxbox::handleEvent(XEvent * const e) { | |||
700 | m_last_event = *e; | 705 | m_last_event = *e; |
701 | 706 | ||
702 | // it is possible (e.g. during moving) for a window | 707 | // it is possible (e.g. during moving) for a window |
703 | // to mask all events to go to it | 708 | // to mask certain events to go somewhere (e.g. to that window) |
704 | if ((m_masked == e->xany.window) && m_masked_window) { | 709 | if (!m_redirect_events.empty()) { |
705 | if (e->type == MotionNotify) { | 710 | |
706 | m_last_time = e->xmotion.time; | 711 | bool drop_event = false; |
707 | m_masked_window->motionNotifyEvent(e->xmotion); | 712 | RedirectEvents::iterator it = m_redirect_events.begin(); |
708 | return; | 713 | RedirectEvents::iterator it_end = m_redirect_events.end(); |
709 | } else if (e->type == ButtonRelease) { | 714 | RedirectEvent *re = 0; |
710 | e->xbutton.window = m_masked_window->fbWindow().window(); | 715 | bool matched = false; |
716 | Window orig_win = e->xany.window; | ||
717 | |||
718 | // look through all registered redirects | ||
719 | while (it != it_end) { | ||
720 | matched = false; | ||
721 | re = *it; | ||
722 | // do we affect this event? | ||
723 | if (e->type == re->catch_type && | ||
724 | (re->catch_win == None || | ||
725 | re->catch_win == orig_win)) { | ||
726 | matched = true; | ||
727 | // redirect? | ||
728 | if (re->redirect_win != None) { | ||
729 | e->xany.window = re->redirect_win; | ||
730 | } else { | ||
731 | drop_event = true; | ||
732 | } | ||
733 | } | ||
734 | |||
735 | // does this event stop this redirect? | ||
736 | if (e->type == re->stop_type && | ||
737 | ((re->stop_win == None && matched) || | ||
738 | re->stop_win == orig_win)) { | ||
739 | RedirectEvents::iterator next_it = it; | ||
740 | ++next_it; | ||
741 | delete (*it); | ||
742 | m_redirect_events.erase(it); | ||
743 | it = next_it; | ||
744 | } else | ||
745 | ++it; | ||
711 | } | 746 | } |
712 | 747 | ||
748 | // if one of the redirects says to drop it, we do | ||
749 | if (drop_event) | ||
750 | return; | ||
713 | } | 751 | } |
752 | |||
753 | |||
714 | // try FbTk::EventHandler first | 754 | // try FbTk::EventHandler first |
715 | FbTk::EventManager::instance()->handleEvent(*e); | 755 | FbTk::EventManager::instance()->handleEvent(*e); |
716 | 756 | ||
@@ -1905,7 +1945,6 @@ void Fluxbox::setFocusedWindow(WinClient *client) { | |||
1905 | return; | 1945 | return; |
1906 | } | 1946 | } |
1907 | #ifdef DEBUG | 1947 | #ifdef DEBUG |
1908 | cerr<<"-----------------"<<endl; | ||
1909 | cerr<<"Setting Focused window = "<<client<<endl; | 1948 | cerr<<"Setting Focused window = "<<client<<endl; |
1910 | cerr<<"Current Focused window = "<<m_focused_window<<endl; | 1949 | cerr<<"Current Focused window = "<<m_focused_window<<endl; |
1911 | cerr<<"------------------"<<endl; | 1950 | cerr<<"------------------"<<endl; |
@@ -1978,16 +2017,38 @@ void Fluxbox::setFocusedWindow(WinClient *client) { | |||
1978 | * last_focused is set to something if we want to make use of the | 2017 | * last_focused is set to something if we want to make use of the |
1979 | * previously focused window (it must NOT be set focused now, it | 2018 | * previously focused window (it must NOT be set focused now, it |
1980 | * is probably dying). | 2019 | * is probably dying). |
2020 | * | ||
2021 | * ignore_event means that it ignores the given event until | ||
2022 | * it gets a focusIn | ||
1981 | */ | 2023 | */ |
1982 | void Fluxbox::revertFocus(BScreen &screen) { | 2024 | void Fluxbox::revertFocus(BScreen &screen, bool wait_for_end) { |
1983 | // Relevant resources: | 2025 | // Relevant resources: |
1984 | // resource.focus_last = whether we focus last focused when changing workspace | 2026 | // resource.focus_last = whether we focus last focused when changing workspace |
1985 | // Fluxbox::FocusModel = sloppy, click, whatever | 2027 | // Fluxbox::FocusModel = sloppy, click, whatever |
1986 | WinClient *next_focus = screen.getLastFocusedWindow(screen.currentWorkspaceID()); | 2028 | if (wait_for_end) { |
2029 | if (m_focus_revert_screen == 0) { | ||
2030 | m_focus_revert_screen = &screen; | ||
2031 | return; | ||
2032 | } else if (m_focus_revert_screen == &screen) | ||
2033 | return; | ||
2034 | else | ||
2035 | cerr<<"Unexpected screen in revertFocus()"<<endl; | ||
2036 | } | ||
2037 | |||
2038 | WinClient *next_focus = 0; | ||
2039 | long ignore_event = 0; | ||
2040 | if (screen.doFocusLast()) { | ||
2041 | next_focus = screen.getLastFocusedWindow(screen.currentWorkspaceID()); | ||
2042 | |||
2043 | // when doFocusLast is set, we don't do exact sloppy focus - we | ||
2044 | // go to the last focused window, rather than the pointer window | ||
2045 | // i.e. we ignore any EnterNotify events until the focus sending arrives | ||
2046 | ignore_event = EnterNotify; | ||
2047 | } | ||
1987 | 2048 | ||
1988 | // if setting focus fails, or isn't possible, fallback correctly | 2049 | // if setting focus fails, or isn't possible, fallback correctly |
1989 | if (!(next_focus && next_focus->fbwindow() && | 2050 | if (!(next_focus && next_focus->fbwindow() && |
1990 | next_focus->fbwindow()->setCurrentClient(*next_focus, true))) { | 2051 | next_focus->fbwindow()->setCurrentClient(*next_focus, true, ignore_event))) { |
1991 | setFocusedWindow(0); // so we don't get dangling m_focused_window pointer | 2052 | setFocusedWindow(0); // so we don't get dangling m_focused_window pointer |
1992 | switch (screen.getFocusModel()) { | 2053 | switch (screen.getFocusModel()) { |
1993 | case SLOPPYFOCUS: | 2054 | case SLOPPYFOCUS: |
@@ -2017,3 +2078,41 @@ void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) { | |||
2017 | screen.rootWindow().window(), True, | 2078 | screen.rootWindow().window(), True, |
2018 | GrabModeAsync, GrabModeAsync, CurrentTime); | 2079 | GrabModeAsync, GrabModeAsync, CurrentTime); |
2019 | } | 2080 | } |
2081 | |||
2082 | /** | ||
2083 | * Allows people to create special event exclusions/redirects | ||
2084 | * useful for getting around X followup events, or for | ||
2085 | * effectively grabbing things | ||
2086 | * The ignore is automatically removed when it finds the wakeup_win | ||
2087 | * with an event matching the wakeup_mask | ||
2088 | * ignore None means all windows | ||
2089 | */ | ||
2090 | void Fluxbox::addRedirectEvent(BScreen *screen, | ||
2091 | long catch_type, Window catch_win, | ||
2092 | long stop_type, Window stop_win, | ||
2093 | Window redirect_win) { | ||
2094 | RedirectEvent * re = new RedirectEvent(); | ||
2095 | re->screen = screen; | ||
2096 | re->catch_type = catch_type; | ||
2097 | re->catch_win = catch_win; | ||
2098 | re->stop_type = stop_type; | ||
2099 | re->stop_win = stop_win; | ||
2100 | re->redirect_win = redirect_win; | ||
2101 | |||
2102 | m_redirect_events.push_back(re); | ||
2103 | } | ||
2104 | |||
2105 | // So that an object may remove the ignore on its own | ||
2106 | void Fluxbox::removeRedirectEvent(long stop_type, Window stop_win) { | ||
2107 | RedirectEvents::iterator it = m_redirect_events.begin(); | ||
2108 | RedirectEvents::iterator it_end = m_redirect_events.end(); | ||
2109 | RedirectEvent *re = 0; | ||
2110 | for (; it != it_end; ++it) { | ||
2111 | re = *it; | ||
2112 | if (re->stop_type == re->stop_type && re->stop_win == stop_win) { | ||
2113 | m_redirect_events.erase(it); | ||
2114 | delete re; | ||
2115 | return; | ||
2116 | } | ||
2117 | } | ||
2118 | } | ||