]> git.sur5r.net Git - i3/i3/commitdiff
mark parents of urgent container also as urgent
authorSascha Kruse <knopwob@googlemail.com>
Mon, 3 Sep 2012 14:05:44 +0000 (16:05 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Sat, 22 Sep 2012 17:31:34 +0000 (19:31 +0200)
include/con.h
src/con.c
src/handlers.c

index f741dee0c18885f5b58f7612fa945d91251cdf4d..7436b2d9936739c6fd590f8a8df2bd33352af04b 100644 (file)
@@ -293,4 +293,17 @@ Rect con_minimum_size(Con *con);
  */
 bool con_fullscreen_permits_focusing(Con *con);
 
+/**
+ * Checks if the given container has an urgent child.
+ *
+ */
+bool con_has_urgent_child(Con *con);
+
+/**
+ * Make all parent containers urgent if con is urgent or clear the urgent flag
+ * of all parent containers if there are no more urgent children left.
+ *
+ */
+void con_update_parents_urgency(Con *con);
+
 #endif
index f5ccfcddbed5b541566c12e80eb59cb7bfa9c404..c966daf9df62b0d9dad6aa9229413a5f0f69261f 100644 (file)
--- a/src/con.c
+++ b/src/con.c
@@ -195,8 +195,14 @@ void con_focus(Con *con) {
         con_focus(con->parent);
 
     focused = con;
-    if (con->urgent) {
+    /* We can't blindly reset non-leaf containers since they might have
+     * other urgent children. Therefore we only reset leafs and propagate
+     * the changes upwards via con_update_parents_urgency() which does proper
+     * checks before resetting the urgency.
+     */
+    if (con->urgent && con_is_leaf(con)) {
         con->urgent = false;
+        con_update_parents_urgency(con);
         workspace_update_urgent_flag(con_get_workspace(con));
     }
 }
@@ -1371,3 +1377,46 @@ bool con_fullscreen_permits_focusing(Con *con) {
     /* Focusing con would hide it behind a fullscreen window, disallow it. */
     return false;
 }
+
+/*
+ *
+ * Checks if the given container has an urgent child.
+ *
+ */
+bool con_has_urgent_child(Con *con) {
+    Con *child;
+
+    if (con_is_leaf(con))
+        return con->urgent;
+
+    /* We are not interested in floating windows since they can only be
+     * attached to a workspace → nodes_head instead of focus_head */
+    TAILQ_FOREACH(child, &(con->nodes_head), nodes) {
+        if (con_has_urgent_child(child))
+            return true;
+    }
+
+    return false;
+}
+
+/*
+ * Make all parent containers urgent if con is urgent or clear the urgent flag
+ * of all parent containers if there are no more urgent children left.
+ *
+ */
+void con_update_parents_urgency(Con *con) {
+    Con *parent = con->parent;
+
+    bool new_urgency_value = con->urgent;
+    while (parent->type != CT_WORKSPACE && parent->type != CT_DOCKAREA) {
+        if (new_urgency_value) {
+            parent->urgent = true;
+        } else {
+            /* We can only reset the urgency when the parent
+             * has no other urgent children */
+            if (!con_has_urgent_child(parent))
+                parent->urgent = false;
+        }
+        parent = parent->parent;
+    }
+}
index f9099cc147dca70663a371efaffb2ec58004bdfd..7fa29e126f0944cfdf0d821c7975bc05c0a4c2fe 100644 (file)
@@ -852,6 +852,9 @@ static bool handle_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_
             con->window->urgent.tv_usec = 0;
         }
     }
+
+    con_update_parents_urgency(con);
+
     LOG("Urgency flag changed to %d\n", con->urgent);
 
     Con *ws;