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
- `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
### Added

View File

@ -91,13 +91,16 @@ 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},
/* 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}, */
/* { "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: */

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.
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")
Defines the font or font set used. Optionally set the size as a decimal number
@ -556,9 +559,10 @@ matched.
=item B<filtering>
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:
@ -574,8 +578,8 @@ Shell-like globing is supported.
=item B<modifying>
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.

View File

@ -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 ###

View File

@ -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,14 +203,23 @@ static void on_notify(GDBusConnection *connection,
if (dict_value)
raw_icon = get_raw_image_from_data_hint(dict_value);
dict_value = g_variant_lookup_value(content, "value", G_VARIANT_TYPE_INT32);
if (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;
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:
@ -246,6 +256,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 {

View File

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

View File

@ -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]);

View File

@ -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;

View File

@ -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: */

View File

@ -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;

View File

@ -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);
}