i3 - improved tiling WM


Fix test 158

Patch status: superseded

Patch by Tony Crisci

Long description:

Test 158 was not properly testing the absense of the WM_TAKE_FOCUS
ClientMessage because of a bad assumption about how sync_with_i3
presently works.

This fix implements a function that should work in the way it was
previously intended.

To apply this patch, use:
curl http://cr.i3wm.org/patch/500/raw.patch | git am

b/testcases/t/158-wm_take_focus.t

19
@@ -17,15 +17,62 @@
20
 # Tests if the WM_TAKE_FOCUS protocol is correctly handled by i3
21
 #
22
 use i3test;
23
+use X11::XCB qw(:all);
24
+
25
+# Determines whether or not we received a WM_TAKE_FOCUS ClientMessage. Sends a
26
+# sync message to i3 which will send a reply after WM_TAKE_FOCUS should have
27
+# been received. If we get the sync message instead of WM_TAKE_FOCUS, we assume
28
+# it was not sent.
29
+sub recv_take_focus {
30
+    my ($window) = @_;
31
+
32
+    my $take_focus = $x->atom(name => 'WM_TAKE_FOCUS');
33
+    # max ulong
34
+    my $not_take_focus = 4294967295;
35
+
36
+    my $root = $x->get_root_window();
37
+
38
+    # Generate a ClientMessage, see xcb_client_message_t
39
+    my $msg = pack "CCSLLLLLLL",
40
+         CLIENT_MESSAGE,    # response_type
41
+         32,                # format
42
+         0,                 # sequence
43
+         $root,             # destination window
44
+         $x->atom(name => 'I3_SYNC')->id,
45
+
46
+         $window->id,       # data[0]: our own window id
47
+         $not_take_focus,   # data[1]: a value to identify the request
48
+         0,
49
+         0,
50
+         0;
51
+
52
+    $x->send_event(0, $root, EVENT_MASK_SUBSTRUCTURE_REDIRECT, $msg);
53
+
54
+    my $result = 0;
55
+
56
+    wait_for_event 1, sub {
57
+        # A return value of 0 means "continue to wait" and a return value of 1
58
+        # means "the event was found"
59
+        return 0 unless $_[0]->{response_type} == 161;
60
+        my ($event) = @_;
61
+        my @data = unpack("L2", $event->{data});
62
+
63
+        return 1 if $data[0] == $window->id && $data[1] == $not_take_focus;
64
+
65
+        $result = $data[0] == $take_focus->id;
66
+
67
+        return $result;
68
+    };
69
+
70
+    return $result;
71
+}
72
 
73
 subtest 'Window without WM_TAKE_FOCUS', sub {
74
     fresh_workspace;
75
 
76
     my $window = open_window;
77
-    # sync_with_i3 will send a ClientMessage to i3 and receive one targeted to
78
-    # $window->id. If it receives WM_TAKE_FOCUS instead, it will return 0, thus
79
-    # the test will fail.
80
-    ok(sync_with_i3(window_id => $window->id), 'did not receive ClientMessage');
81
+
82
+    ok(!recv_take_focus($window), 'Did not receive ClientMessage');
83
 
84
     done_testing;
85
 };
86
@@ -42,11 +89,7 @@ subtest 'Window with WM_TAKE_FOCUS', sub {
87
 
88
     $window->map;
89
 
90
-    ok(wait_for_event(1, sub {
91
-        return 0 unless $_[0]->{response_type} == 161;
92
-        my ($data, $time) = unpack("L2", $_[0]->{data});
93
-        return ($data == $take_focus->id);
94
-    }), 'got ClientMessage with WM_TAKE_FOCUS atom');
95
+    ok(recv_take_focus($window), 'got ClientMessage with WM_TAKE_FOCUS atom');
96
 
97
     done_testing;
98
 };