Set EWMH active window to None when none has focus
Patch status: merged
Patch by Tony Crisci
Long description:
_NET_ACTIVE_WINDOW: > The window ID of the currently active window or None if no window has > the focus. This fixes a bug that would not update _NET_ACTIVE_WINDOW when focus changed to an i3 container without a window such as a branch or workspace content container.
To apply this patch, use:
curl http://cr.i3wm.org/patch/563/raw.patch | git am
b/src/x.c
22 |
@@ -1013,6 +1013,8 @@ void x_push_changes(Con *con) { |
23 |
to_focus, focused, focused->name); |
24 |
send_take_focus(to_focus, last_timestamp); |
25 |
|
26 |
+ ewmh_update_active_window((con_has_managed_window(focused) ? focused->window->id : XCB_WINDOW_NONE)); |
27 |
+ |
28 |
if (to_focus != last_focused && is_con_attached(focused)) |
29 |
ipc_send_window_event("focus", focused); |
30 |
} else { |
31 |
@@ -1030,7 +1032,7 @@ void x_push_changes(Con *con) { |
32 |
xcb_change_window_attributes(conn, focused->window->id, XCB_CW_EVENT_MASK, values); |
33 |
} |
34 |
|
35 |
- ewmh_update_active_window(to_focus); |
36 |
+ ewmh_update_active_window((con_has_managed_window(focused) ? focused->window->id : XCB_WINDOW_NONE)); |
37 |
|
38 |
if (to_focus != XCB_NONE && to_focus != last_focused && focused->window != NULL && is_con_attached(focused)) |
39 |
ipc_send_window_event("focus", focused); |
40 |
@@ -1043,6 +1045,7 @@ void x_push_changes(Con *con) { |
41 |
if (focused_id == XCB_NONE) { |
42 |
DLOG("Still no window focused, better set focus to the root window\n"); |
43 |
xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, root, XCB_CURRENT_TIME); |
44 |
+ ewmh_update_active_window(XCB_WINDOW_NONE); |
45 |
focused_id = root; |
46 |
} |
47 |
|
b/testcases/t/195-net-active-window.t
52 |
@@ -15,7 +15,8 @@ |
53 |
# (unless you are already familiar with Perl) |
54 |
# |
55 |
# Verifies that the _NET_ACTIVE_WINDOW message only changes focus when the |
56 |
-# window is on a visible workspace. |
57 |
+# window is on a visible workspace and that focus changes properly update this |
58 |
+# property on the root window. |
59 |
# ticket #774, bug still present in commit 1e49f1b08a3035c1f238fcd6615e332216ab582e |
60 |
# ticket #1136, bug still present in commit fd07f989fdf441ef335245dd3436a70ff60e8896 |
61 |
use i3test; |
62 |
@@ -40,6 +41,23 @@ sub send_net_active_window { |
63 |
$x->send_event(0, $x->get_root_window(), X11::XCB::EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg); |
64 |
} |
65 |
|
66 |
+sub get_net_active_window { |
67 |
+ my $cookie = $x->get_property( |
68 |
+ 0, |
69 |
+ $x->get_root_window(), |
70 |
+ $x->atom(name => '_NET_ACTIVE_WINDOW')->id, |
71 |
+ $x->atom(name => 'WINDOW')->id, |
72 |
+ 0, |
73 |
+ 4096, |
74 |
+ ); |
75 |
+ my $reply = $x->get_property_reply($cookie->{sequence}); |
76 |
+ my $len = $reply->{length}; |
77 |
+ |
78 |
+ return -1 if $len == 0; |
79 |
+ return unpack("L", $reply->{value}); |
80 |
+ |
81 |
+} |
82 |
+ |
83 |
my $ws1 = fresh_workspace; |
84 |
my $win1 = open_window; |
85 |
my $win2 = open_window; |
86 |
@@ -113,4 +131,28 @@ send_net_active_window($scratch->id); |
87 |
|
88 |
is($x->input_focus, $win3->id, 'window 3 still focused'); |
89 |
|
90 |
+################################################################################ |
91 |
+# Verify that the _NET_ACTIVE_WINDOW property is updated on the root window |
92 |
+# correctly. |
93 |
+################################################################################ |
94 |
+ |
95 |
+fresh_workspace; |
96 |
+ |
97 |
+is(get_net_active_window(), 0, 'workspace content focus is indicated by the root property as "None" window'); |
98 |
+ |
99 |
+my $win4 = open_window; |
100 |
+ |
101 |
+cmd '[id="' . $win4->id . '"] focus'; |
102 |
+ |
103 |
+is(get_net_active_window(), $win4->id, 'window 4 is indicated as focused by the root property'); |
104 |
+ |
105 |
+# make a branch |
106 |
+open_window; |
107 |
+open_window; |
108 |
+cmd 'split h'; |
109 |
+open_window; |
110 |
+cmd 'focus parent'; |
111 |
+ |
112 |
+is(get_net_active_window(), 0, 'branch focus is indicated by the root property as "None" window'); |
113 |
+ |
114 |
done_testing; |