diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | src/Screen.cc | 3 | ||||
-rw-r--r-- | src/Window.cc | 31 | ||||
-rw-r--r-- | src/Window.hh | 6 | ||||
-rw-r--r-- | src/fluxbox.cc | 131 | ||||
-rw-r--r-- | src/fluxbox.hh | 40 |
6 files changed, 182 insertions, 34 deletions
@@ -1,5 +1,10 @@ | |||
1 | (Format: Year/Month/Day) | 1 | (Format: Year/Month/Day) |
2 | Changes for 0.9.6: | 2 | Changes for 0.9.6: |
3 | *03/10/05: | ||
4 | * Make focusLast work for sloppy focus when changing workspace or | ||
5 | closing a window (Simon) | ||
6 | - also generalises event redirects (e.g. for window moving) | ||
7 | fluxbox.hh/cc Window.hh/cc Screen.cc | ||
3 | *03/10/04: | 8 | *03/10/04: |
4 | * Fix NLS bad message errors by adding explicit codeset entries (Simon) | 9 | * Fix NLS bad message errors by adding explicit codeset entries (Simon) |
5 | - thanks to Matt Hope for pointing us to the recent workaround from | 10 | - thanks to Matt Hope for pointing us to the recent workaround from |
diff --git a/src/Screen.cc b/src/Screen.cc index 487f0c0..3795455 100644 --- a/src/Screen.cc +++ b/src/Screen.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: Screen.cc,v 1.236 2003/10/02 16:14:41 rathnor Exp $ | 25 | // $Id: Screen.cc,v 1.237 2003/10/05 02:31:22 rathnor Exp $ |
26 | 26 | ||
27 | 27 | ||
28 | #include "Screen.hh" | 28 | #include "Screen.hh" |
@@ -836,6 +836,7 @@ void BScreen::changeWorkspaceID(unsigned int id) { | |||
836 | return; | 836 | return; |
837 | 837 | ||
838 | XSync(FbTk::App::instance()->display(), true); | 838 | XSync(FbTk::App::instance()->display(), true); |
839 | |||
839 | WinClient *focused_client = Fluxbox::instance()->getFocusedWindow(); | 840 | WinClient *focused_client = Fluxbox::instance()->getFocusedWindow(); |
840 | FluxboxWindow *focused = 0; | 841 | FluxboxWindow *focused = 0; |
841 | if (focused_client) | 842 | if (focused_client) |
diff --git a/src/Window.cc b/src/Window.cc index 47fe00c..e104ae6 100644 --- a/src/Window.cc +++ b/src/Window.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: Window.cc,v 1.238 2003/10/02 16:14:41 rathnor Exp $ | 25 | // $Id: Window.cc,v 1.239 2003/10/05 02:31:22 rathnor Exp $ |
26 | 26 | ||
27 | #include "Window.hh" | 27 | #include "Window.hh" |
28 | 28 | ||
@@ -888,7 +888,7 @@ void FluxboxWindow::updateClientLeftWindow() { | |||
888 | } | 888 | } |
889 | } | 889 | } |
890 | 890 | ||
891 | bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { | 891 | bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput, long ignore_event) { |
892 | // make sure it's in our list | 892 | // make sure it's in our list |
893 | if (client.m_win != this) | 893 | if (client.m_win != this) |
894 | return false; | 894 | return false; |
@@ -896,7 +896,7 @@ bool FluxboxWindow::setCurrentClient(WinClient &client, bool setinput) { | |||
896 | m_client = &client; | 896 | m_client = &client; |
897 | m_client->raise(); | 897 | m_client->raise(); |
898 | frame().setLabelButtonFocus(*m_labelbuttons[m_client]); | 898 | frame().setLabelButtonFocus(*m_labelbuttons[m_client]); |
899 | return setinput && setInputFocus(); | 899 | return setinput && setInputFocus(ignore_event); |
900 | } | 900 | } |
901 | 901 | ||
902 | bool FluxboxWindow::isGroupable() const { | 902 | bool FluxboxWindow::isGroupable() const { |
@@ -1138,7 +1138,7 @@ void FluxboxWindow::moveResize(int new_x, int new_y, | |||
1138 | // tried. A FocusqIn event should eventually arrive for that | 1138 | // tried. A FocusqIn event should eventually arrive for that |
1139 | // window if it actually got the focus, then setFocusedFlag is called, | 1139 | // window if it actually got the focus, then setFocusedFlag is called, |
1140 | // which updates all the graphics etc | 1140 | // which updates all the graphics etc |
1141 | bool FluxboxWindow::setInputFocus() { | 1141 | bool FluxboxWindow::setInputFocus(long ignore_event) { |
1142 | 1142 | ||
1143 | if (((signed) (frame().x() + frame().width())) < 0) { | 1143 | if (((signed) (frame().x() + frame().width())) < 0) { |
1144 | if (((signed) (frame().y() + frame().height())) < 0) { | 1144 | if (((signed) (frame().y() + frame().height())) < 0) { |
@@ -1181,6 +1181,14 @@ bool FluxboxWindow::setInputFocus() { | |||
1181 | if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE || | 1181 | if (m_client->getFocusMode() == WinClient::F_LOCALLYACTIVE || |
1182 | m_client->getFocusMode() == WinClient::F_PASSIVE) { | 1182 | m_client->getFocusMode() == WinClient::F_PASSIVE) { |
1183 | m_client->setInputFocus(RevertToPointerRoot, CurrentTime); | 1183 | m_client->setInputFocus(RevertToPointerRoot, CurrentTime); |
1184 | |||
1185 | // People can ignore an event until the focus comes through | ||
1186 | // this is most likely to be an EnterNotify for sloppy focus | ||
1187 | if (ignore_event) | ||
1188 | Fluxbox::instance()->addRedirectEvent( | ||
1189 | &screen(), ignore_event, None, | ||
1190 | FocusIn, m_client->window(), None); | ||
1191 | |||
1184 | // this may or may not send, but we've setInputFocus already, so return true | 1192 | // this may or may not send, but we've setInputFocus already, so return true |
1185 | m_client->sendFocus(); | 1193 | m_client->sendFocus(); |
1186 | return true; | 1194 | return true; |
@@ -2724,7 +2732,16 @@ void FluxboxWindow::startMoving(Window win) { | |||
2724 | if (m_windowmenu.isVisible()) | 2732 | if (m_windowmenu.isVisible()) |
2725 | m_windowmenu.hide(); | 2733 | m_windowmenu.hide(); |
2726 | 2734 | ||
2727 | fluxbox->maskWindowEvents(screen().rootWindow().window(), this); | 2735 | // The "stop" window and event aren't going to happen (since it's |
2736 | // grabbed, so they are just so we can remove it in stopMoving) | ||
2737 | fluxbox->addRedirectEvent(&screen(), | ||
2738 | MotionNotify, screen().rootWindow().window(), | ||
2739 | MotionNotify, fbWindow().window(), | ||
2740 | fbWindow().window()); | ||
2741 | fluxbox->addRedirectEvent(&screen(), | ||
2742 | ButtonRelease, screen().rootWindow().window(), | ||
2743 | ButtonRelease, fbWindow().window(), | ||
2744 | fbWindow().window()); | ||
2728 | 2745 | ||
2729 | m_last_move_x = frame().x(); | 2746 | m_last_move_x = frame().x(); |
2730 | m_last_move_y = frame().y(); | 2747 | m_last_move_y = frame().y(); |
@@ -2742,8 +2759,8 @@ void FluxboxWindow::stopMoving() { | |||
2742 | moving = false; | 2759 | moving = false; |
2743 | Fluxbox *fluxbox = Fluxbox::instance(); | 2760 | Fluxbox *fluxbox = Fluxbox::instance(); |
2744 | 2761 | ||
2745 | fluxbox->maskWindowEvents(0, 0); | 2762 | fluxbox->removeRedirectEvent(MotionNotify, fbWindow().window()); |
2746 | 2763 | fluxbox->removeRedirectEvent(ButtonRelease, fbWindow().window()); | |
2747 | 2764 | ||
2748 | if (! screen().doOpaqueMove()) { | 2765 | if (! screen().doOpaqueMove()) { |
2749 | parent().drawRectangle(screen().rootTheme().opGC(), | 2766 | parent().drawRectangle(screen().rootTheme().opGC(), |
diff --git a/src/Window.hh b/src/Window.hh index 9d94166..8831522 100644 --- a/src/Window.hh +++ b/src/Window.hh | |||
@@ -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: Window.hh,v 1.97 2003/09/29 14:58:15 rathnor Exp $ | 25 | // $Id: Window.hh,v 1.98 2003/10/05 02:31:23 rathnor Exp $ |
26 | 26 | ||
27 | #ifndef WINDOW_HH | 27 | #ifndef WINDOW_HH |
28 | #define WINDOW_HH | 28 | #define WINDOW_HH |
@@ -167,14 +167,14 @@ public: | |||
167 | /// remove client from client list | 167 | /// remove client from client list |
168 | bool removeClient(WinClient &client); | 168 | bool removeClient(WinClient &client); |
169 | /// set new current client and raise it | 169 | /// set new current client and raise it |
170 | bool setCurrentClient(WinClient &client, bool setinput = true); | 170 | bool setCurrentClient(WinClient &client, bool setinput = true, long ignore_event = 0); |
171 | WinClient *findClient(Window win); | 171 | WinClient *findClient(Window win); |
172 | void nextClient(); | 172 | void nextClient(); |
173 | void prevClient(); | 173 | void prevClient(); |
174 | void moveClientLeft(); | 174 | void moveClientLeft(); |
175 | void moveClientRight(); | 175 | void moveClientRight(); |
176 | 176 | ||
177 | bool setInputFocus(); | 177 | bool setInputFocus(long ignore_event = 0); |
178 | void raiseAndFocus() { raise(); setInputFocus(); } | 178 | void raiseAndFocus() { raise(); setInputFocus(); } |
179 | void setFocusFlag(bool flag); | 179 | void setFocusFlag(bool flag); |
180 | // map this window | 180 | // map this window |
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 | } | ||
diff --git a/src/fluxbox.hh b/src/fluxbox.hh index 6459385..5d3f505 100644 --- a/src/fluxbox.hh +++ b/src/fluxbox.hh | |||
@@ -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.hh,v 1.72 2003/09/10 09:51:58 fluxgen Exp $ | 25 | // $Id: fluxbox.hh,v 1.73 2003/10/05 02:31:23 rathnor Exp $ |
26 | 26 | ||
27 | #ifndef FLUXBOX_HH | 27 | #ifndef FLUXBOX_HH |
28 | #define FLUXBOX_HH | 28 | #define FLUXBOX_HH |
@@ -148,13 +148,11 @@ public: | |||
148 | inline unsigned int getCacheLife() const { return *m_rc_cache_life * 60000; } | 148 | inline unsigned int getCacheLife() const { return *m_rc_cache_life * 60000; } |
149 | inline unsigned int getCacheMax() const { return *m_rc_cache_max; } | 149 | inline unsigned int getCacheMax() const { return *m_rc_cache_max; } |
150 | 150 | ||
151 | inline void maskWindowEvents(Window w, FluxboxWindow *bw) | ||
152 | { m_masked = w; m_masked_window = bw; } | ||
153 | |||
154 | void watchKeyRelease(BScreen &screen, unsigned int mods); | 151 | void watchKeyRelease(BScreen &screen, unsigned int mods); |
155 | 152 | ||
156 | void setFocusedWindow(WinClient *w); | 153 | void setFocusedWindow(WinClient *w); |
157 | void revertFocus(BScreen &screen); | 154 | // focus revert gets delayed until the end of the event handle |
155 | void revertFocus(BScreen &screen, bool wait_for_end = true); | ||
158 | void shutdown(); | 156 | void shutdown(); |
159 | void load_rc(BScreen &scr); | 157 | void load_rc(BScreen &scr); |
160 | void loadRootCommand(BScreen &scr); | 158 | void loadRootCommand(BScreen &scr); |
@@ -204,6 +202,21 @@ public: | |||
204 | // screen we are watching for modifier changes | 202 | // screen we are watching for modifier changes |
205 | BScreen *watchingScreen() { return m_watching_screen; } | 203 | BScreen *watchingScreen() { return m_watching_screen; } |
206 | const XEvent &lastEvent() const { return m_last_event; } | 204 | const XEvent &lastEvent() const { return m_last_event; } |
205 | |||
206 | /** | ||
207 | * Allows people to create special event exclusions/redirects | ||
208 | * useful for getting around X followup events, or for | ||
209 | * effectively grabbing things | ||
210 | * The ignore is automatically removed when it finds the stop_win | ||
211 | * with an event matching the stop_type | ||
212 | * ignore None means all windows | ||
213 | */ | ||
214 | void addRedirectEvent(BScreen *screen, long catch_type, Window catch_win, | ||
215 | long stop_type, Window stop_win, Window redirect_win); | ||
216 | |||
217 | // So that an object may remove the ignore on its own | ||
218 | void removeRedirectEvent(long stop_type, Window stop_win); | ||
219 | |||
207 | private: | 220 | private: |
208 | 221 | ||
209 | typedef struct MenuTimestamp { | 222 | typedef struct MenuTimestamp { |
@@ -264,9 +277,20 @@ private: | |||
264 | ScreenList m_screen_list; | 277 | ScreenList m_screen_list; |
265 | 278 | ||
266 | WinClient *m_focused_window; | 279 | WinClient *m_focused_window; |
267 | FluxboxWindow *m_masked_window; | ||
268 | FbTk::Timer m_timer; | 280 | FbTk::Timer m_timer; |
269 | 281 | ||
282 | typedef struct RedirectEvent { | ||
283 | BScreen *screen; | ||
284 | long catch_type; | ||
285 | Window catch_win; | ||
286 | long stop_type; | ||
287 | Window stop_win; | ||
288 | Window redirect_win; | ||
289 | } RedirectEvent; | ||
290 | |||
291 | typedef std::list<RedirectEvent *> RedirectEvents; | ||
292 | |||
293 | RedirectEvents m_redirect_events; | ||
270 | BScreen *m_mousescreen, *m_keyscreen; | 294 | BScreen *m_mousescreen, *m_keyscreen; |
271 | BScreen *m_watching_screen; | 295 | BScreen *m_watching_screen; |
272 | unsigned int m_watch_keyrelease; | 296 | unsigned int m_watch_keyrelease; |
@@ -275,7 +299,6 @@ private: | |||
275 | 299 | ||
276 | bool m_reconfigure_wait, m_reread_menu_wait; | 300 | bool m_reconfigure_wait, m_reread_menu_wait; |
277 | Time m_last_time; | 301 | Time m_last_time; |
278 | Window m_masked; | ||
279 | std::string m_rc_file; ///< resource filename | 302 | std::string m_rc_file; ///< resource filename |
280 | char **m_argv; | 303 | char **m_argv; |
281 | int m_argc; | 304 | int m_argc; |
@@ -296,6 +319,9 @@ private: | |||
296 | const char *m_RC_PATH; | 319 | const char *m_RC_PATH; |
297 | const char *m_RC_INIT_FILE; | 320 | const char *m_RC_INIT_FILE; |
298 | Atom m_kwm1_dockwindow, m_kwm2_dockwindow; | 321 | Atom m_kwm1_dockwindow, m_kwm2_dockwindow; |
322 | |||
323 | // each event can only affect one screen (right?) | ||
324 | BScreen *m_focus_revert_screen; | ||
299 | }; | 325 | }; |
300 | 326 | ||
301 | 327 | ||