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 {
|