From 711b11c92f3d304fb21c77b882adac45d90528e1 Mon Sep 17 00:00:00 2001 From: Benedikt Heine Date: Sun, 18 Nov 2018 21:36:27 +0100 Subject: [PATCH] Merge queue_update and queue_check_timeouts --- src/dunst.c | 1 - src/queues.c | 114 +++++++++++++++++++++++++------------------------- src/queues.h | 7 ---- test/queues.c | 25 ++++++++--- 4 files changed, 76 insertions(+), 71 deletions(-) diff --git a/src/dunst.c b/src/dunst.c index 6f901c0..5dce077 100644 --- a/src/dunst.c +++ b/src/dunst.c @@ -68,7 +68,6 @@ static gboolean run(void *data) dunst_status(S_FULLSCREEN, have_fullscreen_window()); dunst_status(S_IDLE, x_is_idle()); - queues_check_timeouts(status); queues_update(status); static gint64 next_timeout = 0; diff --git a/src/queues.c b/src/queues.c index 8e03b63..09303cd 100644 --- a/src/queues.c +++ b/src/queues.c @@ -113,6 +113,8 @@ static void queues_swap_notifications(GQueue *queueA, */ static bool queues_notification_is_ready(const struct notification *n, struct dunst_status status, bool shown) { + if (!status.running) + return false; if (status.fullscreen && shown) return n && n->fullscreen != FS_PUSHBACK; else if (status.fullscreen && !shown) @@ -121,6 +123,38 @@ static bool queues_notification_is_ready(const struct notification *n, struct du return true; } +/** + * Check if a notification has timed out + * + * @param n the notification to check + * @param status the current status of dunst + * @returns true, if the notification is timed out, otherwise false + */ +static bool queues_notification_is_finished(struct notification *n, struct dunst_status status) +{ + assert(n); + + if (n->timeout == 0) // sticky + return false; + if (n->start == 0) // hidden // TODO: is this really the implication of hidden? + return false; + + bool is_idle = status.fullscreen ? false : status.idle; + + /* don't timeout when user is idle */ + if (is_idle && !n->transient) { + n->start = time_monotonic_now(); + return false; + } + + /* remove old message */ + if (time_monotonic_now() - n->start > n->timeout) { + return true; + } + + return false; +} + /* see queues.h */ int queues_notification_insert(struct notification *n) { @@ -342,69 +376,33 @@ void queues_history_push_all(void) } } -/* see queues.h */ -void queues_check_timeouts(struct dunst_status status) -{ - /* nothing to do */ - if (displayed->length == 0) - return; - - bool is_idle = status.fullscreen ? false : status.idle; - - GList *iter = g_queue_peek_head_link(displayed); - while (iter) { - struct notification *n = iter->data; - - /* - * Update iter to the next item before we either exit the - * current iteration of the loop or potentially delete the - * notification which would invalidate the pointer. - */ - iter = iter->next; - - /* don't timeout when user is idle */ - if (is_idle && !n->transient) { - n->start = time_monotonic_now(); - continue; - } - - /* skip hidden and sticky messages */ - if (n->start == 0 || n->timeout == 0) { - continue; - } - - /* remove old message */ - if (time_monotonic_now() - n->start > n->timeout) { - queues_notification_close(n, REASON_TIME); - } - } -} - /* see queues.h */ void queues_update(struct dunst_status status) { - if (!status.running) { - while (displayed->length > 0) { - g_queue_insert_sorted( - waiting, g_queue_pop_head(displayed), notification_cmp_data, NULL); - } - return; - } + GList *iter, *nextiter; - /* move notifications back to queue, which are set to pushback */ - if (status.fullscreen) { - GList *iter = g_queue_peek_head_link(displayed); - while (iter) { - struct notification *n = iter->data; - GList *nextiter = iter->next; - - if (n->fullscreen == FS_PUSHBACK){ - g_queue_delete_link(displayed, iter); - g_queue_insert_sorted(waiting, n, notification_cmp_data, NULL); - } + /* Move back all notifications, which aren't eligible to get shown anymore + * Will move the notifications back to waiting, if dunst isn't running or fullscreen + * and notifications is not eligible to get shown anymore */ + iter = g_queue_peek_head_link(displayed); + while (iter) { + struct notification *n = iter->data; + nextiter = iter->next; + if (queues_notification_is_finished(n, status)){ + queues_notification_close(n, REASON_TIME); iter = nextiter; + continue; } + + if (!queues_notification_is_ready(n, status, true)) { + g_queue_delete_link(displayed, iter); + g_queue_insert_sorted(waiting, n, notification_cmp_data, NULL); + iter = nextiter; + continue; + } + + iter = nextiter; } int cur_displayed_limit; @@ -418,10 +416,10 @@ void queues_update(struct dunst_status status) cur_displayed_limit = settings.geometry.h; /* move notifications from queue to displayed */ - GList *iter = g_queue_peek_head_link(waiting); + iter = g_queue_peek_head_link(waiting); while (displayed->length < cur_displayed_limit && iter) { struct notification *n = iter->data; - GList *nextiter = iter->next; + nextiter = iter->next; if (!n) return; diff --git a/src/queues.h b/src/queues.h index a74e30b..92d5156 100644 --- a/src/queues.h +++ b/src/queues.h @@ -118,13 +118,6 @@ void queues_history_push(struct notification *n); */ void queues_history_push_all(void); -/** - * Check timeout of each notification and close it, if necessary - * - * @param status the current status of dunst - */ -void queues_check_timeouts(struct dunst_status status); - /** * Move inserted notifications from waiting queue to displayed queue * and show them. In displayed queue, the amount of elements is limited diff --git a/test/queues.c b/test/queues.c index 6e5bfb4..de69578 100644 --- a/test/queues.c +++ b/test/queues.c @@ -430,9 +430,6 @@ TEST test_queue_timeout(void) queues_init(); - // Usually this shouldn't do anything, but we may abort ;-) - queues_check_timeouts(STATUS_NORMAL); - n1 = test_notification("n1", 0); n2 = test_notification("n2", 10); n3 = test_notification("n3", 10); @@ -448,7 +445,6 @@ TEST test_queue_timeout(void) n1->start -= S2US(11); n2->start -= S2US(11); n3->start -= S2US(11); - queues_check_timeouts(STATUS_IDLE); queues_update(STATUS_IDLE); QUEUE_LEN_ALL(0,2,1); @@ -457,7 +453,6 @@ TEST test_queue_timeout(void) // hacky way to shift time n1->start -= S2US(11); n2->start -= S2US(11); - queues_check_timeouts(STATUS_NORMAL); queues_update(STATUS_NORMAL); QUEUE_LEN_ALL(0,1,2); @@ -665,6 +660,25 @@ TEST test_queues_update_seep_showlowurg(void) PASS(); } +TEST test_queues_timeout_before_paused(void) +{ + struct notification *n; + queues_init(); + + n = test_notification("n", 10); + + queues_notification_insert(n); + queues_update(STATUS_NORMAL); + + n->start -= S2US(11); + queues_update(STATUS_PAUSE); + + QUEUE_LEN_ALL(0,0,1); + + queues_teardown(); + PASS(); +} + SUITE(suite_queues) { RUN_TEST(test_datachange_beginning_empty); @@ -690,6 +704,7 @@ SUITE(suite_queues) RUN_TEST(test_queues_update_seep_showlowurg); RUN_TEST(test_queues_update_seeping); RUN_TEST(test_queues_update_xmore); + RUN_TEST(test_queues_timeout_before_paused); } /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */