From 958aa2bc9658940c0f747049d91546e0832ff54a Mon Sep 17 00:00:00 2001 From: Benedikt Heine Date: Fri, 6 Jul 2018 20:47:42 +0200 Subject: [PATCH] Lock notifications while executing dmenu When executing dmenu, the current notifications get "locked", by setting their timeout temporarily to 0 and referencing them. So the notification won't get closed (exept forcefully) and won't get freed while dmenu is opened. This is currently pointless, but as the dmenu call will become threaded, it's necessary later. --- src/menu.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/menu.c b/src/menu.c index d724cdd..33a4a93 100644 --- a/src/menu.c +++ b/src/menu.c @@ -23,6 +23,11 @@ static bool is_initialized = false; static regex_t cregex; +struct notification_lock { + struct notification *n; + gint64 timeout; +}; + static int regex_init(void) { if (is_initialized) @@ -199,10 +204,27 @@ void context_menu(void) } char *dmenu_input = NULL; + GList *locked_notifications = NULL; + for (const GList *iter = queues_get_displayed(); iter; iter = iter->next) { struct notification *n = iter->data; + + // Reference and lock the notification if we need it + if (n->urls || n->actions) { + notification_ref(n); + + struct notification_lock *nl = + g_malloc(sizeof(struct notification_lock)); + + nl->n = n; + nl->timeout = n->timeout; + n->timeout = 0; + + locked_notifications = g_list_prepend(locked_notifications, nl); + } + if (n->urls) dmenu_input = string_append(dmenu_input, n->urls, "\n"); @@ -272,5 +294,20 @@ void context_menu(void) dispatch_menu_result(buf); g_free(dmenu_input); + + // unref all notifications + for (GList *iter = locked_notifications; + iter; + iter = iter->next) { + + struct notification_lock *nl = iter->data; + struct notification *n = nl->n; + + n->timeout = nl->timeout; + + g_free(nl); + notification_unref(n); + } + g_list_free(locked_notifications); } /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */