dunst/rules.c
Yuri D'Elia b5e00c43c7 Fix markup handling.
The current "allow_markup" setting will simply strip any markup from the final
notification, which includes formatting elements. On top of that, literal
[<>&..] symbols are not quoted before are being passed onto pango in several
places, resulting in stray error messages.

This patch fixes allow_markup to correctly strip markup only from the incoming
notification, not from the format.

You might also want to treat incoming messages as literal text (supplied by
un-aware programs), in which case you need to properly quote the text before
it's processed by pango. A new setting is introduced, called "plain_text",
which forces incoming messages to be treated literally.

allow_markup/plain_text are complimentary to each other.

The new rule actions allow to narrow down the handling to a specific block,
achieving notification Zen.

The following is done in this patch:

- Fix ruleset initialization in config.def.h.
- Introduce new allow_markup/plain_text actions in the rules.
- Fix handling of allow_markup to strip markup from summary/body only,
  preserving format's markup.
- Fix broken string functions (string_replace_all didn't handle recursive
  replacements correctly).
- Fix quoting of other literal fields (icon name/appname).
- Fix handling of ignore_newline as well (applied only on summary/body).
- Dunstrc update with the same previous defaults.
2014-12-05 16:05:41 +01:00

82 lines
2.2 KiB
C

/* copyright 2013 Sascha Kruse and contributors (see LICENSE for licensing information) */
#include <glib.h>
#include <fnmatch.h>
#include "dunst.h"
#include "rules.h"
/*
* Apply rule to notification.
*/
void rule_apply(rule_t * r, notification * n)
{
if (r->timeout != -1)
n->timeout = r->timeout;
if (r->urgency != -1)
n->urgency = r->urgency;
if (r->allow_markup != -1)
n->allow_markup = r->allow_markup;
if (r->plain_text != -1)
n->plain_text = r->plain_text;
if (r->new_icon)
n->icon = r->new_icon;
if (r->fg)
n->color_strings[ColFG] = r->fg;
if (r->bg)
n->color_strings[ColBG] = r->bg;
if (r->format)
n->format = r->format;
if (r->script)
n->script = r->script;
}
/*
* Check all rules if they match n and apply.
*/
void rule_apply_all(notification * n)
{
for (GSList * iter = rules; iter; iter = iter->next) {
rule_t *r = iter->data;
if (rule_matches_notification(r, n)) {
rule_apply(r, n);
}
}
}
/*
* Initialize rule with default values.
*/
void rule_init(rule_t * r)
{
r->name = NULL;
r->appname = NULL;
r->summary = NULL;
r->body = NULL;
r->icon = NULL;
r->category = NULL;
r->msg_urgency = -1;
r->timeout = -1;
r->urgency = -1;
r->allow_markup = -1;
r->plain_text = -1;
r->new_icon = NULL;
r->fg = NULL;
r->bg = NULL;
r->format = NULL;
}
/*
* Check whether rule should be applied to n.
*/
bool rule_matches_notification(rule_t * r, notification * n)
{
return ((!r->appname || !fnmatch(r->appname, n->appname, 0))
&& (!r->summary || !fnmatch(r->summary, n->summary, 0))
&& (!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->msg_urgency == -1 || r->msg_urgency == n->urgency));
}
/* vim: set ts=8 sw=8 tw=0: */