osc: implement urxvt’s “OSC 777;notify”

OSC 777 is URxvt’s generic escape to send commands to its perl
extensions. The first parameter is the name of the extension, followed
by its arguments.

OSC 777;notify is a, if not well established, at least a fairly well
known escape sequence to request a (desktop) notification. The syntax
is:

  \e]777;notify;<title>;<body>\e\\

Neither title nor body is escaped in any way, meaning they should not
contain a ‘;’.

Foot will split title from body at the *first* ‘;’. Any remaining ‘;’
characters are treated as part of ‘body’.

Instead of adding built-in support for the freedesktop notification
specification (which would require us to link against at least dbus),
add a new config option to foot.ini: ‘notify’.

This option specifies the command to execute when a notification is
received. ‘${title}’ and ‘${body}’ can be used anywhere, in any
combination, and as many times as you want, in any of the command
arguments.

The default value is ‘notify-send -a foot -i foot ${title} ${body}’
This commit is contained in:
Daniel Eklöf 2020-12-08 19:19:55 +01:00
parent 3e25faeae7
commit 21cc68d49e
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
6 changed files with 184 additions and 12 deletions

View file

@ -566,6 +566,27 @@ parse_section_main(const char *key, const char *value, struct config *conf,
mbstowcs(conf->word_delimiters, value, chars + 1);
}
else if (strcmp(key, "notify") == 0) {
free(conf->notify.raw_cmd);
free(conf->notify.argv);
conf->notify.raw_cmd = NULL;
conf->notify.argv = NULL;
char *raw_cmd = xstrdup(value);
char **argv = NULL;
if (!tokenize_cmdline(raw_cmd, &argv)) {
LOG_AND_NOTIFY_ERR(
"%s:%d: [default]: notify: syntax error in command line",
path, lineno);
return false;
}
conf->notify.raw_cmd = raw_cmd;
conf->notify.argv = argv;
}
else {
LOG_AND_NOTIFY_ERR("%s:%u: [default]: %s: invalid key", path, lineno, key);
return false;
@ -1989,6 +2010,10 @@ config_load(struct config *conf, const char *conf_path,
.server_socket_path = get_server_socket_path(),
.presentation_timings = false,
.hold_at_exit = false,
.notify = {
.raw_cmd = NULL,
.argv = NULL,
},
.tweak = {
.fcft_filter = FCFT_SCALING_FILTER_LANCZOS3,
@ -2004,6 +2029,10 @@ config_load(struct config *conf, const char *conf_path,
.notifications = tll_init(),
};
conf->notify.raw_cmd = xstrdup(
"notify-send -a foot -i foot ${title} ${body}");
tokenize_cmdline(conf->notify.raw_cmd, &conf->notify.argv);
tll_foreach(*initial_user_notifications, it)
tll_push_back(conf->notifications, it->item);
tll_free(*initial_user_notifications);
@ -2070,6 +2099,8 @@ config_free(struct config conf)
free(conf.app_id);
free(conf.word_delimiters);
free(conf.scrollback.indicator.text);
free(conf.notify.raw_cmd);
free(conf.notify.argv);
for (size_t i = 0; i < ALEN(conf.fonts); i++) {
tll_foreach(conf.fonts[i], it)
config_font_destroy(&it->item);