Dont set input focus and send WM_TAKE_FOCUS
Patch status: needinfo
Patch by Tony Crisci
Long description:
If input focus is set by the window manager, it is not necessary to send WM_TAKE_FOCUS because it has already taken focus. http://tronche.com/gui/x/icccm/sec-4.html#s-4.1.7 > The goal is to support window managers that want to assign the input > focus to a top-level window in such a way that the top-level window > either can assign it to one of its subwindows or can decline the offer > of the focus. For example, a clock or a text editor with no currently > open frames might not want to take focus even though the window > manager generally believes that clients should take the input focus > after being deiconified or raised. Both setting input focus and sending WM_TAKE_FOCUS is effectively setting focus on the window twice which is certainly against the spirit of the spec, if not the letter. fixes #1167
To apply this patch, use:
curl http://cr.i3wm.org/patch/497/raw.patch | git am
b/src/x.c
32 |
@@ -987,20 +987,16 @@ void x_push_changes(Con *con) { |
33 |
/* Invalidate focused_id to correctly focus new windows with the same ID */ |
34 |
focused_id = XCB_NONE; |
35 |
} else { |
36 |
- bool set_focus = true; |
37 |
if (focused->window != NULL && |
38 |
- focused->window->needs_take_focus) { |
39 |
+ focused->window->needs_take_focus && |
40 |
+ focused->window->doesnt_accept_focus) { |
41 |
DLOG("Updating focus by sending WM_TAKE_FOCUS to window 0x%08x (focused: %p / %s)\n", |
42 |
to_focus, focused, focused->name); |
43 |
send_take_focus(to_focus); |
44 |
- set_focus = !focused->window->doesnt_accept_focus; |
45 |
- DLOG("set_focus = %d\n", set_focus); |
46 |
|
47 |
- if (!set_focus && to_focus != last_focused && is_con_attached(focused)) |
48 |
+ if (to_focus != last_focused && is_con_attached(focused)) |
49 |
ipc_send_window_event("focus", focused); |
50 |
- } |
51 |
- |
52 |
- if (set_focus) { |
53 |
+ } else { |
54 |
DLOG("Updating focus (focused: %p / %s) to X11 window 0x%08x\n", focused, focused->name, to_focus); |
55 |
/* We remove XCB_EVENT_MASK_FOCUS_CHANGE from the event mask to get |
56 |
* no focus change events for our own focus changes. We only want |
b/testcases/t/158-wm_take_focus.t
61 |
@@ -30,7 +30,7 @@ subtest 'Window without WM_TAKE_FOCUS', sub { |
62 |
done_testing; |
63 |
}; |
64 |
|
65 |
-subtest 'Window with WM_TAKE_FOCUS', sub { |
66 |
+subtest 'Window with WM_TAKE_FOCUS and without InputHint', sub { |
67 |
fresh_workspace; |
68 |
|
69 |
my $take_focus = $x->atom(name => 'WM_TAKE_FOCUS'); |
70 |
@@ -40,6 +40,9 @@ subtest 'Window with WM_TAKE_FOCUS', sub { |
71 |
protocols => [ $take_focus ], |
72 |
}); |
73 |
|
74 |
+ # add a WM_HINTS property without the InputHint |
75 |
+ $window->delete_hint('input'); |
76 |
+ |
77 |
$window->map; |
78 |
|
79 |
ok(wait_for_event(1, sub { |