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/589/raw.patch | git am
b/src/con.c
18 |
@@ -231,6 +231,7 @@ void con_focus(Con *con) { |
19 |
con->urgent = false; |
20 |
con_update_parents_urgency(con); |
21 |
workspace_update_urgent_flag(con_get_workspace(con)); |
22 |
+ ipc_send_window_event("urgent", con); |
23 |
} |
24 |
} |
25 |
|
26 |
@@ -1580,6 +1581,9 @@ void con_set_urgency(Con *con, bool urgent) { |
27 |
return; |
28 |
} |
29 |
|
30 |
+ if (con->urgent == urgent) |
31 |
+ return; |
32 |
+ |
33 |
if (con->urgency_timer == NULL) { |
34 |
con->urgent = urgent; |
35 |
} else |
36 |
@@ -1597,14 +1601,16 @@ void con_set_urgency(Con *con, bool urgent) { |
37 |
|
38 |
con_update_parents_urgency(con); |
39 |
|
40 |
- if (con->urgent == urgent) |
41 |
- LOG("Urgency flag changed to %d\n", con->urgent); |
42 |
- |
43 |
Con *ws; |
44 |
/* Set the urgency flag on the workspace, if a workspace could be found |
45 |
* (for dock clients, that is not the case). */ |
46 |
if ((ws = con_get_workspace(con)) != NULL) |
47 |
workspace_update_urgent_flag(ws); |
48 |
+ |
49 |
+ if (con->urgent == urgent) { |
50 |
+ LOG("Urgency flag changed to %d\n", con->urgent); |
51 |
+ ipc_send_window_event("urgent", con); |
52 |
+ } |
53 |
} |
54 |
|
55 |
/* |
b/src/workspace.c
60 |
@@ -325,11 +325,14 @@ static void workspace_reassign_sticky(Con *con) { |
61 |
static void workspace_defer_update_urgent_hint_cb(EV_P_ ev_timer *w, int revents) { |
62 |
Con *con = w->data; |
63 |
|
64 |
- DLOG("Resetting urgency flag of con %p by timer\n", con); |
65 |
- con->urgent = false; |
66 |
- con_update_parents_urgency(con); |
67 |
- workspace_update_urgent_flag(con_get_workspace(con)); |
68 |
- tree_render(); |
69 |
+ if (con->urgent) { |
70 |
+ DLOG("Resetting urgency flag of con %p by timer\n", con); |
71 |
+ con->urgent = false; |
72 |
+ con_update_parents_urgency(con); |
73 |
+ workspace_update_urgent_flag(con_get_workspace(con)); |
74 |
+ ipc_send_window_event("urgent", con); |
75 |
+ tree_render(); |
76 |
+ } |
77 |
|
78 |
ev_timer_stop(main_loop, con->urgency_timer); |
79 |
FREE(con->urgency_timer); |
80 |
@@ -385,6 +388,7 @@ static void _workspace_show(Con *workspace) { |
81 |
* focus and thereby immediately destroy it */ |
82 |
if (next->urgent && (int)(config.workspace_urgency_timer * 1000) > 0) { |
83 |
/* focus for now… */ |
84 |
+ next->urgent = false; |
85 |
con_focus(next); |
86 |
|
87 |
/* … but immediately reset urgency flags; they will be set to false by |
b/testcases/t/231-ipc-window-urgent.t
93 |
@@ -0,0 +1,67 @@ |
94 |
+#!perl |
95 |
+# vim:ts=4:sw=4:expandtab |
96 |
+# |
97 |
+# Please read the following documents before working on tests: |
98 |
+# • http://build.i3wm.org/docs/testsuite.html |
99 |
+# (or docs/testsuite) |
100 |
+# |
101 |
+# • http://build.i3wm.org/docs/lib-i3test.html |
102 |
+# (alternatively: perldoc ./testcases/lib/i3test.pm) |
103 |
+# |
104 |
+# • http://build.i3wm.org/docs/ipc.html |
105 |
+# (or docs/ipc) |
106 |
+# |
107 |
+# • http://onyxneon.com/books/modern_perl/modern_perl_a4.pdf |
108 |
+# (unless you are already familiar with Perl) |
109 |
+# |
110 |
+# Test that the window::urgent event works correctly |
111 |
+# Bug still in: 4.8-8-g20f1c92 |
112 |
+use i3test; |
113 |
+ |
114 |
+my $config = <<EOT; |
115 |
+# i3 config file (v4) |
116 |
+font -misc-fixed-medium-r-normal--13-120-75-75-C-70-iso10646-1 |
117 |
+ |
118 |
+force_display_urgency_hint 0ms |
119 |
+EOT |
120 |
+ |
121 |
+my $i3 = i3(get_socket_path()); |
122 |
+$i3->connect()->recv; |
123 |
+ |
124 |
+my $cv; |
125 |
+$i3->subscribe({ |
126 |
+ window => sub { |
127 |
+ my ($event) = @_; |
128 |
+ $cv->send($event) if $event->{change} eq 'urgent'; |
129 |
+ } |
130 |
+})->recv; |
131 |
+ |
132 |
+my $t; |
133 |
+$t = AnyEvent->timer( |
134 |
+ after => 0.5, |
135 |
+ cb => sub { |
136 |
+ $cv->send(0); |
137 |
+ } |
138 |
+); |
139 |
+ |
140 |
+$cv = AnyEvent->condvar; |
141 |
+fresh_workspace; |
142 |
+my $win = open_window; |
143 |
+my $dummy_win = open_window; |
144 |
+ |
145 |
+$win->add_hint('urgency'); |
146 |
+my $event = $cv->recv; |
147 |
+ |
148 |
+isnt($event, 0, 'an urgent con should emit the window::urgent event'); |
149 |
+is($event->{container}->{window}, $win->{id}, 'the event should contain information about the window'); |
150 |
+is($event->{container}->{urgent}, 1, 'the container should be urgent'); |
151 |
+ |
152 |
+$cv = AnyEvent->condvar; |
153 |
+$win->delete_hint('urgency'); |
154 |
+my $event = $cv->recv; |
155 |
+ |
156 |
+isnt($event, 0, 'an urgent con should emit the window::urgent event'); |
157 |
+is($event->{container}->{window}, $win->{id}, 'the event should contain information about the window'); |
158 |
+is($event->{container}->{urgent}, 0, 'the container should not be urgent'); |
159 |
+ |
160 |
+done_testing; |