Implement the window::urgent event
Patch status: needinfo
Patch by Tony Crisci
Long description:
The window::urgent event is emitted when a container becomes urgent or loses its urgent status.
To apply this patch, use:
curl http://cr.i3wm.org/patch/600/raw.patch | git am
b/docs/ipc
19 |
@@ -722,6 +722,7 @@ This event consists of a single serialized map containing a property |
20 |
* +title+ - the window's title has changed |
21 |
* +fullscreen_mode+ - the window has entered or exited fullscreen mode |
22 |
* +move+ - the window has changed its position in the tree |
23 |
+* +urgent+ - the window has become urgent or lost its urgent status |
24 |
|
25 |
Additionally a +container (object)+ field will be present, which consists |
26 |
of the window's parent container. Be aware that for the "new" event, the |
b/src/con.c
31 |
@@ -231,6 +231,7 @@ void con_focus(Con *con) { |
32 |
con->urgent = false; |
33 |
con_update_parents_urgency(con); |
34 |
workspace_update_urgent_flag(con_get_workspace(con)); |
35 |
+ ipc_send_window_event("urgent", con); |
36 |
} |
37 |
} |
38 |
|
39 |
@@ -1599,14 +1600,16 @@ void con_set_urgency(Con *con, bool urgent) { |
40 |
|
41 |
con_update_parents_urgency(con); |
42 |
|
43 |
- if (con->urgent == urgent) |
44 |
- LOG("Urgency flag changed to %d\n", con->urgent); |
45 |
- |
46 |
Con *ws; |
47 |
/* Set the urgency flag on the workspace, if a workspace could be found |
48 |
* (for dock clients, that is not the case). */ |
49 |
if ((ws = con_get_workspace(con)) != NULL) |
50 |
workspace_update_urgent_flag(ws); |
51 |
+ |
52 |
+ if (con->urgent == urgent) { |
53 |
+ LOG("Urgency flag changed to %d\n", con->urgent); |
54 |
+ ipc_send_window_event("urgent", con); |
55 |
+ } |
56 |
} |
57 |
|
58 |
/* |
b/src/workspace.c
63 |
@@ -326,11 +326,14 @@ static void workspace_reassign_sticky(Con *con) { |
64 |
static void workspace_defer_update_urgent_hint_cb(EV_P_ ev_timer *w, int revents) { |
65 |
Con *con = w->data; |
66 |
|
67 |
- DLOG("Resetting urgency flag of con %p by timer\n", con); |
68 |
- con->urgent = false; |
69 |
- con_update_parents_urgency(con); |
70 |
- workspace_update_urgent_flag(con_get_workspace(con)); |
71 |
- tree_render(); |
72 |
+ if (con->urgent) { |
73 |
+ DLOG("Resetting urgency flag of con %p by timer\n", con); |
74 |
+ con->urgent = false; |
75 |
+ con_update_parents_urgency(con); |
76 |
+ workspace_update_urgent_flag(con_get_workspace(con)); |
77 |
+ ipc_send_window_event("urgent", con); |
78 |
+ tree_render(); |
79 |
+ } |
80 |
|
81 |
ev_timer_stop(main_loop, con->urgency_timer); |
82 |
FREE(con->urgency_timer); |
83 |
@@ -386,6 +389,7 @@ static void _workspace_show(Con *workspace) { |
84 |
* focus and thereby immediately destroy it */ |
85 |
if (next->urgent && (int)(config.workspace_urgency_timer * 1000) > 0) { |
86 |
/* focus for now… */ |
87 |
+ next->urgent = false; |
88 |
con_focus(next); |
89 |
|
90 |
/* … but immediately reset urgency flags; they will be set to false by |
b/testcases/t/232-ipc-window-urgent.t
96 |
@@ -0,0 +1,68 @@ |
97 |
+#!perl |
98 |
+# vim:ts=4:sw=4:expandtab |
99 |
+# |
100 |
+# Please read the following documents before working on tests: |
101 |
+# • http://build.i3wm.org/docs/testsuite.html |
102 |
+# (or docs/testsuite) |
103 |
+# |
104 |
+# • http://build.i3wm.org/docs/lib-i3test.html |
105 |
+# (alternatively: perldoc ./testcases/lib/i3test.pm) |
106 |
+# |
107 |
+# • http://build.i3wm.org/docs/ipc.html |
108 |
+# (or docs/ipc) |
109 |
+# |
110 |
+# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf |
111 |
+# (unless you are already familiar with Perl) |
112 |
+# |
113 |
+# Test that the window::urgent event works correctly. The window::urgent event |
114 |
+# should be emitted when a window becomes urgent or loses its urgent status. |
115 |
+# |
116 |
+use i3test; |
117 |
+ |
118 |
+my $config = <<EOT; |
119 |
+# i3 config file (v4) |
120 |
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 |
121 |
+ |
122 |
+force_display_urgency_hint 0ms |
123 |
+EOT |
124 |
+ |
125 |
+my $i3 = i3(get_socket_path()); |
126 |
+$i3->connect()->recv; |
127 |
+ |
128 |
+my $cv; |
129 |
+$i3->subscribe({ |
130 |
+ window => sub { |
131 |
+ my ($event) = @_; |
132 |
+ $cv->send($event) if $event->{change} eq 'urgent'; |
133 |
+ } |
134 |
+})->recv; |
135 |
+ |
136 |
+my $t; |
137 |
+$t = AnyEvent->timer( |
138 |
+ after => 0.5, |
139 |
+ cb => sub { |
140 |
+ $cv->send(0); |
141 |
+ } |
142 |
+); |
143 |
+ |
144 |
+$cv = AnyEvent->condvar; |
145 |
+fresh_workspace; |
146 |
+my $win = open_window; |
147 |
+my $dummy_win = open_window; |
148 |
+ |
149 |
+$win->add_hint('urgency'); |
150 |
+my $event = $cv->recv; |
151 |
+ |
152 |
+isnt($event, 0, 'an urgent con should emit the window::urgent event'); |
153 |
+is($event->{container}->{window}, $win->{id}, 'the event should contain information about the window'); |
154 |
+is($event->{container}->{urgent}, 1, 'the container should be urgent'); |
155 |
+ |
156 |
+$cv = AnyEvent->condvar; |
157 |
+$win->delete_hint('urgency'); |
158 |
+my $event = $cv->recv; |
159 |
+ |
160 |
+isnt($event, 0, 'an urgent con should emit the window::urgent event'); |
161 |
+is($event->{container}->{window}, $win->{id}, 'the event should contain information about the window'); |
162 |
+is($event->{container}->{urgent}, 0, 'the container should not be urgent'); |
163 |
+ |
164 |
+done_testing; |