Merge pull request #343 from bebehei/transient-notifications

add support for transient hints
This commit is contained in:
Nikos Tsipinakis 2017-09-07 14:01:19 +03:00 committed by GitHub
commit 16bbde5bf3
11 changed files with 55 additions and 20 deletions

View File

@ -5,6 +5,11 @@
### Fixed ### Fixed
- `new_icon` rule being ignored on notifications that had a raw icon - `new_icon` rule being ignored on notifications that had a raw icon
## 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 ## 1.2.0 - 2017-07-12
### Added ### Added

View File

@ -91,13 +91,16 @@ keyboard_shortcut context_ks = {.str = "none",
rule_t default_rules[] = { rule_t default_rules[] = {
/* name can be any unique string. It is used to identify the rule in dunstrc to override it there */ /* 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 */ /* 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, false, NULL, NULL, NULL, NULL, NULL}, { "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, false, NULL, NULL, NULL, "%s %b", NULL}, */ /* ignore transient hints in history by default */
/* { "rule2", "Pidgin", "*says*, NULL, NULL, NULL, -1, -1, CRITICAL, MARKUP_NULL, false, NULL, NULL, NULL, NULL, NULL}, */ { "ignore_transient_in_history",
/* { "rule3", "Pidgin", "*signed on*", NULL, NULL, NULL, -1, -1, LOW, MARKUP_NULL, false, NULL, NULL, NULL, NULL, NULL}, */ NULL, NULL, NULL, NULL, NULL, -1, -1, -1, MARKUP_NULL, 1, 1, -1, NULL, NULL, NULL, NULL, NULL},
/* { "rule4", "Pidgin", "*signed off*", NULL, NULL, NULL, -1, -1, LOW, MARKUP_NULL, false, 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}, */
/* { "rule5", NULL, "*foobar*", NULL, NULL, NULL, -1, -1, -1, MARKUP_NULL, false, NULL, NULL, "#00FF00", NULL, 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}, */
}; };
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */ /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -234,6 +234,9 @@ Don't timeout notifications if user is idle longer than this value (in seconds).
Set to 0 to disable. 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<font> (default: "Monospace 8") =item B<font> (default: "Monospace 8")
Defines the font or font set used. Optionally set the size as a decimal number Defines the font or font set used. Optionally set the size as a decimal number
@ -556,9 +559,10 @@ matched.
=item B<filtering> =item B<filtering>
Notifications can be matched for any of the following attributes: appname, Notifications can be matched for any of the following attributes: appname,
summary, body, icon, category and msg_urgency where each is the respective summary, body, icon, category, match_transient and msg_urgency where each is
notification attribute to be matched and 'msg_urgency' is the urgency of the the respective notification attribute to be matched and 'msg_urgency' is the
notification, it is named so to not conflict with trying to modify the urgency. 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 To define a matching rule simply assign the specified value to the value that
should be matched, for example: should be matched, for example:
@ -574,8 +578,8 @@ Shell-like globing is supported.
=item B<modifying> =item B<modifying>
The following attributes can be overridden: timeout, urgency, foreground, The following attributes can be overridden: timeout, urgency, foreground,
background, new_icon, format where, as with the filtering attributes, each one background, new_icon, set_transient, format where, as with the filtering attributes,
corresponds to the respective notification attribute to be modified. 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 As with filtering, to make a rule modify an attribute simply assign it in the
rule definition. rule definition.

View File

@ -80,6 +80,7 @@
# Don't remove messages, if the user is idle (no mouse or keyboard input) # Don't remove messages, if the user is idle (no mouse or keyboard input)
# for longer than idle_threshold seconds. # for longer than idle_threshold seconds.
# Set to 0 to disable. # Set to 0 to disable.
# Transient notifications ignore this setting.
idle_threshold = 120 idle_threshold = 120
### Text ### ### Text ###

View File

@ -138,6 +138,7 @@ static void on_notify(GDBusConnection *connection,
/* hints */ /* hints */
gint urgency = 1; gint urgency = 1;
gint progress = -1; gint progress = -1;
gboolean transient = 0;
gchar *fgcolor = NULL; gchar *fgcolor = NULL;
gchar *bgcolor = NULL; gchar *bgcolor = NULL;
gchar *category = NULL; gchar *category = NULL;
@ -202,14 +203,23 @@ static void on_notify(GDBusConnection *connection,
if (dict_value) if (dict_value)
raw_icon = get_raw_image_from_data_hint(dict_value); raw_icon = get_raw_image_from_data_hint(dict_value);
dict_value = g_variant_lookup_value(content, "value", G_VARIANT_TYPE_INT32); /* Check for transient hints
if (dict_value) { *
* 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;
if((dict_value = g_variant_lookup_value(content, "value", G_VARIANT_TYPE_INT32)))
progress = g_variant_get_int32(dict_value); progress = g_variant_get_int32(dict_value);
} else { else if((dict_value = g_variant_lookup_value(content, "value", G_VARIANT_TYPE_UINT32)))
dict_value = g_variant_lookup_value(content, "value", G_VARIANT_TYPE_UINT32); progress = g_variant_get_uint32(dict_value);
if (dict_value)
progress = g_variant_get_uint32(dict_value);
}
} }
break; break;
case 7: case 7:
@ -246,6 +256,7 @@ static void on_notify(GDBusConnection *connection,
n->urgency = urgency; n->urgency = urgency;
n->category = category; n->category = category;
n->dbus_client = g_strdup(sender); n->dbus_client = g_strdup(sender);
n->transient = transient;
if (actions->count > 0) { if (actions->count > 0) {
n->actions = actions; n->actions = actions;
} else { } else {

View File

@ -69,7 +69,7 @@ void check_timeouts(void)
iter = iter->next; iter = iter->next;
/* don't timeout when user is idle */ /* don't timeout when user is idle */
if (x_is_idle()) { if (x_is_idle() && !n->transient) {
n->start = time(NULL); n->start = time(NULL);
continue; continue;
} }

View File

@ -41,6 +41,7 @@ void notification_print(notification *n)
printf("\tcategory: %s\n", n->category); printf("\tcategory: %s\n", n->category);
printf("\ttimeout: %d\n", n->timeout); printf("\ttimeout: %d\n", n->timeout);
printf("\turgency: %d\n", n->urgency); printf("\turgency: %d\n", n->urgency);
printf("\ttransient: %d\n", n->transient);
printf("\tformatted: '%s'\n", n->msg); printf("\tformatted: '%s'\n", n->msg);
printf("\tfg: %s\n", n->color_strings[ColFG]); printf("\tfg: %s\n", n->color_strings[ColFG]);
printf("\tbg: %s\n", n->color_strings[ColBG]); printf("\tbg: %s\n", n->color_strings[ColBG]);

View File

@ -53,6 +53,7 @@ typedef struct _notification {
int displayed_height; int displayed_height;
const char *color_strings[3]; const char *color_strings[3];
bool first_render; bool first_render;
bool transient;
int progress; /* percentage + 1, 0 to hide */ int progress; /* percentage + 1, 0 to hide */
int line_count; int line_count;

View File

@ -18,6 +18,8 @@ void rule_apply(rule_t *r, notification *n)
n->urgency = r->urgency; n->urgency = r->urgency;
if (r->history_ignore != -1) if (r->history_ignore != -1)
n->history_ignore = r->history_ignore; n->history_ignore = r->history_ignore;
if (r->set_transient != -1)
n->transient = r->set_transient;
if (r->markup != MARKUP_NULL) if (r->markup != MARKUP_NULL)
n->markup = r->markup; n->markup = r->markup;
if (r->new_icon) { if (r->new_icon) {
@ -66,6 +68,8 @@ void rule_init(rule_t *r)
r->markup = MARKUP_NULL; r->markup = MARKUP_NULL;
r->new_icon = NULL; r->new_icon = NULL;
r->history_ignore = false; r->history_ignore = false;
r->match_transient = -1;
r->set_transient = -1;
r->fg = NULL; r->fg = NULL;
r->bg = NULL; r->bg = NULL;
r->format = 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->body || !fnmatch(r->body, n->body, 0))
&& (!r->icon || !fnmatch(r->icon, n->icon, 0)) && (!r->icon || !fnmatch(r->icon, n->icon, 0))
&& (!r->category || !fnmatch(r->category, n->category, 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)); && (r->msg_urgency == -1 || r->msg_urgency == n->urgency));
} }
/* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */ /* vim: set tabstop=8 shiftwidth=8 expandtab textwidth=0: */

View File

@ -23,6 +23,8 @@ typedef struct _rule_t {
int urgency; int urgency;
enum markup_mode markup; enum markup_mode markup;
int history_ignore; int history_ignore;
int match_transient;
int set_transient;
char *new_icon; char *new_icon;
char *fg; char *fg;
char *bg; char *bg;

View File

@ -636,6 +636,8 @@ void load_settings(char *cmdline_config_path)
r->format = ini_get_string(cur_section, "format", r->format); r->format = ini_get_string(cur_section, "format", r->format);
r->new_icon = ini_get_string(cur_section, "new_icon", r->new_icon); 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->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); r->script = ini_get_path(cur_section, "script", NULL);
} }