1 |
lack 10/05/29 15:01:29 |
2 |
|
3 |
Added: strictmousefocus-1.1.1.patch |
4 |
mousefocus-1.1.1-r2.patch |
5 |
Log: |
6 |
Fix focus-follows-mouse (Bug #290649) |
7 |
(Portage version: 2.1.8.3/cvs/Linux i686) |
8 |
|
9 |
Revision Changes Path |
10 |
1.1 x11-wm/fluxbox/files/strictmousefocus-1.1.1.patch |
11 |
|
12 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-wm/fluxbox/files/strictmousefocus-1.1.1.patch?rev=1.1&view=markup |
13 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-wm/fluxbox/files/strictmousefocus-1.1.1.patch?rev=1.1&content-type=text/plain |
14 |
|
15 |
Index: strictmousefocus-1.1.1.patch |
16 |
=================================================================== |
17 |
From a830cf18ce0830451208157ecd0997521e171522 Mon Sep 17 00:00:00 2001 |
18 |
From: Jim Ramsay <jim.ramsay@××××××××.com> |
19 |
Date: Fri, 28 May 2010 13:22:13 -0400 |
20 |
Subject: [PATCH 1/2] Add new focus model: StrictMouseFocus |
21 |
|
22 |
This is not actually implemented yet, but from now on, "MouseFocus" means: |
23 |
Focus follows mouse only when you are moving the mouse, any EnterNotify events |
24 |
caused by non-mouse operations (window closing, keycommands, changing |
25 |
desktops) will *not* shift focus |
26 |
|
27 |
And once fully-implemented, "StrictMouseFocus" will mean: |
28 |
Focus follows mouse on every EnterNotify event (except when the "ClientMenu" |
29 |
closes or during alt+tab window cycling) |
30 |
--- |
31 |
doc/fluxbox.1.in | 7 +++++-- |
32 |
nls/fluxbox-nls.hh | 1 + |
33 |
src/FocusControl.cc | 5 +++++ |
34 |
src/FocusControl.hh | 7 ++++--- |
35 |
src/Screen.cc | 7 ++++++- |
36 |
5 files changed, 21 insertions(+), 6 deletions(-) |
37 |
|
38 |
diff --git a/doc/fluxbox.1.in b/doc/fluxbox.1.in |
39 |
index 11f70d9..86802b9 100644 |
40 |
--- a/doc/fluxbox.1.in |
41 |
+++ b/doc/fluxbox.1.in |
42 |
@@ -910,10 +910,13 @@ session\.screen0\.followModel: <model> |
43 |
be focused\. `Ignore\' does nothing, and `Follow\' uses the setting in |
44 |
session\.screen0\.userFollowModel\. Default: Ignore |
45 |
|
46 |
-session\.screen0\.focusModel: ClickToFocus|MouseFocus |
47 |
+session\.screen0\.focusModel: ClickToFocus|MouseFocus|StrictMouseFocus |
48 |
This controls how windows gain focus via the mouse\. With `ClickToFocus\', |
49 |
the user must click on the window\. With `MouseFocus\', windows gain focus |
50 |
- whenever the mouse moves over them\. Default: ClickToFocus |
51 |
+ whenever the mouse moves over them, but only when the mouse is moving. |
52 |
+ With `StrictMouseFocus\', windows gain focus whenever the mouse enters any |
53 |
+ exposed area, even if this is due to layer changes, window movement, |
54 |
+ changing desktops, closing windows, etc\. Default: ClickToFocus |
55 |
|
56 |
session\.screen0\.autoRaise: <boolean> |
57 |
When True, this setting automatically raises any window that gains focus\. |
58 |
diff --git a/nls/fluxbox-nls.hh b/nls/fluxbox-nls.hh |
59 |
index a304995..178c2f2 100644 |
60 |
--- a/nls/fluxbox-nls.hh |
61 |
+++ b/nls/fluxbox-nls.hh |
62 |
@@ -84,6 +84,7 @@ enum { |
63 |
ConfigmenuMaxIgnoreInc = 27, |
64 |
ConfigmenuMaxDisableMove = 28, |
65 |
ConfigmenuMaxDisableResize = 29, |
66 |
+ ConfigmenuStrictMouseFocus = 30, |
67 |
|
68 |
EwmhSet = 5, |
69 |
EwmhOutOfMemoryClientList = 1, |
70 |
diff --git a/src/FocusControl.cc b/src/FocusControl.cc |
71 |
index e0a3662..66a2ed8 100644 |
72 |
--- a/src/FocusControl.cc |
73 |
+++ b/src/FocusControl.cc |
74 |
@@ -491,6 +491,7 @@ void FocusControl::revertFocus(BScreen &screen) { |
75 |
else { |
76 |
switch (screen.focusControl().focusModel()) { |
77 |
case FocusControl::MOUSEFOCUS: |
78 |
+ case FocusControl::STRICTMOUSEFOCUS: |
79 |
XSetInputFocus(screen.rootWindow().display(), |
80 |
PointerRoot, None, CurrentTime); |
81 |
break; |
82 |
@@ -596,6 +597,8 @@ std::string FbTk::Resource<FocusControl::FocusModel>::getString() const { |
83 |
switch (m_value) { |
84 |
case FocusControl::MOUSEFOCUS: |
85 |
return string("MouseFocus"); |
86 |
+ case FocusControl::STRICTMOUSEFOCUS: |
87 |
+ return string("StrictMouseFocus"); |
88 |
case FocusControl::CLICKFOCUS: |
89 |
return string("ClickFocus"); |
90 |
} |
91 |
@@ -608,6 +611,8 @@ void FbTk::Resource<FocusControl::FocusModel>:: |
92 |
setFromString(char const *strval) { |
93 |
if (strcasecmp(strval, "MouseFocus") == 0) |
94 |
m_value = FocusControl::MOUSEFOCUS; |
95 |
+ else if (strcasecmp(strval, "StrictMouseFocus") == 0) |
96 |
+ m_value = FocusControl::STRICTMOUSEFOCUS; |
97 |
else if (strcasecmp(strval, "ClickToFocus") == 0) |
98 |
m_value = FocusControl::CLICKFOCUS; |
99 |
else |
100 |
diff --git a/src/FocusControl.hh b/src/FocusControl.hh |
101 |
index 91681ab..72eec11 100644 |
102 |
--- a/src/FocusControl.hh |
103 |
+++ b/src/FocusControl.hh |
104 |
@@ -42,8 +42,9 @@ public: |
105 |
typedef std::list<Focusable *> Focusables; |
106 |
/// main focus model |
107 |
enum FocusModel { |
108 |
- MOUSEFOCUS = 0, ///< focus follows mouse |
109 |
- CLICKFOCUS ///< focus on click |
110 |
+ MOUSEFOCUS = 0, ///< focus follows mouse, but only when the mouse is moving |
111 |
+ CLICKFOCUS, ///< focus on click |
112 |
+ STRICTMOUSEFOCUS ///< focus always follows mouse, even when stationary |
113 |
}; |
114 |
/// focus model for tabs |
115 |
enum TabFocusModel { |
116 |
@@ -90,7 +91,7 @@ public: |
117 |
*/ |
118 |
void dirFocus(FluxboxWindow &win, FocusDir dir); |
119 |
/// @return true if focus mode is mouse focus |
120 |
- bool isMouseFocus() const { return focusModel() == MOUSEFOCUS; } |
121 |
+ bool isMouseFocus() const { return focusModel() != CLICKFOCUS; } |
122 |
/// @return true if tab focus mode is mouse tab focus |
123 |
bool isMouseTabFocus() const { return tabFocusModel() == MOUSETABFOCUS; } |
124 |
|
125 |
diff --git a/src/Screen.cc b/src/Screen.cc |
126 |
index 649ea2b..0271868 100644 |
127 |
--- a/src/Screen.cc |
128 |
+++ b/src/Screen.cc |
129 |
@@ -1615,8 +1615,13 @@ void BScreen::setupConfigmenu(FbTk::Menu &menu) { |
130 |
"Click To Focus", "Click to focus", |
131 |
FocusControl::CLICKFOCUS); |
132 |
_FOCUSITEM(Configmenu, MouseFocus, |
133 |
- "Mouse Focus", "Mouse Focus", |
134 |
+ "Mouse Focus (Keyboard Friendly)", |
135 |
+ "Mouse Focus (Keyboard Friendly)", |
136 |
FocusControl::MOUSEFOCUS); |
137 |
+ _FOCUSITEM(Configmenu, StrictMouseFocus, |
138 |
+ "Mouse Focus (Strict)", |
139 |
+ "Mouse Focus (Strict)", |
140 |
+ FocusControl::STRICTMOUSEFOCUS); |
141 |
#undef _FOCUSITEM |
142 |
|
143 |
focus_menu->insert(new FbTk::MenuSeparator()); |
144 |
-- |
145 |
1.7.1 |
146 |
|
147 |
|
148 |
From 9db301c26e27e4d139dff424f8eab2f8def30cb5 Mon Sep 17 00:00:00 2001 |
149 |
From: Jim Ramsay <jim.ramsay@××××××××.com> |
150 |
Date: Fri, 28 May 2010 15:50:15 -0400 |
151 |
Subject: [PATCH 2/2] Implement StrictMouseFocus |
152 |
|
153 |
As noted in the previous commit, StrictMouseFocus now works as advertised: |
154 |
Focus follows mouse on every EnterNotify event (except when the "ClientMenu" |
155 |
closes or during alt+tab window cycling) |
156 |
--- |
157 |
src/ClientMenu.cc | 7 ++++++- |
158 |
src/FocusControl.cc | 19 ++++++++++++++----- |
159 |
src/FocusControl.hh | 10 ++++++++-- |
160 |
3 files changed, 28 insertions(+), 8 deletions(-) |
161 |
|
162 |
diff --git a/src/ClientMenu.cc b/src/ClientMenu.cc |
163 |
index f5af305..46306d9 100644 |
164 |
--- a/src/ClientMenu.cc |
165 |
+++ b/src/ClientMenu.cc |
166 |
@@ -25,6 +25,7 @@ |
167 |
#include "Screen.hh" |
168 |
#include "Window.hh" |
169 |
#include "WindowCmd.hh" |
170 |
+#include "FocusControl.hh" |
171 |
#include <X11/keysym.h> |
172 |
|
173 |
#include "FbTk/MenuItem.hh" |
174 |
@@ -52,8 +53,12 @@ public: |
175 |
|
176 |
m_client.focus(); |
177 |
fbwin->raise(); |
178 |
- if ((mods & ControlMask) == 0) |
179 |
+ if ((mods & ControlMask) == 0) { |
180 |
+ // Ignore any focus changes due to this menu closing |
181 |
+ // (even in StrictMouseFocus mode) |
182 |
+ m_client.screen().focusControl().ignoreAtPointer(true); |
183 |
parent->hide(); |
184 |
+ } |
185 |
} |
186 |
|
187 |
const std::string &label() const { return m_client.title(); } |
188 |
diff --git a/src/FocusControl.cc b/src/FocusControl.cc |
189 |
index 66a2ed8..44cd81b 100644 |
190 |
--- a/src/FocusControl.cc |
191 |
+++ b/src/FocusControl.cc |
192 |
@@ -403,21 +403,30 @@ void FocusControl::dirFocus(FluxboxWindow &win, FocusDir dir) { |
193 |
|
194 |
} |
195 |
|
196 |
-void FocusControl::ignoreAtPointer() |
197 |
+void FocusControl::ignoreAtPointer(bool force) |
198 |
{ |
199 |
- int ignore_i; |
200 |
+ int ignore_i, ignore_x, ignore_y; |
201 |
unsigned int ignore_ui; |
202 |
Window ignore_w; |
203 |
|
204 |
XQueryPointer(m_screen.rootWindow().display(), |
205 |
m_screen.rootWindow().window(), &ignore_w, &ignore_w, |
206 |
- &m_ignore_mouse_x, &m_ignore_mouse_y, |
207 |
+ &ignore_x, &ignore_y, |
208 |
&ignore_i, &ignore_i, &ignore_ui); |
209 |
+ |
210 |
+ this->ignoreAt(ignore_x, ignore_y, force); |
211 |
+} |
212 |
+ |
213 |
+void FocusControl::ignoreAt(int x, int y, bool force) |
214 |
+{ |
215 |
+ if (force || this->focusModel() == MOUSEFOCUS) { |
216 |
+ m_ignore_mouse_x = x; m_ignore_mouse_y = y; |
217 |
+ } |
218 |
} |
219 |
|
220 |
-void FocusControl::ignoreAt(int x, int y) |
221 |
+void FocusControl::ignoreCancel() |
222 |
{ |
223 |
- m_ignore_mouse_x = x; m_ignore_mouse_y = y; |
224 |
+ m_ignore_mouse_x = m_ignore_mouse_y = -1; |
225 |
} |
226 |
|
227 |
bool FocusControl::isIgnored(int x, int y) |
228 |
diff --git a/src/FocusControl.hh b/src/FocusControl.hh |
229 |
index 72eec11..c265253 100644 |
230 |
--- a/src/FocusControl.hh |
231 |
+++ b/src/FocusControl.hh |
232 |
@@ -96,9 +96,15 @@ public: |
233 |
bool isMouseTabFocus() const { return tabFocusModel() == MOUSETABFOCUS; } |
234 |
|
235 |
/// Set the "ignore" pointer location to the current pointer location |
236 |
- void ignoreAtPointer(); |
237 |
+ /// @param force If true, ignore even in StrictMouseFocus mode |
238 |
+ void ignoreAtPointer(bool force = false); |
239 |
/// Set the "ignore" pointer location to the given coordinates |
240 |
- void ignoreAt(int x, int y); |
241 |
+ /// @param x Current X position of the pointer |
242 |
+ /// @param y Current Y position of the pointer |
243 |
+ /// @param force If true, ignore even in StrictMouseFocus mode |
244 |
+ void ignoreAt(int x, int y, bool force = false); |
245 |
+ /// unset the "ignore" pointer location |
246 |
+ void ignoreCancel(); |
247 |
/// @return true if events at the given X/Y coordinate should be ignored |
248 |
/// (ie, they were previously cached via one of the ignoreAt calls) |
249 |
bool isIgnored(int x, int y); |
250 |
-- |
251 |
1.7.1 |
252 |
|
253 |
|
254 |
|
255 |
|
256 |
1.1 x11-wm/fluxbox/files/mousefocus-1.1.1-r2.patch |
257 |
|
258 |
file : http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-wm/fluxbox/files/mousefocus-1.1.1-r2.patch?rev=1.1&view=markup |
259 |
plain: http://sources.gentoo.org/viewvc.cgi/gentoo-x86/x11-wm/fluxbox/files/mousefocus-1.1.1-r2.patch?rev=1.1&content-type=text/plain |
260 |
|
261 |
Index: mousefocus-1.1.1-r2.patch |
262 |
=================================================================== |
263 |
From 998d9ea7942e3bcb07b52e06d08ef69bbe552944 Mon Sep 17 00:00:00 2001 |
264 |
From: Jim Ramsay <i.am@×××××××××.com> |
265 |
Date: Fri, 30 Jan 2009 10:41:27 -0500 |
266 |
Subject: [PATCH 1/2] Added facility to selectively ignore EnterNotify events |
267 |
|
268 |
This will be used to avoid some situations where an EnterNotify event should not |
269 |
focus the window beneath the mouse cursor. For example, when a menu (or any |
270 |
window for that matter) is unmapped, focus should not pass to whatever window is |
271 |
beneath the current location of the mouse cursor, but to the previous window in |
272 |
the focus list. |
273 |
|
274 |
This was first noticed when using the ClientMenu feature with |
275 |
focus-follows-mouse on -> The focus would always end up on the window beneath |
276 |
the mouse pointer, not the window selected in the menu. |
277 |
--- |
278 |
src/FocusControl.cc | 25 ++++++++++++++++++++++++- |
279 |
src/FocusControl.hh | 10 ++++++++++ |
280 |
src/Window.cc | 8 ++++++-- |
281 |
3 files changed, 40 insertions(+), 3 deletions(-) |
282 |
|
283 |
diff --git a/src/FocusControl.cc b/src/FocusControl.cc |
284 |
index cead827..e0a3662 100644 |
285 |
--- a/src/FocusControl.cc |
286 |
+++ b/src/FocusControl.cc |
287 |
@@ -81,7 +81,8 @@ FocusControl::FocusControl(BScreen &screen): |
288 |
m_focused_win_list(screen), m_creation_order_win_list(screen), |
289 |
m_cycling_list(0), |
290 |
m_was_iconic(false), |
291 |
- m_cycling_last(0) { |
292 |
+ m_cycling_last(0), |
293 |
+ m_ignore_mouse_x(-1), m_ignore_mouse_y(-1) { |
294 |
|
295 |
m_cycling_window = m_focused_list.clientList().end(); |
296 |
|
297 |
@@ -402,6 +403,28 @@ void FocusControl::dirFocus(FluxboxWindow &win, FocusDir dir) { |
298 |
|
299 |
} |
300 |
|
301 |
+void FocusControl::ignoreAtPointer() |
302 |
+{ |
303 |
+ int ignore_i; |
304 |
+ unsigned int ignore_ui; |
305 |
+ Window ignore_w; |
306 |
+ |
307 |
+ XQueryPointer(m_screen.rootWindow().display(), |
308 |
+ m_screen.rootWindow().window(), &ignore_w, &ignore_w, |
309 |
+ &m_ignore_mouse_x, &m_ignore_mouse_y, |
310 |
+ &ignore_i, &ignore_i, &ignore_ui); |
311 |
+} |
312 |
+ |
313 |
+void FocusControl::ignoreAt(int x, int y) |
314 |
+{ |
315 |
+ m_ignore_mouse_x = x; m_ignore_mouse_y = y; |
316 |
+} |
317 |
+ |
318 |
+bool FocusControl::isIgnored(int x, int y) |
319 |
+{ |
320 |
+ return x == m_ignore_mouse_x && y == m_ignore_mouse_y; |
321 |
+} |
322 |
+ |
323 |
void FocusControl::removeClient(WinClient &client) { |
324 |
if (client.screen().isShuttingdown()) |
325 |
return; |
326 |
diff --git a/src/FocusControl.hh b/src/FocusControl.hh |
327 |
index 4de4310..91681ab 100644 |
328 |
--- a/src/FocusControl.hh |
329 |
+++ b/src/FocusControl.hh |
330 |
@@ -93,6 +93,15 @@ public: |
331 |
bool isMouseFocus() const { return focusModel() == MOUSEFOCUS; } |
332 |
/// @return true if tab focus mode is mouse tab focus |
333 |
bool isMouseTabFocus() const { return tabFocusModel() == MOUSETABFOCUS; } |
334 |
+ |
335 |
+ /// Set the "ignore" pointer location to the current pointer location |
336 |
+ void ignoreAtPointer(); |
337 |
+ /// Set the "ignore" pointer location to the given coordinates |
338 |
+ void ignoreAt(int x, int y); |
339 |
+ /// @return true if events at the given X/Y coordinate should be ignored |
340 |
+ /// (ie, they were previously cached via one of the ignoreAt calls) |
341 |
+ bool isIgnored(int x, int y); |
342 |
+ |
343 |
/// @return true if cycling is in progress |
344 |
bool isCycling() const { return m_cycling_list != 0; } |
345 |
/// Appends a client to the front of the focus list |
346 |
@@ -157,6 +166,7 @@ private: |
347 |
const FocusableList *m_cycling_list; |
348 |
Focusable *m_was_iconic; |
349 |
WinClient *m_cycling_last; |
350 |
+ int m_ignore_mouse_x, m_ignore_mouse_y; |
351 |
|
352 |
static WinClient *s_focused_window; |
353 |
static FluxboxWindow *s_focused_fbwindow; |
354 |
diff --git a/src/Window.cc b/src/Window.cc |
355 |
index 5d50fcf..fe32d29 100644 |
356 |
--- a/src/Window.cc |
357 |
+++ b/src/Window.cc |
358 |
@@ -2676,13 +2676,17 @@ void FluxboxWindow::enterNotifyEvent(XCrossingEvent &ev) { |
359 |
sa.enter = sa.leave = False; |
360 |
XCheckIfEvent(display, &dummy, queueScanner, (char *) &sa); |
361 |
|
362 |
- if ((!sa.leave || sa.inferior) && !screen().focusControl().isCycling() ) { |
363 |
+ if ((!sa.leave || sa.inferior) && |
364 |
+ !screen().focusControl().isCycling() && |
365 |
+ !screen().focusControl().isIgnored(ev.x_root, ev.y_root) ) { |
366 |
focus(); |
367 |
} |
368 |
} |
369 |
} |
370 |
|
371 |
- if (screen().focusControl().isMouseTabFocus() && client && client != m_client) { |
372 |
+ if (screen().focusControl().isMouseTabFocus() && |
373 |
+ client && client != m_client && |
374 |
+ !screen().focusControl().isIgnored(ev.x_root, ev.y_root) ) { |
375 |
setCurrentClient(*client, isFocused()); |
376 |
} |
377 |
|
378 |
-- |
379 |
1.7.1 |
380 |
|
381 |
|
382 |
From e16a6d1fa71825b5390d9139b771f470aeb03d79 Mon Sep 17 00:00:00 2001 |
383 |
From: Jim Ramsay <i.am@×××××××××.com> |
384 |
Date: Sat, 29 May 2010 09:30:48 -0400 |
385 |
Subject: [PATCH 2/2] Ignore EnterNotify when the ClientMenu closes |
386 |
|
387 |
This is so that the resulting exposition of a window belowe the ClientMenu will |
388 |
not steal focus from the window just focused by the ClientMenu. |
389 |
--- |
390 |
src/ClientMenu.cc | 7 ++++++- |
391 |
1 files changed, 6 insertions(+), 1 deletions(-) |
392 |
|
393 |
diff --git a/src/ClientMenu.cc b/src/ClientMenu.cc |
394 |
index f5af305..c49791c 100644 |
395 |
--- a/src/ClientMenu.cc |
396 |
+++ b/src/ClientMenu.cc |
397 |
@@ -25,6 +25,7 @@ |
398 |
#include "Screen.hh" |
399 |
#include "Window.hh" |
400 |
#include "WindowCmd.hh" |
401 |
+#include "FocusControl.hh" |
402 |
#include <X11/keysym.h> |
403 |
|
404 |
#include "FbTk/MenuItem.hh" |
405 |
@@ -52,8 +53,12 @@ public: |
406 |
|
407 |
m_client.focus(); |
408 |
fbwin->raise(); |
409 |
- if ((mods & ControlMask) == 0) |
410 |
+ if ((mods & ControlMask) == 0) { |
411 |
+ // Ignore any focus changes due to this menu closing |
412 |
+ // (even in StrictMouseFocus mode) |
413 |
+ m_client.screen().focusControl().ignoreAtPointer(); |
414 |
parent->hide(); |
415 |
+ } |
416 |
} |
417 |
|
418 |
const std::string &label() const { return m_client.title(); } |
419 |
-- |
420 |
1.7.1 |