From 1533fcd7827510d66d2c06dfa7791a3211643b0c Mon Sep 17 00:00:00 2001 From: Benedikt Heine Date: Wed, 27 Sep 2017 00:17:57 +0200 Subject: [PATCH] Replace notifications flickerless Previously, notifications had been replaced by removing the notification out of the displayed/queue lists, redrawing the window and then adding the new notification into the queue. This produced a flickering in dunst. By avoiding the overhead of closing and opening the window (simply replacing the datapointer of the list), the flickering disappears. --- src/notification.c | 39 +++++++++++++++++++++++++++++++++++++-- src/notification.h | 1 + 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/notification.c b/src/notification.c index 68bf2eb..18be083 100644 --- a/src/notification.c +++ b/src/notification.c @@ -428,7 +428,6 @@ int notification_init(notification *n, int id) if (id == 0) { n->id = ++next_notification_id; } else { - notification_close_by_id(id, -1); n->id = id; } @@ -516,7 +515,8 @@ int notification_init(notification *n, int id) } printf("skipping notification: %s %s\n", n->body, n->summary); } else { - g_queue_insert_sorted(queue, n, notification_cmp_data, NULL); + if (id == 0 || !notification_replace_by_id(n)) + g_queue_insert_sorted(queue, n, notification_cmp_data, NULL); } char *tmp = g_strconcat(n->summary, " ", n->body, NULL); @@ -606,6 +606,41 @@ int notification_close(notification *n, int reason) return notification_close_by_id(n->id, reason); } +/* + * Replace the notification which matches the id field of + * the new notification. The given notification is inserted + * right in the same position as the old notification. + * + * Returns true, if a matching notification has been found + * and is replaced. Else false. + */ +bool notification_replace_by_id(notification *new) +{ + + for (GList *iter = g_queue_peek_head_link(displayed); + iter; + iter = iter->next) { + notification *old = iter->data; + if (old->id == new->id) { + iter->data = new; + history_push(old); + return true; + } + } + + for (GList *iter = g_queue_peek_head_link(queue); + iter; + iter = iter->next) { + notification *old = iter->data; + if (old->id == new->id) { + iter->data = new; + history_push(old); + return true; + } + } + return false; +} + void notification_update_text_to_render(notification *n) { if (n->text_to_render) { diff --git a/src/notification.h b/src/notification.h index c0efef4..408dad4 100644 --- a/src/notification.h +++ b/src/notification.h @@ -67,6 +67,7 @@ notification *notification_create(void); int notification_init(notification *n, int id); void notification_free(notification *n); int notification_close_by_id(int id, int reason); +bool notification_replace_by_id(notification *n); int notification_cmp(const void *a, const void *b); int notification_cmp_data(const void *a, const void *b, void *data); int notification_is_duplicate(const notification *a, const notification *b);