diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b94516..71f89c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ ### Added - `fullscreen` rule to hide notifications when a fullscreen window is active +- When new notifications arrive, but display is full, important notifications don't + have to wait for a timeout in a displayed notification (#541) ## 1.3.2 - 2018-05-06 diff --git a/src/queues.c b/src/queues.c index 017a4f4..600a3e7 100644 --- a/src/queues.c +++ b/src/queues.c @@ -258,7 +258,7 @@ void queues_history_pop(void) n->redisplayed = true; n->start = 0; n->timeout = settings.sticky_history ? 0 : n->timeout; - g_queue_push_head(waiting, n); + g_queue_insert_sorted(waiting, n, notification_cmp_data, NULL); } /* see queues.h */ @@ -381,6 +381,40 @@ void queues_update(bool fullscreen) iter = nextiter; } + + /* If displayed is actually full, let the more important notifications + * from waiting seep into displayed. + */ + if (settings.sort) { + GList *i_waiting, *i_displayed; + + while ( (i_waiting = g_queue_peek_head_link(waiting)) + && (i_displayed = g_queue_peek_tail_link(displayed))) { + + while ( fullscreen + && i_waiting + && i_waiting->data + && ((notification*) i_waiting->data)->fullscreen != FS_SHOW) { + i_waiting = i_waiting->prev; + } + + if (i_waiting && notification_cmp(i_displayed->data, i_waiting->data) > 0) { + notification *towait = i_displayed->data; + notification *todisp = i_waiting->data; + + g_queue_delete_link(displayed, i_displayed); + g_queue_delete_link(waiting, i_waiting); + + todisp->start = time_monotonic_now(); + notification_run_script(todisp); + + g_queue_insert_sorted(displayed, todisp, notification_cmp_data, NULL); + g_queue_insert_sorted(waiting, towait, notification_cmp_data, NULL); + } else { + break; + } + } + } } /* see queues.h */