aboutsummaryrefslogtreecommitdiff
path: root/src/fluxbox.cc
diff options
context:
space:
mode:
authorfluxgen <fluxgen>2003-12-30 20:56:41 (GMT)
committerfluxgen <fluxgen>2003-12-30 20:56:41 (GMT)
commit3490c73f570cb43fcdea5c2f8770a379d721a73d (patch)
treec90fdca53a52d99bd5ef5f02356ab13f33eea639 /src/fluxbox.cc
parent4a8a7a32d4e3df3ffa7dc68482ff8f1053d257eb (diff)
downloadfluxbox-3490c73f570cb43fcdea5c2f8770a379d721a73d.zip
fluxbox-3490c73f570cb43fcdea5c2f8770a379d721a73d.tar.bz2
fixed focus issue
Diffstat (limited to 'src/fluxbox.cc')
-rw-r--r--src/fluxbox.cc164
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
197template<>
198void FbTk::Resource<long>::
199setFromString(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
268template<> 261template<>
269string FbTk::Resource<long>::
270getString() {
271 char tmpstr[128];
272 sprintf(tmpstr, "%ld", m_value);
273 return string(tmpstr);
274}
275
276template<>
277void FbTk::Resource<Fluxbox::Layer>:: 262void FbTk::Resource<Fluxbox::Layer>::
278setFromString(const char *strval) { 263setFromString(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}
310template<>
311void FbTk::Resource<long>::
312setFromString(const char *strval) {
313 if (sscanf(strval, "%ld", &m_value) != 1)
314 setDefaultValue();
315}
316
317
318string FbTk::Resource<long>::
319getString() {
320 char tmpstr[128];
321 sprintf(tmpstr, "%ld", m_value);
322 return string(tmpstr);
323}
325 324
326static Window last_bad_window = None; 325static Window last_bad_window = None;
327namespace { 326namespace {
@@ -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 */
1937void Fluxbox::revertFocus(BScreen &screen, bool wait_for_end) { 1898void 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 */
2002void 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
2019void 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}