diff --git a/config.c b/config.c index 5dbbacb7..1ec73da0 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} --hint BOOLEAN:suppress-sound:${muted} --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} --hint STRING:sound-name:${sound-name} --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 6db7ffae..71992c8f 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -464,6 +464,12 @@ Note: do not set *TERM* here; use the *term* option in the main sounds be muted. It is intended to set the *suppress-sound* hint (with e.g. notify-send's *--hint* option). + _${sound-name}_ is replaced by sound-name requested by the + notification. This should be a name from the freedesktop sound + naming specification, but this is not something that foot + enforces. It is intended to set the *sound-name* 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 @@ -574,6 +580,7 @@ xdgtoken=95ebdfe56e4f47ddb5bba9d7dc3a2c35 --expire-time ${expire-time}++ --hint STRING:image-path:${icon}++ --hint BOOLEAN:suppress-sound:${muted}++ + --hint STRING:sound-name:${sound-name}++ --replace-id ${replace-id}++ ${action-argument}++ --print-id++ diff --git a/foot.ini b/foot.ini index fba9305e..9e2f5f29 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} --hint BOOLEAN:suppress-sound:${muted} --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} --hint STRING:sound-name:${sound-name} --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 0b37f40a..d1c06fb1 100644 --- a/notify.c +++ b/notify.c @@ -34,6 +34,7 @@ notify_free(struct terminal *term, struct notification *notif) free(notif->icon_cache_id); free(notif->icon_symbolic_name); free(notif->icon_data); + free(notif->sound_name); free(notif->xdg_token); free(notif->stdout_data); @@ -421,11 +422,11 @@ 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, muted=%s " - "(tracking: %s)", + "urgency=\"%s\", icon=\"%s\", expires=%d, replaces=%u, muted=%s, " + "sound-name=%s (tracking: %s)", title, body, app_id, notif->category, urgency_str, icon_name_or_path, notif->expire_time, replaces_id, - notif->muted ? "yes" : "no", + notif->muted ? "yes" : "no", notif->sound_name, track_notification ? "yes" : "no"); xassert(title != NULL); @@ -466,14 +467,17 @@ notify_notify(struct terminal *term, struct notification *notif) } if (!spawn_expand_template( - &term->conf->desktop_notifications.command, 11, + &term->conf->desktop_notifications.command, 12, (const char *[]){ "app-id", "window-title", "icon", "title", "body", "category", - "urgency", "muted", "expire-time", "replace-id", "action-argument"}, + "urgency", "muted", "sound-name", "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, - notif->muted ? "true" : "false", expire_time, replaces_id_str, + notif->muted ? "true" : "false", + notif->sound_name != NULL ? notif->sound_name : "", + expire_time, replaces_id_str, /* Custom expansion below, since we need to expand to multiple arguments */ "${action-argument}"}, @@ -545,6 +549,7 @@ notify_notify(struct terminal *term, struct notification *notif) notif->icon_data = NULL; notif->icon_data_sz = 0; notif->icon_path = NULL; + notif->sound_name = NULL; notif->icon_fd = -1; notif->stdout_fd = -1; struct notification *new_notif = &tll_back(term->active_notifications); diff --git a/notify.h b/notify.h index ccdfdea8..89b51238 100644 --- a/notify.h +++ b/notify.h @@ -53,6 +53,7 @@ struct notification { bool report_closed; /* OSC-99: report notification closed to client */ bool muted; /* Explicitly mute the notification */ + char *sound_name; /* Should be set to NULL if muted == true */ /* * Used internally by notify diff --git a/osc.c b/osc.c index 50415570..eba1850f 100644 --- a/osc.c +++ b/osc.c @@ -740,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=silent%s", + "\033]99;i=%s:p=?;p=%s:a=%s:o=%s:u=%s:c=1:w=1:s=silent,xdg-names%s", reply_id, p_caps, a_caps, when_caps, u_caps, terminator); xassert(n < sizeof(reply)); @@ -964,6 +964,15 @@ kitty_notification(struct terminal *term, char *string) if (sound_name != NULL) { notif->muted = streq(sound_name, "silent"); + + if (notif->muted || streq(sound_name, "system")) { + free(notif->sound_name); + notif->sound_name = NULL; + } else { + free(notif->sound_name); + notif->sound_name = sound_name; + sound_name = NULL; /* Prevent double free */ + } } /* Handled chunked payload - append to existing metadata */