From 045ead985c1e320f289704b6a995d48a5eccf59e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Tue, 23 Jul 2024 16:41:52 +0200 Subject: [PATCH] notify: don't focus/report on notification dismissal Only do it when the notification was activated. Here, activated means the 'click to activate' notification action was triggered. How do we tie everything together? First, we add a new template parameter, ${action}. It's intended to be used with e.g. notify-send's --action option. When the action is triggered, notify-send prints its name on stdout, on a separate line. Look for this in stdout. Only if we've seen it do we focus/report the notification. --- CHANGELOG.md | 2 +- config.c | 2 +- doc/foot.ini.5.scd | 31 ++++++++++++++++++++++++++----- foot.ini | 2 +- notify.c | 27 ++++++++++++++++----------- notify.h | 1 + 6 files changed, 46 insertions(+), 19 deletions(-) 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 */