diff --git a/CHANGELOG.md b/CHANGELOG.md index 861245b2..fe27afc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -75,7 +75,7 @@ * `desktop-notifications.command` option, replaces `notify`. * `desktop-notifications.inhibit-when-focused` option, replaces `notify-focus-inhibit`. -* `${icon}` and `${urgency}` added to the +* `${icon}`, `${urgency}` and `${action}` added to the `desktop-notifications.command` template. [1707]: https://codeberg.org/dnkl/foot/issues/1707 diff --git a/config.c b/config.c index a624f95c..be465abf 100644 --- a/config.c +++ b/config.c @@ -3225,7 +3225,7 @@ config_load(struct config *conf, const char *conf_path, parse_modifiers(XKB_MOD_NAME_SHIFT, 5, &conf->mouse.selection_override_modifiers); tokenize_cmdline( - "notify-send --wait --app-name ${app-id} --icon ${icon} --urgency ${urgency} -- ${title} ${body}", + "notify-send --wait --app-name ${app-id} --icon ${icon} --urgency ${urgency} --action ${action} -- ${title} ${body}", &conf->desktop_notifications.command.argv.args); tokenize_cmdline("xdg-open ${url}", &conf->url.launch.argv.args); diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index 5135e080..8e388107 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -462,11 +462,32 @@ Note: do not set *TERM* here; use the *term* option in the main behavior depends on the notification daemon in use, and how it has been configured. - For this to work, foot needs an XDG activation token. To this - end, foot will read the command's stdout; a line prefixed with - *xdgtoken=* will be recognized as containing the XDG - activation token: + For this to work, foot needs to know when the notification was + activated (as opposed to just dismissed), and it needs an XDG + activation token. + There are two parts to handle this. First, the notification + must define an action. For this purpose, foot definse the + template parameter *${action}*. It is intended to be used with + e.g. notify-send's *-A,--action* option. The contents of + *${action}* is not configurable, but will be on the form + 'name=label', where name is a notification internal reference + to the action, and label is what is displayed in the + notification. + + Second, foot needs to know when the notification activated, + and it needs to get hold of the XDG activation token. + + Both are expected to be printed on stdout. + + Foot expects the action name (not label) to be printed on a + single line. No prefix, no postfix. + + Foot expects the activation token to be printed on a single + line, prefixed with *xdgtoken=*. + + Example: + activate-foot xdgtoken=18179adf579a7a904ce73754964b1ec3 The expected format of stdout may change at any time. Please @@ -491,7 +512,7 @@ Note: do not set *TERM* here; use the *term* option in the main For *notify-send*, this can be achieved with the *--wait* option. - Default: _notify-send --wait --app-name ${app-id} --icon ${icon} --urgency ${urgency} -- ${title} ${body}_. + Default: _notify-send --wait --app-name ${app-id} --icon ${icon} --urgency ${urgency} --action ${action} -- ${title} ${body}_. *inhibit-when-focused* Boolean. If enabled, foot will not display notifications if the diff --git a/foot.ini b/foot.ini index 33727dd3..707f09a2 100644 --- a/foot.ini +++ b/foot.ini @@ -47,7 +47,7 @@ # command-focused=no [desktop-notifications] -# command=notify-send --wait --app-name ${app-id} --icon ${icon} --urgency ${urgency} -- ${title} ${body} +# command=notify-send --wait --app-name ${app-id} --icon ${icon} --urgency ${urgency} --action ${action} -- ${title} ${body} # inhibit-when-focused=yes diff --git a/notify.c b/notify.c index 4261268d..d12c3081 100644 --- a/notify.c +++ b/notify.c @@ -54,8 +54,11 @@ consume_stdout(struct notification *notif, bool eof) } else if (!eof) break; + if (strcmp(line, "activate-foot") == 0) + notif->activated = true; + /* Check for 'xdgtoken=xyz' */ - if (len > 9 && memcmp(line, "xdgtoken=", 9) == 0) { + else if (len > 9 && memcmp(line, "xdgtoken=", 9) == 0) { notif->xdg_token = xstrndup(&line[9], len - 9); LOG_DBG("XDG token: \"%s\"", notif->xdg_token); } @@ -133,12 +136,13 @@ notif_done(struct reaper *reaper, pid_t pid, int status, void *data) LOG_DBG("notification %s dismissed", notif->id); - if (notif->focus) { - LOG_DBG("focus window on notification activation: \"%s\"", notif->xdg_token); + if (notif->activated && notif->focus) { + LOG_DBG("focus window on notification activation: \"%s\"", + notif->xdg_token); wayl_activate(term->wl, term->window, notif->xdg_token); } - if (notif->report) { + if (notif->activated && notif->report) { xassert(notif->id != NULL); LOG_DBG("sending notification report to client"); @@ -221,13 +225,14 @@ notify_notify(struct terminal *term, struct notification *notif) ? "normal" : "critical"; if (!spawn_expand_template( - &term->conf->desktop_notifications.command, 6, - (const char *[]){ - "app-id", "window-title", "icon", "title", "body", "urgency"}, - (const char *[]){ - term->app_id ? term->app_id : term->conf->app_id, - term->window_title, icon_name_or_path, title, body, urgency_str}, - &argc, &argv)) + &term->conf->desktop_notifications.command, 7, + (const char *[]){ + "app-id", "window-title", "icon", "title", "body", "urgency", "action"}, + (const char *[]){ + term->app_id ? term->app_id : term->conf->app_id, + term->window_title, icon_name_or_path, title, body, urgency_str, + "activate-foot=Click to activate"}, + &argc, &argv)) { return false; } diff --git a/notify.h b/notify.h index 90fbf9fc..ba017276 100644 --- a/notify.h +++ b/notify.h @@ -45,6 +45,7 @@ struct notification { * Used internally by notify */ + bool activated; /* User 'activated' the notification */ char *xdg_token; /* XDG activation token, from daemon */ pid_t pid; /* Notifier command PID */