diff options
author | fluxgen <fluxgen> | 2003-12-30 20:56:41 (GMT) |
---|---|---|
committer | fluxgen <fluxgen> | 2003-12-30 20:56:41 (GMT) |
commit | 3490c73f570cb43fcdea5c2f8770a379d721a73d (patch) | |
tree | c90fdca53a52d99bd5ef5f02356ab13f33eea639 /src/fluxbox.cc | |
parent | 4a8a7a32d4e3df3ffa7dc68482ff8f1053d257eb (diff) | |
download | fluxbox-3490c73f570cb43fcdea5c2f8770a379d721a73d.zip fluxbox-3490c73f570cb43fcdea5c2f8770a379d721a73d.tar.bz2 |
fixed focus issue
Diffstat (limited to 'src/fluxbox.cc')
-rw-r--r-- | src/fluxbox.cc | 164 |
1 files changed, 33 insertions, 131 deletions
diff --git a/src/fluxbox.cc b/src/fluxbox.cc index 9cad953..439ed8f 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.214 2003/12/21 22:42:31 fluxgen Exp $ | 25 | // $Id: fluxbox.cc,v 1.215 2003/12/30 20:56:40 fluxgen Exp $ |
26 | 26 | ||
27 | #include "fluxbox.hh" | 27 | #include "fluxbox.hh" |
28 | 28 | ||
@@ -194,13 +194,6 @@ setFromString(const char *strval) { | |||
194 | setDefaultValue(); | 194 | setDefaultValue(); |
195 | } | 195 | } |
196 | 196 | ||
197 | template<> | ||
198 | void FbTk::Resource<long>:: | ||
199 | setFromString(const char *strval) { | ||
200 | if (sscanf(strval, "%ld", &m_value) != 1) | ||
201 | setDefaultValue(); | ||
202 | } | ||
203 | |||
204 | //----------------------------------------------------------------- | 197 | //----------------------------------------------------------------- |
205 | //---- manipulators for int, bool, and some enums with Resource --- | 198 | //---- manipulators for int, bool, and some enums with Resource --- |
206 | //----------------------------------------------------------------- | 199 | //----------------------------------------------------------------- |
@@ -266,14 +259,6 @@ getString() { | |||
266 | } | 259 | } |
267 | 260 | ||
268 | template<> | 261 | template<> |
269 | string FbTk::Resource<long>:: | ||
270 | getString() { | ||
271 | char tmpstr[128]; | ||
272 | sprintf(tmpstr, "%ld", m_value); | ||
273 | return string(tmpstr); | ||
274 | } | ||
275 | |||
276 | template<> | ||
277 | void FbTk::Resource<Fluxbox::Layer>:: | 262 | void FbTk::Resource<Fluxbox::Layer>:: |
278 | setFromString(const char *strval) { | 263 | setFromString(const char *strval) { |
279 | int tempnum = 0; | 264 | int tempnum = 0; |
@@ -322,6 +307,20 @@ getString() { | |||
322 | return string(tmpstr); | 307 | return string(tmpstr); |
323 | } | 308 | } |
324 | } | 309 | } |
310 | template<> | ||
311 | void FbTk::Resource<long>:: | ||
312 | setFromString(const char *strval) { | ||
313 | if (sscanf(strval, "%ld", &m_value) != 1) | ||
314 | setDefaultValue(); | ||
315 | } | ||
316 | |||
317 | |||
318 | string FbTk::Resource<long>:: | ||
319 | getString() { | ||
320 | char tmpstr[128]; | ||
321 | sprintf(tmpstr, "%ld", m_value); | ||
322 | return string(tmpstr); | ||
323 | } | ||
325 | 324 | ||
326 | static Window last_bad_window = None; | 325 | static Window last_bad_window = None; |
327 | namespace { | 326 | namespace { |
@@ -393,11 +392,12 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile | |||
393 | m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"), | 392 | m_rc_cache_life(m_resourcemanager, 5, "session.cacheLife", "Session.CacheLife"), |
394 | m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"), | 393 | m_rc_cache_max(m_resourcemanager, 200, "session.cacheMax", "Session.CacheMax"), |
395 | m_rc_auto_raise_delay(m_resourcemanager, 250, "session.autoRaiseDelay", "Session.AutoRaiseDelay"), | 394 | m_rc_auto_raise_delay(m_resourcemanager, 250, "session.autoRaiseDelay", "Session.AutoRaiseDelay"), |
396 | m_focused_window(0), | 395 | m_focused_window(0), m_masked_window(0), |
397 | m_mousescreen(0), | 396 | m_mousescreen(0), |
398 | m_keyscreen(0), | 397 | m_keyscreen(0), |
399 | m_watching_screen(0), m_watch_keyrelease(0), | 398 | m_watching_screen(0), m_watch_keyrelease(0), |
400 | m_last_time(0), | 399 | m_last_time(0), |
400 | m_masked(0), | ||
401 | m_rc_file(rcfilename ? rcfilename : ""), | 401 | m_rc_file(rcfilename ? rcfilename : ""), |
402 | m_argv(argv), m_argc(argc), | 402 | m_argv(argv), m_argc(argc), |
403 | m_starting(true), | 403 | m_starting(true), |
@@ -405,9 +405,7 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile | |||
405 | m_server_grabs(0), | 405 | m_server_grabs(0), |
406 | m_randr_event_type(0), | 406 | m_randr_event_type(0), |
407 | m_RC_PATH("fluxbox"), | 407 | m_RC_PATH("fluxbox"), |
408 | m_RC_INIT_FILE("init"), | 408 | m_RC_INIT_FILE("init") { |
409 | m_focus_revert_screen(0) | ||
410 | { | ||
411 | 409 | ||
412 | 410 | ||
413 | if (s_singleton != 0) | 411 | if (s_singleton != 0) |
@@ -552,7 +550,7 @@ Fluxbox::Fluxbox(int argc, char **argv, const char *dpy_name, const char *rcfile | |||
552 | m_atomhandler[atomh]->initForScreen(*screen); | 550 | m_atomhandler[atomh]->initForScreen(*screen); |
553 | } | 551 | } |
554 | 552 | ||
555 | revertFocus(*screen, false); // make sure focus style is correct | 553 | revertFocus(*screen); // make sure focus style is correct |
556 | 554 | ||
557 | } // end init screens | 555 | } // end init screens |
558 | 556 | ||
@@ -624,10 +622,6 @@ void Fluxbox::eventLoop() { | |||
624 | } else { | 622 | } else { |
625 | last_bad_window = None; | 623 | last_bad_window = None; |
626 | handleEvent(&e); | 624 | handleEvent(&e); |
627 | if (m_focus_revert_screen != 0) { | ||
628 | revertFocus(*m_focus_revert_screen, false); | ||
629 | m_focus_revert_screen = 0; | ||
630 | } | ||
631 | } | 625 | } |
632 | } else { | 626 | } else { |
633 | FbTk::Timer::updateTimers(ConnectionNumber(disp)); //handle all timers | 627 | FbTk::Timer::updateTimers(ConnectionNumber(disp)); //handle all timers |
@@ -718,52 +712,18 @@ void Fluxbox::handleEvent(XEvent * const e) { | |||
718 | m_last_event = *e; | 712 | m_last_event = *e; |
719 | 713 | ||
720 | // it is possible (e.g. during moving) for a window | 714 | // it is possible (e.g. during moving) for a window |
721 | // to mask certain events to go somewhere (e.g. to that window) | 715 | // to mask all events to go to it |
722 | if (!m_redirect_events.empty()) { | 716 | if ((m_masked == e->xany.window) && m_masked_window) { |
723 | 717 | if (e->type == MotionNotify) { | |
724 | bool drop_event = false; | 718 | m_last_time = e->xmotion.time; |
725 | RedirectEvents::iterator it = m_redirect_events.begin(); | 719 | m_masked_window->motionNotifyEvent(e->xmotion); |
726 | RedirectEvents::iterator it_end = m_redirect_events.end(); | ||
727 | RedirectEvent *re = 0; | ||
728 | bool matched = false; | ||
729 | Window orig_win = e->xany.window; | ||
730 | |||
731 | // look through all registered redirects | ||
732 | while (it != it_end) { | ||
733 | matched = false; | ||
734 | re = *it; | ||
735 | // do we affect this event? | ||
736 | if (e->type == re->catch_type && | ||
737 | (re->catch_win == None || | ||
738 | re->catch_win == orig_win)) { | ||
739 | matched = true; | ||
740 | // redirect? | ||
741 | if (re->redirect_win != None) { | ||
742 | e->xany.window = re->redirect_win; | ||
743 | } else { | ||
744 | drop_event = true; | ||
745 | } | ||
746 | } | ||
747 | |||
748 | // does this event stop this redirect? | ||
749 | if (e->type == re->stop_type && | ||
750 | ((re->stop_win == None && matched) || | ||
751 | re->stop_win == orig_win)) { | ||
752 | RedirectEvents::iterator next_it = it; | ||
753 | ++next_it; | ||
754 | delete (*it); | ||
755 | m_redirect_events.erase(it); | ||
756 | it = next_it; | ||
757 | } else | ||
758 | ++it; | ||
759 | } | ||
760 | |||
761 | // if one of the redirects says to drop it, we do | ||
762 | if (drop_event) | ||
763 | return; | 720 | return; |
721 | } else if (e->type == ButtonRelease) { | ||
722 | e->xbutton.window = m_masked_window->fbWindow().window(); | ||
723 | } | ||
724 | |||
764 | } | 725 | } |
765 | 726 | ||
766 | |||
767 | // update key/mouse screen and last time before we enter other eventhandlers | 727 | // update key/mouse screen and last time before we enter other eventhandlers |
768 | if (e->type == KeyPress || | 728 | if (e->type == KeyPress || |
769 | e->type == KeyRelease) { | 729 | e->type == KeyRelease) { |
@@ -1211,7 +1171,7 @@ void Fluxbox::handleKeyEvent(XKeyEvent &ke) { | |||
1211 | if (m_watching_screen && m_watch_keyrelease) { | 1171 | if (m_watching_screen && m_watch_keyrelease) { |
1212 | // mask the mod of the released key out | 1172 | // mask the mod of the released key out |
1213 | // won't mask anything if it isn't a mod | 1173 | // won't mask anything if it isn't a mod |
1214 | ke.state &= ~FbTk::KeyUtil::keycodeToModmask(ke.keycode); | 1174 | ke.state &= ~FbTk::KeyUtil::instance().keycodeToModmask(ke.keycode); |
1215 | 1175 | ||
1216 | if ((m_watch_keyrelease & ke.state) == 0) { | 1176 | if ((m_watch_keyrelease & ke.state) == 0) { |
1217 | 1177 | ||
@@ -1628,6 +1588,7 @@ void Fluxbox::load_rc() { | |||
1628 | else // expand tilde | 1588 | else // expand tilde |
1629 | *m_rc_stylefile = StringUtil::expandFilename(*m_rc_stylefile); | 1589 | *m_rc_stylefile = StringUtil::expandFilename(*m_rc_stylefile); |
1630 | 1590 | ||
1591 | |||
1631 | // expand tilde | 1592 | // expand tilde |
1632 | *m_rc_groupfile = StringUtil::expandFilename(*m_rc_groupfile); | 1593 | *m_rc_groupfile = StringUtil::expandFilename(*m_rc_groupfile); |
1633 | 1594 | ||
@@ -1934,35 +1895,15 @@ void Fluxbox::setFocusedWindow(WinClient *client) { | |||
1934 | * ignore_event means that it ignores the given event until | 1895 | * ignore_event means that it ignores the given event until |
1935 | * it gets a focusIn | 1896 | * it gets a focusIn |
1936 | */ | 1897 | */ |
1937 | void Fluxbox::revertFocus(BScreen &screen, bool wait_for_end) { | 1898 | void Fluxbox::revertFocus(BScreen &screen) { |
1938 | // Relevant resources: | 1899 | // Relevant resources: |
1939 | // resource.focus_last = whether we focus last focused when changing workspace | 1900 | // resource.focus_last = whether we focus last focused when changing workspace |
1940 | // BScreen::FocusModel = sloppy, click, whatever | 1901 | // BScreen::FocusModel = sloppy, click, whatever |
1941 | if (wait_for_end) { | 1902 | WinClient *next_focus = screen.getLastFocusedWindow(screen.currentWorkspaceID()); |
1942 | if (m_focus_revert_screen == 0) { | ||
1943 | m_focus_revert_screen = &screen; | ||
1944 | return; | ||
1945 | } else if (m_focus_revert_screen == &screen) | ||
1946 | return; | ||
1947 | else | ||
1948 | cerr<<"Unexpected screen in revertFocus()"<<endl; | ||
1949 | } | ||
1950 | |||
1951 | WinClient *next_focus = 0; | ||
1952 | long ignore_event = 0; | ||
1953 | if (screen.doFocusLast()) { | ||
1954 | next_focus = screen.getLastFocusedWindow(screen.currentWorkspaceID()); | ||
1955 | |||
1956 | // when doFocusLast is set, we don't do exact sloppy focus - we | ||
1957 | // go to the last focused window, rather than the pointer window | ||
1958 | // i.e. we ignore any EnterNotify events until the focus sending arrives | ||
1959 | if (screen.getFocusModel() != BScreen::CLICKTOFOCUS) | ||
1960 | ignore_event = EnterNotify; | ||
1961 | } | ||
1962 | 1903 | ||
1963 | // if setting focus fails, or isn't possible, fallback correctly | 1904 | // if setting focus fails, or isn't possible, fallback correctly |
1964 | if (!(next_focus && next_focus->fbwindow() && | 1905 | if (!(next_focus && next_focus->fbwindow() && |
1965 | next_focus->fbwindow()->setCurrentClient(*next_focus, true, ignore_event))) { | 1906 | next_focus->fbwindow()->setCurrentClient(*next_focus, true))) { |
1966 | setFocusedWindow(0); // so we don't get dangling m_focused_window pointer | 1907 | setFocusedWindow(0); // so we don't get dangling m_focused_window pointer |
1967 | switch (screen.getFocusModel()) { | 1908 | switch (screen.getFocusModel()) { |
1968 | case BScreen::SLOPPYFOCUS: | 1909 | case BScreen::SLOPPYFOCUS: |
@@ -1990,42 +1931,3 @@ void Fluxbox::watchKeyRelease(BScreen &screen, unsigned int mods) { | |||
1990 | screen.rootWindow().window(), True, | 1931 | screen.rootWindow().window(), True, |
1991 | GrabModeAsync, GrabModeAsync, CurrentTime); | 1932 | GrabModeAsync, GrabModeAsync, CurrentTime); |
1992 | } | 1933 | } |
1993 | |||
1994 | /** | ||
1995 | * Allows people to create special event exclusions/redirects | ||
1996 | * useful for getting around X followup events, or for | ||
1997 | * effectively grabbing things | ||
1998 | * The ignore is automatically removed when it finds the wakeup_win | ||
1999 | * with an event matching the wakeup_mask | ||
2000 | * ignore None means all windows | ||
2001 | */ | ||
2002 | void Fluxbox::addRedirectEvent(BScreen *screen, | ||
2003 | long catch_type, Window catch_win, | ||
2004 | long stop_type, Window stop_win, | ||
2005 | Window redirect_win) { | ||
2006 | RedirectEvent * re = new RedirectEvent(); | ||
2007 | re->screen = screen; | ||
2008 | re->catch_type = catch_type; | ||
2009 | re->catch_win = catch_win; | ||
2010 | re->stop_type = stop_type; | ||
2011 | re->stop_win = stop_win; | ||
2012 | re->redirect_win = redirect_win; | ||
2013 | |||
2014 | m_redirect_events.push_back(re); | ||
2015 | } | ||
2016 | |||
2017 | // So that an object may remove the ignore on its own | ||
2018 | // stop_type of None means remove all redirects for this window | ||
2019 | void Fluxbox::removeRedirectEvent(long stop_type, Window stop_win) { | ||
2020 | RedirectEvents::iterator it = m_redirect_events.begin(); | ||
2021 | RedirectEvents::iterator it_end = m_redirect_events.end(); | ||
2022 | RedirectEvent *re = 0; | ||
2023 | for (; it != it_end; ++it) { | ||
2024 | re = *it; | ||
2025 | if (re->stop_win == stop_win && (stop_type == None || stop_type == re->stop_type)) { | ||
2026 | m_redirect_events.erase(it); | ||
2027 | delete re; | ||
2028 | return; | ||
2029 | } | ||
2030 | } | ||
2031 | } | ||