summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Ramsay <i.am@jimramsay.com>2009-01-30 15:41:27 (GMT)
committerJim Ramsay <i.am@jimramsay.com>2009-02-27 20:18:07 (GMT)
commit5c7784affe78467d7ef4e52e22da83c341622d53 (patch)
treecbb83969ab422857bac498d51238789b0dfc6648
parente7700166604d737ff23427877100c8888c761494 (diff)
downloadfluxbox_lack-5c7784affe78467d7ef4e52e22da83c341622d53.zip
fluxbox_lack-5c7784affe78467d7ef4e52e22da83c341622d53.tar.bz2
Added facility to selectively ignore EnterNotify events
This will be used to avoid some situations where an EnterNotify event should not focus the window beneath the mouse cursor. For example, when a menu (or any window for that matter) is unmapped, focus should not pass to whatever window is beneath the current location of the mouse cursor, but to the previous window in the focus list. This was first noticed when using the ClientMenu feature with focus-follows-mouse on -> The focus would always end up on the window beneath the mouse pointer, not the window selected in the menu.
-rw-r--r--src/FocusControl.cc25
-rw-r--r--src/FocusControl.hh10
-rw-r--r--src/Window.cc8
3 files changed, 40 insertions, 3 deletions
diff --git a/src/FocusControl.cc b/src/FocusControl.cc
index 78752bb..701373b 100644
--- a/src/FocusControl.cc
+++ b/src/FocusControl.cc
@@ -81,7 +81,8 @@ FocusControl::FocusControl(BScreen &screen):
81 m_focused_win_list(screen), m_creation_order_win_list(screen), 81 m_focused_win_list(screen), m_creation_order_win_list(screen),
82 m_cycling_list(0), 82 m_cycling_list(0),
83 m_was_iconic(false), 83 m_was_iconic(false),
84 m_cycling_last(0) { 84 m_cycling_last(0),
85 m_ignore_mouse_x(-1), m_ignore_mouse_y(-1) {
85 86
86 m_cycling_window = m_focused_list.clientList().end(); 87 m_cycling_window = m_focused_list.clientList().end();
87 88
@@ -400,6 +401,28 @@ void FocusControl::dirFocus(FluxboxWindow &win, FocusDir dir) {
400 401
401} 402}
402 403
404void FocusControl::ignoreAtPointer()
405{
406 int ignore_i;
407 unsigned int ignore_ui;
408 Window ignore_w;
409
410 XQueryPointer(m_screen.rootWindow().display(),
411 m_screen.rootWindow().window(), &ignore_w, &ignore_w,
412 &m_ignore_mouse_x, &m_ignore_mouse_y,
413 &ignore_i, &ignore_i, &ignore_ui);
414}
415
416void FocusControl::ignoreAt(int x, int y)
417{
418 m_ignore_mouse_x = x; m_ignore_mouse_y = y;
419}
420
421bool FocusControl::isIgnored(int x, int y)
422{
423 return x == m_ignore_mouse_x && y == m_ignore_mouse_y;
424}
425
403void FocusControl::removeClient(WinClient &client) { 426void FocusControl::removeClient(WinClient &client) {
404 if (client.screen().isShuttingdown()) 427 if (client.screen().isShuttingdown())
405 return; 428 return;
diff --git a/src/FocusControl.hh b/src/FocusControl.hh
index 4de4310..91681ab 100644
--- a/src/FocusControl.hh
+++ b/src/FocusControl.hh
@@ -93,6 +93,15 @@ public:
93 bool isMouseFocus() const { return focusModel() == MOUSEFOCUS; } 93 bool isMouseFocus() const { return focusModel() == MOUSEFOCUS; }
94 /// @return true if tab focus mode is mouse tab focus 94 /// @return true if tab focus mode is mouse tab focus
95 bool isMouseTabFocus() const { return tabFocusModel() == MOUSETABFOCUS; } 95 bool isMouseTabFocus() const { return tabFocusModel() == MOUSETABFOCUS; }
96
97 /// Set the "ignore" pointer location to the current pointer location
98 void ignoreAtPointer();
99 /// Set the "ignore" pointer location to the given coordinates
100 void ignoreAt(int x, int y);
101 /// @return true if events at the given X/Y coordinate should be ignored
102 /// (ie, they were previously cached via one of the ignoreAt calls)
103 bool isIgnored(int x, int y);
104
96 /// @return true if cycling is in progress 105 /// @return true if cycling is in progress
97 bool isCycling() const { return m_cycling_list != 0; } 106 bool isCycling() const { return m_cycling_list != 0; }
98 /// Appends a client to the front of the focus list 107 /// Appends a client to the front of the focus list
@@ -157,6 +166,7 @@ private:
157 const FocusableList *m_cycling_list; 166 const FocusableList *m_cycling_list;
158 Focusable *m_was_iconic; 167 Focusable *m_was_iconic;
159 WinClient *m_cycling_last; 168 WinClient *m_cycling_last;
169 int m_ignore_mouse_x, m_ignore_mouse_y;
160 170
161 static WinClient *s_focused_window; 171 static WinClient *s_focused_window;
162 static FluxboxWindow *s_focused_fbwindow; 172 static FluxboxWindow *s_focused_fbwindow;
diff --git a/src/Window.cc b/src/Window.cc
index 4b4d1dc..513fbb6 100644
--- a/src/Window.cc
+++ b/src/Window.cc
@@ -2680,13 +2680,17 @@ void FluxboxWindow::enterNotifyEvent(XCrossingEvent &ev) {
2680 sa.enter = sa.leave = False; 2680 sa.enter = sa.leave = False;
2681 XCheckIfEvent(display, &dummy, queueScanner, (char *) &sa); 2681 XCheckIfEvent(display, &dummy, queueScanner, (char *) &sa);
2682 2682
2683 if ((!sa.leave || sa.inferior) && !screen().focusControl().isCycling() ) { 2683 if ((!sa.leave || sa.inferior) &&
2684 !screen().focusControl().isCycling() &&
2685 !screen().focusControl().isIgnored(ev.x_root, ev.y_root) ) {
2684 focus(); 2686 focus();
2685 } 2687 }
2686 } 2688 }
2687 } 2689 }
2688 2690
2689 if (screen().focusControl().isMouseTabFocus() && client && client != m_client) { 2691 if (screen().focusControl().isMouseTabFocus() &&
2692 client && client != m_client &&
2693 !screen().focusControl().isIgnored(ev.x_root, ev.y_root) ) {
2690 setCurrentClient(*client, isFocused()); 2694 setCurrentClient(*client, isFocused());
2691 } 2695 }
2692 2696