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; |