Add support for _NET_WM_STATE_DEMANDS_ATTENTION.
Patch status: needinfo
Patch by oblique
Long description:
_NET_WM_STATE_DEMANDS_ATTENTION indicates that some action in or with the window happened. It's a weaker hint than urgency flag of WM_HINTS, but some applications and almost all Qt applications use it instead of WM_HINTS' urgency flag (one example is Skype).
To apply this patch, use:
curl http://cr.i3wm.org/patch/60/raw.patch | git am
b/docs/hacking-howto
| 19 |
@@ -28,7 +28,8 @@ In the case of i3, the tasks (and order of them) are the following: |
| 20 |
the first client of X) and manage them (reparent them, create window |
| 21 |
decorations, etc.) |
| 22 |
. When new windows are created, manage them |
| 23 |
-. Handle the client’s `_WM_STATE` property, but only the `_WM_STATE_FULLSCREEN` |
| 24 |
+. Handle the client’s `_WM_STATE` property, but only `_WM_STATE_FULLSCREEN` and |
| 25 |
+ `_NET_WM_STATE_DEMANDS_ATTENTION` |
| 26 |
. Handle the client’s `WM_NAME` property |
| 27 |
. Handle the client’s size hints to display them proportionally |
| 28 |
. Handle the client’s urgency hint |
b/include/atoms.xmacro
| 33 |
@@ -2,6 +2,7 @@ xmacro(_NET_SUPPORTED) |
| 34 |
xmacro(_NET_SUPPORTING_WM_CHECK) |
| 35 |
xmacro(_NET_WM_NAME) |
| 36 |
xmacro(_NET_WM_STATE_FULLSCREEN) |
| 37 |
+xmacro(_NET_WM_STATE_DEMANDS_ATTENTION) |
| 38 |
xmacro(_NET_WM_STATE) |
| 39 |
xmacro(_NET_WM_WINDOW_TYPE) |
| 40 |
xmacro(_NET_WM_WINDOW_TYPE_DOCK) |
b/src/handlers.c
| 45 |
@@ -619,10 +619,10 @@ static void handle_client_message(xcb_client_message_event_t *event) {
|
| 46 |
|
| 47 |
LOG("ClientMessage for window 0x%08x\n", event->window);
|
| 48 |
if (event->type == A__NET_WM_STATE) {
|
| 49 |
- if (event->format != 32 || event->data.data32[1] != A__NET_WM_STATE_FULLSCREEN) {
|
| 50 |
- DLOG("atom in clientmessage is %d, fullscreen is %d\n",
|
| 51 |
- event->data.data32[1], A__NET_WM_STATE_FULLSCREEN); |
| 52 |
- DLOG("not about fullscreen atom\n");
|
| 53 |
+ if (event->format != 32 || |
| 54 |
+ (event->data.data32[1] != A__NET_WM_STATE_FULLSCREEN && |
| 55 |
+ event->data.data32[1] != A__NET_WM_STATE_DEMANDS_ATTENTION)) {
|
| 56 |
+ DLOG("Unknown atom in clientmessage of type %d\n", event->data.data32[1]);
|
| 57 |
return; |
| 58 |
} |
| 59 |
|
| 60 |
@@ -632,15 +632,52 @@ static void handle_client_message(xcb_client_message_event_t *event) {
|
| 61 |
return; |
| 62 |
} |
| 63 |
|
| 64 |
- /* Check if the fullscreen state should be toggled */ |
| 65 |
- if ((con->fullscreen_mode != CF_NONE && |
| 66 |
- (event->data.data32[0] == _NET_WM_STATE_REMOVE || |
| 67 |
- event->data.data32[0] == _NET_WM_STATE_TOGGLE)) || |
| 68 |
- (con->fullscreen_mode == CF_NONE && |
| 69 |
- (event->data.data32[0] == _NET_WM_STATE_ADD || |
| 70 |
- event->data.data32[0] == _NET_WM_STATE_TOGGLE))) {
|
| 71 |
- DLOG("toggling fullscreen\n");
|
| 72 |
- con_toggle_fullscreen(con, CF_OUTPUT); |
| 73 |
+ if (event->data.data32[1] == A__NET_WM_STATE_FULLSCREEN) {
|
| 74 |
+ /* Check if the fullscreen state should be toggled */ |
| 75 |
+ if ((con->fullscreen_mode != CF_NONE && |
| 76 |
+ (event->data.data32[0] == _NET_WM_STATE_REMOVE || |
| 77 |
+ event->data.data32[0] == _NET_WM_STATE_TOGGLE)) || |
| 78 |
+ (con->fullscreen_mode == CF_NONE && |
| 79 |
+ (event->data.data32[0] == _NET_WM_STATE_ADD || |
| 80 |
+ event->data.data32[0] == _NET_WM_STATE_TOGGLE))) {
|
| 81 |
+ DLOG("toggling fullscreen\n");
|
| 82 |
+ con_toggle_fullscreen(con, CF_OUTPUT); |
| 83 |
+ } |
| 84 |
+ } else if (event->data.data32[1] == A__NET_WM_STATE_DEMANDS_ATTENTION) {
|
| 85 |
+ bool urgent; |
| 86 |
+ |
| 87 |
+ /* Check if the urgent flag must be set */ |
| 88 |
+ if (event->data.data32[0] == _NET_WM_STATE_ADD) |
| 89 |
+ urgent = true; |
| 90 |
+ else if (event->data.data32[0] == _NET_WM_STATE_REMOVE) |
| 91 |
+ urgent = false; |
| 92 |
+ else if (event->data.data32[0] == _NET_WM_STATE_TOGGLE) |
| 93 |
+ urgent = !con->urgent; |
| 94 |
+ |
| 95 |
+ if (con->urgency_timer == NULL) {
|
| 96 |
+ con->urgent = urgent; |
| 97 |
+ } else |
| 98 |
+ DLOG("Discarding urgency WM_HINT because timer is running\n");
|
| 99 |
+ |
| 100 |
+ //CLIENT_LOG(con); |
| 101 |
+ if (con->window) {
|
| 102 |
+ if (con->urgent) {
|
| 103 |
+ gettimeofday(&con->window->urgent, NULL); |
| 104 |
+ } else {
|
| 105 |
+ con->window->urgent.tv_sec = 0; |
| 106 |
+ con->window->urgent.tv_usec = 0; |
| 107 |
+ } |
| 108 |
+ } |
| 109 |
+ |
| 110 |
+ con_update_parents_urgency(con); |
| 111 |
+ |
| 112 |
+ LOG("Urgency flag changed to %d\n", con->urgent);
|
| 113 |
+ |
| 114 |
+ Con *ws; |
| 115 |
+ /* Set the urgency flag on the workspace, if a workspace could be found |
| 116 |
+ * (for dock clients, that is not the case). */ |
| 117 |
+ if ((ws = con_get_workspace(con)) != NULL) |
| 118 |
+ workspace_update_urgent_flag(ws); |
| 119 |
} |
| 120 |
|
| 121 |
tree_render(); |
| 122 |
@@ -1094,7 +1131,7 @@ void handle_event(int type, xcb_generic_event_t *event) {
|
| 123 |
|
| 124 |
/* Client message are sent to the root window. The only interesting |
| 125 |
* client message for us is _NET_WM_STATE, we honour |
| 126 |
- * _NET_WM_STATE_FULLSCREEN */ |
| 127 |
+ * _NET_WM_STATE_FULLSCREEN and _NET_WM_STATE_DEMANDS_ATTENTION */ |
| 128 |
case XCB_CLIENT_MESSAGE: |
| 129 |
handle_client_message((xcb_client_message_event_t*)event); |
| 130 |
break; |