From 585f0f85e0901c71b5a073fb1613793856193e76 Mon Sep 17 00:00:00 2001 From: Benedikt Heine Date: Sun, 23 Jul 2017 03:42:17 +0200 Subject: [PATCH 1/5] Add support for transistent hints --- CHANGELOG.md | 3 +++ docs/dunst.pod | 2 ++ dunstrc | 1 + src/dbus.c | 15 +++++++++++++++ src/dunst.c | 2 +- src/notification.c | 1 + src/notification.h | 1 + 7 files changed, 24 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb97a72..737f387 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ ### Fixed - `new_icon` rule being ignored on notifications that had a raw icon +## Changed +- transient hints are now handled + ## 1.2.0 - 2017-07-12 ### Added diff --git a/docs/dunst.pod b/docs/dunst.pod index ee53aeb..b91df5e 100644 --- a/docs/dunst.pod +++ b/docs/dunst.pod @@ -234,6 +234,8 @@ Don't timeout notifications if user is idle longer than this value (in seconds). Set to 0 to disable. +Transient notifications will ignore this setting and timeout anyway. + =item B (default: "Monospace 8") Defines the font or font set used. Optionally set the size as a decimal number diff --git a/dunstrc b/dunstrc index 6faedc4..3b2857f 100644 --- a/dunstrc +++ b/dunstrc @@ -80,6 +80,7 @@ # Don't remove messages, if the user is idle (no mouse or keyboard input) # for longer than idle_threshold seconds. # Set to 0 to disable. + # Transient notifications ignore this setting. idle_threshold = 120 ### Text ### diff --git a/src/dbus.c b/src/dbus.c index 8efb2c0..27acc3c 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -138,6 +138,7 @@ static void on_notify(GDBusConnection * connection, /* hints */ gint urgency = 1; gint progress = -1; + gboolean transient = 0; gchar *fgcolor = NULL; gchar *bgcolor = NULL; gchar *category = NULL; @@ -202,6 +203,19 @@ static void on_notify(GDBusConnection * connection, if (dict_value) raw_icon = get_raw_image_from_data_hint(dict_value); + /* Check for transient hints + * + * According to the spec, the transient hint should be boolean. + * But notify-send does not support hints of type 'boolean'. + * So let's check for int and boolean until notify-send is fixed. + */ + if((dict_value = g_variant_lookup_value(content, "transient", G_VARIANT_TYPE_BOOLEAN))) + transient = g_variant_get_boolean(dict_value); + else if((dict_value = g_variant_lookup_value(content, "transient", G_VARIANT_TYPE_UINT32))) + transient = g_variant_get_uint32(dict_value) > 0; + else if((dict_value = g_variant_lookup_value(content, "transient", G_VARIANT_TYPE_INT32))) + transient = g_variant_get_int32(dict_value) > 0; + dict_value = g_variant_lookup_value(content, "value", G_VARIANT_TYPE_INT32); if (dict_value) { progress = g_variant_get_int32(dict_value); @@ -246,6 +260,7 @@ static void on_notify(GDBusConnection * connection, n->urgency = urgency; n->category = category; n->dbus_client = g_strdup(sender); + n->transient = transient; if (actions->count > 0) { n->actions = actions; } else { diff --git a/src/dunst.c b/src/dunst.c index d2893f9..83ad253 100644 --- a/src/dunst.c +++ b/src/dunst.c @@ -62,7 +62,7 @@ void check_timeouts(void) notification *n = iter->data; /* don't timeout when user is idle */ - if (x_is_idle()) { + if (x_is_idle() && !n->transient) { n->start = time(NULL); continue; } diff --git a/src/notification.c b/src/notification.c index df9e842..9a73958 100644 --- a/src/notification.c +++ b/src/notification.c @@ -41,6 +41,7 @@ void notification_print(notification * n) printf("\tcategory: %s\n", n->category); printf("\ttimeout: %d\n", n->timeout); printf("\turgency: %d\n", n->urgency); + printf("\ttransient: %d\n", n->transient); printf("\tformatted: '%s'\n", n->msg); printf("\tfg: %s\n", n->color_strings[ColFG]); printf("\tbg: %s\n", n->color_strings[ColBG]); diff --git a/src/notification.h b/src/notification.h index df64d08..59fb2cf 100644 --- a/src/notification.h +++ b/src/notification.h @@ -53,6 +53,7 @@ typedef struct _notification { int displayed_height; const char *color_strings[3]; bool first_render; + bool transient; int progress; /* percentage + 1, 0 to hide */ int line_count; From 02ba0604909f842b289f760c9b73a8451a1a8a86 Mon Sep 17 00:00:00 2001 From: Benedikt Heine Date: Thu, 27 Jul 2017 20:34:03 +0200 Subject: [PATCH 2/5] Refactor if chain to avoid nested statements --- src/dbus.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/dbus.c b/src/dbus.c index 27acc3c..4894b83 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -216,14 +216,10 @@ static void on_notify(GDBusConnection * connection, else if((dict_value = g_variant_lookup_value(content, "transient", G_VARIANT_TYPE_INT32))) transient = g_variant_get_int32(dict_value) > 0; - dict_value = g_variant_lookup_value(content, "value", G_VARIANT_TYPE_INT32); - if (dict_value) { + if((dict_value = g_variant_lookup_value(content, "value", G_VARIANT_TYPE_INT32))) progress = g_variant_get_int32(dict_value); - } else { - dict_value = g_variant_lookup_value(content, "value", G_VARIANT_TYPE_UINT32); - if (dict_value) - progress = g_variant_get_uint32(dict_value); - } + else if((dict_value = g_variant_lookup_value(content, "value", G_VARIANT_TYPE_UINT32))) + progress = g_variant_get_uint32(dict_value); } break; case 7: From d4f6726944ba2fdf32f520b7d0e4b765d7dc9bb1 Mon Sep 17 00:00:00 2001 From: Benedikt Heine Date: Wed, 2 Aug 2017 15:00:22 +0200 Subject: [PATCH 3/5] Add rule to ignore transient settings --- config.def.h | 14 +++++++------- src/rules.c | 5 +++++ src/rules.h | 2 ++ src/settings.c | 2 ++ 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/config.def.h b/config.def.h index 9e868e5..bf988e1 100644 --- a/config.def.h +++ b/config.def.h @@ -91,11 +91,11 @@ keyboard_shortcut context_ks = {.str = "none", rule_t default_rules[] = { /* name can be any unique string. It is used to identify the rule in dunstrc to override it there */ - /* name, appname, summary, body, icon, category, msg_urgency, timeout, urgency, markup, history_ignore, new_icon, fg, bg, format, script */ - { "empty", NULL, NULL, NULL, NULL, NULL, -1, -1, -1, MARKUP_NULL, false, NULL, NULL, NULL, NULL, NULL}, - /* { "rule1", "notify-send", NULL, NULL, NULL, NULL, -1, -1, -1, MARKUP_NULL, false, NULL, NULL, NULL, "%s %b", NULL}, */ - /* { "rule2", "Pidgin", "*says*, NULL, NULL, NULL, -1, -1, CRITICAL, MARKUP_NULL, false, NULL, NULL, NULL, NULL, NULL}, */ - /* { "rule3", "Pidgin", "*signed on*", NULL, NULL, NULL, -1, -1, LOW, MARKUP_NULL, false, NULL, NULL, NULL, NULL, NULL}, */ - /* { "rule4", "Pidgin", "*signed off*", NULL, NULL, NULL, -1, -1, LOW, MARKUP_NULL, false, NULL, NULL, NULL, NULL, NULL}, */ - /* { "rule5", NULL, "*foobar*", NULL, NULL, NULL, -1, -1, -1, MARKUP_NULL, false, NULL, NULL, "#00FF00", NULL, NULL}, */ + /* name, appname, summary, body, icon, category, msg_urgency, timeout, urgency, markup, history_ignore, match_transient, set_transient, new_icon, fg, bg, format, script */ + { "empty", NULL, NULL, NULL, NULL, NULL, -1, -1, -1, MARKUP_NULL, -1, -1, -1, NULL, NULL, NULL, NULL, NULL}, + /* { "rule1", "notify-send", NULL, NULL, NULL, NULL, -1, -1, -1, MARKUP_NULL, -1, -1, -1, NULL, NULL, NULL, "%s %b", NULL}, */ + /* { "rule2", "Pidgin", "*says*, NULL, NULL, NULL, -1, -1, CRITICAL, MARKUP_NULL, -1, -1, -1, NULL, NULL, NULL, NULL, NULL}, */ + /* { "rule3", "Pidgin", "*signed on*", NULL, NULL, NULL, -1, -1, LOW, MARKUP_NULL, -1, -1, -1, NULL, NULL, NULL, NULL, NULL}, */ + /* { "rule4", "Pidgin", "*signed off*", NULL, NULL, NULL, -1, -1, LOW, MARKUP_NULL, -1, -1, -1, NULL, NULL, NULL, NULL, NULL}, */ + /* { "rule5", NULL, "*foobar*", NULL, NULL, NULL, -1, -1, -1, MARKUP_NULL, -1, -1, -1, NULL, NULL, "#00FF00", NULL, NULL}, */ }; diff --git a/src/rules.c b/src/rules.c index 6cc6871..32ea038 100644 --- a/src/rules.c +++ b/src/rules.c @@ -18,6 +18,8 @@ void rule_apply(rule_t * r, notification * n) n->urgency = r->urgency; if (r->history_ignore != -1) n->history_ignore = r->history_ignore; + if (r->set_transient != -1) + n->transient = r->set_transient; if (r->markup != MARKUP_NULL) n->markup = r->markup; if (r->new_icon) { @@ -66,6 +68,8 @@ void rule_init(rule_t * r) r->markup = MARKUP_NULL; r->new_icon = NULL; r->history_ignore = false; + r->match_transient = -1; + r->set_transient = -1; r->fg = NULL; r->bg = NULL; r->format = NULL; @@ -81,6 +85,7 @@ bool rule_matches_notification(rule_t * r, notification * n) && (!r->body || !fnmatch(r->body, n->body, 0)) && (!r->icon || !fnmatch(r->icon, n->icon, 0)) && (!r->category || !fnmatch(r->category, n->category, 0)) + && (r->match_transient == -1 || (r->match_transient == n->transient)) && (r->msg_urgency == -1 || r->msg_urgency == n->urgency)); } /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */ diff --git a/src/rules.h b/src/rules.h index b9cbcea..82cb370 100644 --- a/src/rules.h +++ b/src/rules.h @@ -23,6 +23,8 @@ typedef struct _rule_t { int urgency; enum markup_mode markup; int history_ignore; + int match_transient; + int set_transient; char *new_icon; char *fg; char *bg; diff --git a/src/settings.c b/src/settings.c index b53e93a..f27f8db 100644 --- a/src/settings.c +++ b/src/settings.c @@ -636,6 +636,8 @@ void load_settings(char *cmdline_config_path) r->format = ini_get_string(cur_section, "format", r->format); r->new_icon = ini_get_string(cur_section, "new_icon", r->new_icon); r->history_ignore = ini_get_bool(cur_section, "history_ignore", r->history_ignore); + 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->script = ini_get_path(cur_section, "script", NULL); } From 2da6730e5a67709e56e3342cdab42a9435e7c9e0 Mon Sep 17 00:00:00 2001 From: Benedikt Heine Date: Wed, 2 Aug 2017 15:56:10 +0200 Subject: [PATCH 4/5] Add docs for transient rules --- CHANGELOG.md | 2 ++ docs/dunst.pod | 12 +++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 737f387..2264f8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ ## Changed - transient hints are now handled + An additional rule option (`match_transient` and `set_transient`) is added + to optionally reset the transient setting ## 1.2.0 - 2017-07-12 diff --git a/docs/dunst.pod b/docs/dunst.pod index b91df5e..d334ea0 100644 --- a/docs/dunst.pod +++ b/docs/dunst.pod @@ -235,6 +235,7 @@ Don't timeout notifications if user is idle longer than this value (in seconds). Set to 0 to disable. Transient notifications will ignore this setting and timeout anyway. +Use a rule overwriting with 'set_transient = no' to disable this behavior. =item B (default: "Monospace 8") @@ -558,9 +559,10 @@ matched. =item B Notifications can be matched for any of the following attributes: appname, -summary, body, icon, category and msg_urgency where each is the respective -notification attribute to be matched and 'msg_urgency' is the urgency of the -notification, it is named so to not conflict with trying to modify the urgency. +summary, body, icon, category, match_transient and msg_urgency where each is +the respective notification attribute to be matched and 'msg_urgency' is the +urgency of the notification, it is named so to not conflict with trying to +modify the urgency. To define a matching rule simply assign the specified value to the value that should be matched, for example: @@ -576,8 +578,8 @@ Shell-like globing is supported. =item B The following attributes can be overridden: timeout, urgency, foreground, -background, new_icon, format where, as with the filtering attributes, each one -corresponds to the respective notification attribute to be modified. +background, new_icon, set_transient, format where, as with the filtering attributes, +each one corresponds to the respective notification attribute to be modified. As with filtering, to make a rule modify an attribute simply assign it in the rule definition. From 289bab03e4c561a00f17ace377ebbf1491f8ff69 Mon Sep 17 00:00:00 2001 From: Benedikt Heine Date: Mon, 14 Aug 2017 16:14:03 +0200 Subject: [PATCH 5/5] Chain history_ignore and transient together If the transient hint is set on the notification, it should only be valid as long as it shows up. So the pushing it to the history makes no sense. As it's no problem to change this individually by the rule system, it's a sane default for history_ignore to default to the transient option. --- config.def.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config.def.h b/config.def.h index bf988e1..1b9a097 100644 --- a/config.def.h +++ b/config.def.h @@ -93,6 +93,9 @@ rule_t default_rules[] = { /* name, appname, summary, body, icon, category, msg_urgency, timeout, urgency, markup, history_ignore, match_transient, set_transient, new_icon, fg, bg, format, script */ { "empty", NULL, NULL, NULL, NULL, NULL, -1, -1, -1, MARKUP_NULL, -1, -1, -1, NULL, NULL, NULL, NULL, NULL}, + /* ignore transient hints in history by default */ + { "ignore_transient_in_history", + NULL, NULL, NULL, NULL, NULL, -1, -1, -1, MARKUP_NULL, 1, 1, -1, NULL, NULL, NULL, NULL, NULL}, /* { "rule1", "notify-send", NULL, NULL, NULL, NULL, -1, -1, -1, MARKUP_NULL, -1, -1, -1, NULL, NULL, NULL, "%s %b", NULL}, */ /* { "rule2", "Pidgin", "*says*, NULL, NULL, NULL, -1, -1, CRITICAL, MARKUP_NULL, -1, -1, -1, NULL, NULL, NULL, NULL, NULL}, */ /* { "rule3", "Pidgin", "*signed on*", NULL, NULL, NULL, -1, -1, LOW, MARKUP_NULL, -1, -1, -1, NULL, NULL, NULL, NULL, NULL}, */