diff --git a/config.c b/config.c index bf3c4175..5dbbacb7 100644 --- a/config.c +++ b/config.c @@ -3242,7 +3242,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 ${app-id} --category ${category} --urgency ${urgency} --expire-time ${expire-time} --hint STRING:image-path:${icon} --replace-id ${replace-id} ${action-argument} --print-id -- ${title} ${body}", + "notify-send --wait --app-name ${app-id} --icon ${app-id} --category ${category} --urgency ${urgency} --expire-time ${expire-time} --hint STRING:image-path:${icon} --hint BOOLEAN:suppress-sound:${muted} --replace-id ${replace-id} ${action-argument} --print-id -- ${title} ${body}", &conf->desktop_notifications.command.argv.args); tokenize_cmdline("--action ${action-name}=${action-label}", &conf->desktop_notifications.command_action_arg.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 8f9ffe57..6db7ffae 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -459,6 +459,11 @@ Note: do not set *TERM* here; use the *term* option in the main below. Can be used together with e.g. notify-send's *--replace-id* option. + _${muted}_ is replaced by either *true* or *false*, depending + on whether the notification has requested all notification + sounds be muted. It is intended to set the *suppress-sound* + hint (with e.g. notify-send's *--hint* option). + _${action-argument}_ will be expanded to the *command-action-argument* option, for each notification action. There will always be at least one action, the @@ -568,6 +573,7 @@ xdgtoken=95ebdfe56e4f47ddb5bba9d7dc3a2c35 --urgency ${urgency}++ --expire-time ${expire-time}++ --hint STRING:image-path:${icon}++ + --hint BOOLEAN:suppress-sound:${muted}++ --replace-id ${replace-id}++ ${action-argument}++ --print-id++ diff --git a/foot.ini b/foot.ini index 029daa9b..fba9305e 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 ${app-id} --category ${category} --urgency ${urgency} --expire-time ${expire-time} --hint STRING:image-path:${icon} --replace-id ${replace-id} ${action-argument} --print-id -- ${title} ${body} +# command=notify-send --wait --app-name ${app-id} --icon ${app-id} --category ${category} --urgency ${urgency} --expire-time ${expire-time} --hint STRING:image-path:${icon} --hint BOOLEAN:suppress-sound:${muted} --replace-id ${replace-id} ${action-argument} --print-id -- ${title} ${body} # command-action-argument=--action ${action-name}=${action-label} # close="" # inhibit-when-focused=yes diff --git a/notify.c b/notify.c index 15139c40..0b37f40a 100644 --- a/notify.c +++ b/notify.c @@ -421,9 +421,12 @@ notify_notify(struct terminal *term, struct notification *notif) ? "normal" : "critical"; LOG_DBG("notify: title=\"%s\", body=\"%s\", app-id=\"%s\", category=\"%s\", " - "urgency=\"%s\", icon=\"%s\", expires=%d, replaces=%u (tracking: %s)", + "urgency=\"%s\", icon=\"%s\", expires=%d, replaces=%u, muted=%s " + "(tracking: %s)", title, body, app_id, notif->category, urgency_str, icon_name_or_path, - notif->expire_time, replaces_id, track_notification ? "yes" : "no"); + notif->expire_time, replaces_id, + notif->muted ? "yes" : "no", + track_notification ? "yes" : "no"); xassert(title != NULL); if (title == NULL) @@ -463,14 +466,14 @@ notify_notify(struct terminal *term, struct notification *notif) } if (!spawn_expand_template( - &term->conf->desktop_notifications.command, 10, + &term->conf->desktop_notifications.command, 11, (const char *[]){ "app-id", "window-title", "icon", "title", "body", "category", - "urgency", "expire-time", "replace-id", "action-argument"}, + "urgency", "muted", "expire-time", "replace-id", "action-argument"}, (const char *[]){ app_id, term->window_title, icon_name_or_path, title, body, notif->category != NULL ? notif->category : "", urgency_str, - expire_time, replaces_id_str, + notif->muted ? "true" : "false", expire_time, replaces_id_str, /* Custom expansion below, since we need to expand to multiple arguments */ "${action-argument}"}, diff --git a/notify.h b/notify.h index 592d2c84..ccdfdea8 100644 --- a/notify.h +++ b/notify.h @@ -52,6 +52,8 @@ struct notification { bool report_activated; /* OSC-99: report notification activation to client */ bool report_closed; /* OSC-99: report notification closed to client */ + bool muted; /* Explicitly mute the notification */ + /* * Used internally by notify */ diff --git a/osc.c b/osc.c index 28d8b7b8..50415570 100644 --- a/osc.c +++ b/osc.c @@ -609,6 +609,7 @@ kitty_notification(struct terminal *term, char *string) char *icon_cache_id = NULL; /* The 'g' parameter */ char *symbolic_icon = NULL; /* The 'n' parameter */ char *category = NULL; /* The 't' parameter */ + char *sound_name = NULL; /* The 's' parameter */ char *payload = NULL; bool focus = true; /* The 'a' parameter */ @@ -739,7 +740,7 @@ kitty_notification(struct terminal *term, char *string) char reply[128]; int n = xsnprintf( reply, sizeof(reply), - "\033]99;i=%s:p=?;p=%s:a=%s:o=%s:u=%s:c=1:w=1%s", + "\033]99;i=%s:p=?;p=%s:a=%s:o=%s:u=%s:c=1:w=1:s=silent%s", reply_id, p_caps, a_caps, when_caps, u_caps, terminator); xassert(n < sizeof(reply)); @@ -783,10 +784,15 @@ kitty_notification(struct terminal *term, char *string) break; } - case 'f': - free(app_id); - app_id = base64_decode(value, NULL); + case 'f': { + /* App-name */ + char *decoded = base64_decode(value, NULL); + if (decoded != NULL) { + free(app_id); + app_id = decoded; + } break; + } case 't': { /* Type (category) */ @@ -805,6 +811,16 @@ kitty_notification(struct terminal *term, char *string) break; } + case 's': { + /* Sound */ + char *decoded = base64_decode(value, NULL); + if (decoded != NULL) { + free(sound_name); + sound_name = decoded; + } + break; + } + case 'g': /* graphical ID (see 'n' and 'p=icon') */ free(icon_cache_id); @@ -946,6 +962,10 @@ kitty_notification(struct terminal *term, char *string) } } + if (sound_name != NULL) { + notif->muted = streq(sound_name, "silent"); + } + /* Handled chunked payload - append to existing metadata */ switch (payload_type) { case PAYLOAD_TITLE: @@ -1067,6 +1087,7 @@ out: free(symbolic_icon); free(payload); free(category); + free(sound_name); } void