i3 - improved tiling WM


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;