From d8a036d776d9df091c0e9f3388639513b11119d6 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Mon, 3 Sep 2012 16:05:44 +0200 Subject: [PATCH] mark parents of urgent container also as urgent --- include/con.h | 13 +++++++++++++ src/con.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++- src/handlers.c | 3 +++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/include/con.h b/include/con.h index f741dee0..7436b2d9 100644 --- a/include/con.h +++ b/include/con.h @@ -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 diff --git a/src/con.c b/src/con.c index f5ccfcdd..c966daf9 100644 --- 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; + } +} diff --git a/src/handlers.c b/src/handlers.c index f9099cc1..7fa29e12 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -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; -- 2.39.5