[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] set urgent flag on _NET_WM_STATE_DEMANDS_ATTENTION and clear it on window focus



---
 NEWS             |  2 ++
 src/clientlist.c | 41 ++++++++++++++++++++++++++++++-----------
 src/clientlist.h |  2 +-
 src/ewmh.c       |  4 ++++
 src/ewmh.h       |  1 +
 5 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/NEWS b/NEWS
index 4dc1ea5..fa82ad4 100644
--- a/NEWS
+++ b/NEWS
@@ -11,6 +11,8 @@ Changes:
       "current" or a certain monitor index
     * align captions of the tree output (commands: layout, stack) better by
       inserting a space in front of every caption
+    * set the urgent flag on _NET_WM_STATE_DEMANDS_ATTENTION
+    * clear the urgent flag on window focus
 
 Release: 0.4.1 on 2012-08-30
 ----------------------------
diff --git a/src/clientlist.c b/src/clientlist.c
index c88da2d..94ac869 100644
--- a/src/clientlist.c
+++ b/src/clientlist.c
@@ -319,6 +319,7 @@ void window_focus(Window window) {
     }
     tag_update_focus_layer(get_current_monitor()->tag);
     grab_client_buttons(get_client_from_window(window), true);
+    client_set_urgent(client, false);
 }
 
 void client_setup_border(HSClient* client, bool focused) {
@@ -537,21 +538,39 @@ void window_hide(Window win) {
 }
 
 // heavily inspired by dwm.c
-void client_clear_urgent(HSClient* client) {
-    if (client->urgent) {
-        char winid_str[STRING_BUF_SIZE];
-        snprintf(winid_str, STRING_BUF_SIZE, "0x%lx", client->window);
+void client_set_urgent(HSClient* client, bool state) {
+    if (client->urgent == state) {
+        // nothing to do
+        return;
+    }
+
+    char winid_str[STRING_BUF_SIZE];
+    snprintf(winid_str, STRING_BUF_SIZE, "0x%lx", client->window);
+
+    if (state) {
+        hook_emit_list("urgent", "on", winid_str, NULL);
+        client->urgent = true;
+    } else {
         hook_emit_list("urgent", "off", winid_str, NULL);
         client->urgent = false;
-        XWMHints *wmh;
-        if(!(wmh = XGetWMHints(g_display, client->window)))
-            return;
+    }
+
+    client_setup_border(client, client->window == frame_focused_window(g_cur_frame));
+
+    XWMHints *wmh;
+    if(!(wmh = XGetWMHints(g_display, client->window)))
+        return;
+
+    if (state) {
+        wmh->flags |= XUrgencyHint;
+    } else {
         wmh->flags &= ~XUrgencyHint;
-        XSetWMHints(g_display, client->window, wmh);
-        XFree(wmh);
-        // report changes to tags
-        tag_set_flags_dirty();
     }
+
+    XSetWMHints(g_display, client->window, wmh);
+    XFree(wmh);
+    // report changes to tags
+    tag_set_flags_dirty();
 }
 
 // heavily inspired by dwm.c
diff --git a/src/clientlist.h b/src/clientlist.h
index e146fcd..27c00b8 100644
--- a/src/clientlist.h
+++ b/src/clientlist.h
@@ -65,7 +65,7 @@ void client_setup_border(HSClient* client, bool focused);
 void client_resize(HSClient* client, XRectangle rect, HSFrame* frame);
 void client_resize_tiling(HSClient* client, XRectangle rect, HSFrame* frame);
 void client_resize_floating(HSClient* client, HSMonitor* m);
-void client_clear_urgent(HSClient* client);
+void client_set_urgent(HSClient* client, bool state);
 void client_update_wm_hints(HSClient* client);
 void client_update_title(HSClient* client);
 void client_raise(HSClient* client);
diff --git a/src/ewmh.c b/src/ewmh.c
index 26a0dc8..f9df8b6 100644
--- a/src/ewmh.c
+++ b/src/ewmh.c
@@ -46,6 +46,7 @@ char* g_netatom_names[NetCOUNT] = {
     [ NetWmState                    ] = "_NET_WM_STATE"                     ,
     [ NetWmWindowOpacity            ] = "_NET_WM_WINDOW_OPACITY"            ,
     [ NetWmStateFullscreen          ] = "_NET_WM_STATE_FULLSCREEN"          ,
+    [ NetWmStateDemandsAttention    ] = "_NET_WM_STATE_DEMANDS_ATTENTION"   ,
     [ NetSupportingWmCheck          ] = "_NET_SUPPORTING_WM_CHECK"          ,
     [ NetWmWindowTypeDesktop        ] = "_NET_WM_WINDOW_TYPE_DESKTOP"       ,
     [ NetWmWindowTypeDock           ] = "_NET_WM_WINDOW_TYPE_DOCK"          ,
@@ -312,6 +313,8 @@ void ewmh_handle_client_message(XEvent* event) {
             } client_atoms[] = {
                 { NetWmStateFullscreen,
                     client->fullscreen,     client_set_fullscreen },
+                { NetWmStateDemandsAttention,
+                    client->urgent,         client_set_urgent },
             };
 
             /* me->data.l[1] and [2] describe the properties to alter */
@@ -360,6 +363,7 @@ void ewmh_update_window_state(struct HSClient* client) {
         bool    enabled;
     } client_atoms[] = {
         { NetWmStateFullscreen,         client->fullscreen      },
+        { NetWmStateDemandsAttention,   client->urgent          },
     };
 
     /* find out which flags are set */
diff --git a/src/ewmh.h b/src/ewmh.h
index 1e6e29c..6c53c15 100644
--- a/src/ewmh.h
+++ b/src/ewmh.h
@@ -36,6 +36,7 @@ enum {
     NetWmWindowOpacity,
     /* window states */
     NetWmStateFullscreen,
+    NetWmStateDemandsAttention,
     /* window types */
     ENUM_WITH_ALIAS(NetWmWindowTypeDesktop, NetWmWindowTypeFIRST),
     NetWmWindowTypeDock,
-- 
1.7.12