diff --git a/CHANGELOG.md b/CHANGELOG.md index ba5abbacc..950934c34 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ have to wait for a timeout in a displayed notification (#541) - ` more` notifications don't occupy space anymore, if there is only a single notification waiting to get displayed. The notification gets displayed directly (#467) +- Added `skip_display` rule option to skip initial notification display, and + include the notification in the history. ## 1.3.2 - 2018-05-06 diff --git a/config.h b/config.h index 1a996c37a..7026d3859 100644 --- a/config.h +++ b/config.h @@ -129,6 +129,7 @@ struct rule default_rules[] = { .history_ignore = -1, .match_transient = -1, .set_transient = -1, + .skip_display = -1, .new_icon = NULL, .fg = NULL, .bg = NULL, diff --git a/docs/dunst.pod b/docs/dunst.pod index 135ac5525..1cc6d8e57 100644 --- a/docs/dunst.pod +++ b/docs/dunst.pod @@ -690,9 +690,9 @@ together. The default stack_stag value is set from the string hints "synchronous", "private-synchronous", "x-canonical-private-synchronous", and "x-dunst-stack-tag". -If you want to skip display of a notification, but still have it in -history, setting 'timeout' to "1ms" will essentially skip initial -display. +If you want to skip initial display of a notification, but still have +it in history, you can set 'skip_display' to 'true' to get this +behavior. =back diff --git a/dunstrc b/dunstrc index 8da67c302..8231e33aa 100644 --- a/dunstrc +++ b/dunstrc @@ -368,6 +368,11 @@ # summary = "foobar" # history_ignore = yes +#[skip-display] +# # This notification will not be displayed, but will be included in the history +# summary = "foobar" +# skip_display = yes + #[signed_on] # appname = Pidgin # summary = "*signed on*" diff --git a/src/dbus.c b/src/dbus.c index e4f098e66..64be60759 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -320,7 +320,7 @@ static void dbus_cb_Notify( // The message got discarded if (id == 0) { - signal_notification_closed(n, 2); + signal_notification_closed(n, REASON_USER); notification_unref(n); } diff --git a/src/notification.h b/src/notification.h index ad63d0b82..10b76adf5 100644 --- a/src/notification.h +++ b/src/notification.h @@ -71,6 +71,7 @@ struct notification { bool transient; /**< timeout albeit user is idle */ int progress; /**< percentage (-1: undefined) */ int history_ignore; /**< push to history or free directly */ + int skip_display; /**< insert notification into history, skipping initial waiting and display */ /* internal */ bool redisplayed; /**< has been displayed before? */ diff --git a/src/queues.c b/src/queues.c index dcbb4e0bf..029022619 100644 --- a/src/queues.c +++ b/src/queues.c @@ -133,6 +133,9 @@ static bool queues_notification_is_finished(struct notification *n, struct dunst { assert(n); + if (n->skip_display && !n->redisplayed) + return true; + if (n->timeout == 0) // sticky return false; @@ -427,8 +430,12 @@ void queues_update(struct dunst_status status) n->start = time_monotonic_now(); notification_run_script(n); - g_queue_delete_link(waiting, iter); - g_queue_insert_sorted(displayed, n, notification_cmp_data, NULL); + if (n->skip_display && !n->redisplayed) { + queues_notification_close(n, REASON_USER); + } else { + g_queue_delete_link(waiting, iter); + g_queue_insert_sorted(displayed, n, notification_cmp_data, NULL); + } iter = nextiter; } diff --git a/src/rules.c b/src/rules.c index 10b099571..70a15f041 100644 --- a/src/rules.c +++ b/src/rules.c @@ -24,6 +24,8 @@ void rule_apply(struct rule *r, struct notification *n) n->history_ignore = r->history_ignore; if (r->set_transient != -1) n->transient = r->set_transient; + if (r->skip_display != -1) + n->skip_display = r->skip_display; if (r->markup != MARKUP_NULL) n->markup = r->markup; if (r->new_icon) @@ -75,6 +77,7 @@ struct rule *rule_new(void) r->history_ignore = false; r->match_transient = -1; r->set_transient = -1; + r->skip_display = -1; return r; } diff --git a/src/rules.h b/src/rules.h index 69e63a11c..6b2d7b290 100644 --- a/src/rules.h +++ b/src/rules.h @@ -27,6 +27,7 @@ struct rule { int history_ignore; int match_transient; int set_transient; + int skip_display; char *new_icon; char *fg; char *bg; diff --git a/src/settings.c b/src/settings.c index 9245b5f9f..46187e2a4 100644 --- a/src/settings.c +++ b/src/settings.c @@ -725,6 +725,7 @@ void load_settings(char *cmdline_config_path) r->match_transient = ini_get_bool(cur_section, "match_transient", r->match_transient); r->set_transient = ini_get_bool(cur_section, "set_transient", r->set_transient); r->desktop_entry = ini_get_string(cur_section, "desktop_entry", r->desktop_entry); + r->skip_display = ini_get_bool(cur_section, "skip_display", r->skip_display); { char *c = ini_get_string( cur_section, diff --git a/test/queues.c b/test/queues.c index 67e76510c..f60049b87 100644 --- a/test/queues.c +++ b/test/queues.c @@ -190,6 +190,50 @@ TEST test_queue_notification_close_histignore(void) PASS(); } +TEST test_queue_notification_skip_display(void) +{ + struct notification *n; + + // Test skipping display + n = test_notification("n", -1); + n->skip_display = true; + + queues_init(); + queues_notification_insert(n); + QUEUE_LEN_ALL(1, 0, 0); + queues_update(STATUS_NORMAL); + QUEUE_LEN_ALL(0, 0, 1); + queues_teardown(); + + PASS(); +} + +TEST test_queue_notification_skip_display_redisplayed(void) +{ + struct notification *n; + + // Test skipping display + n = test_notification("n", -1); + n->skip_display = true; + + queues_init(); + queues_notification_insert(n); + QUEUE_LEN_ALL(1, 0, 0); + queues_update(STATUS_NORMAL); + QUEUE_LEN_ALL(0, 0, 1); + + queues_history_pop(); + QUEUE_LEN_ALL(1, 0, 0); + queues_update(STATUS_NORMAL); + QUEUE_CONTAINSm("A skip display notification should stay in displayed " + "queue when it got pulled out of history queue", + DISP, n); + + queues_teardown(); + + PASS(); +} + TEST test_queue_history_overfull(void) { settings.history_length = 10; @@ -714,6 +758,8 @@ SUITE(suite_queues) RUN_TEST(test_queue_length); RUN_TEST(test_queue_notification_close); RUN_TEST(test_queue_notification_close_histignore); + RUN_TEST(test_queue_notification_skip_display); + RUN_TEST(test_queue_notification_skip_display_redisplayed); RUN_TEST(test_queue_stacking); RUN_TEST(test_queue_stacktag); RUN_TEST(test_queue_teardown);