notify: try to read the daemon assigned notification ID from stdout

And document the things we recognize in the notification helper's
stdout.
This commit is contained in:
Daniel Eklöf 2024-07-24 16:02:19 +02:00
parent e271027c0c
commit f56da385fe
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 56 additions and 3 deletions

View file

@ -496,6 +496,21 @@ Note: do not set *TERM* here; use the *term* option in the main
reporting the XDG activation token in any way. This means
window activation will not work by default.
Stdout
Foot recognizes the following things from the notification
helper's stdout:
- _nnn_: integer in base 10, daemon assigned notification ID
- _id=nnn_: same as plain _nnn_.
- _default_: the 'default' action was triggered
- _action=default_: same as _default_
- _xdgtoken=xyz_: XDG activation token.
Example:
17++
action=default++
xdgtoken=95ebdfe56e4f47ddb5bba9d7dc3a2c35
Default: _notify-send --wait --app-name ${app-id} --icon ${icon} --urgency ${urgency} --action ${action-name}=${action-label} --print-id -- ${title} ${body}_.

View file

@ -34,6 +34,27 @@ notify_free(struct terminal *term, struct notification *notif)
free(notif->stdout_data);
}
static bool
to_integer(const char *line, size_t len, uint32_t *res)
{
bool is_id = true;
uint32_t maybe_id = 0;
for (size_t i = 0; i < len; i++) {
char digit = line[i];
if (digit < '0' || digit > '9') {
is_id = false;
break;
}
maybe_id *= 10;
maybe_id += digit - '0';
}
*res = maybe_id;
return is_id;
}
static void
consume_stdout(struct notification *notif, bool eof)
{
@ -54,10 +75,26 @@ consume_stdout(struct notification *notif, bool eof)
} else if (!eof)
break;
if (strcmp(line, "default") == 0)
notif->activated = true;
uint32_t maybe_id = 0;
/* Check for 'xdgtoken=xyz' */
/* Check for daemon assigned ID, either '123', or 'id=123' */
if (to_integer(line, len, &maybe_id) ||
(len > 3 && memcmp(line, "id=", 3) == 0 &&
to_integer(&line[3], len - 3, &maybe_id)))
{
notif->external_id = maybe_id;
LOG_DBG("external ID: %u", notif->external_id);
}
/* Check for triggered action, either 'default' or 'action=default' */
else if ((len == 7 && memcmp(line, "default", 7) == 0) ||
(len == 7 + 7 && memcmp(line, "action=default", 7 + 7) == 0))
{
notif->activated = true;
LOG_DBG("notification's default action was triggered");
}
/* Check for XDG activation token, 'xdgtoken=xyz' */
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);

View file

@ -45,6 +45,7 @@ struct notification {
* Used internally by notify
*/
uint32_t external_id; /* Daemon assigned notification ID */
bool activated; /* User 'activated' the notification */
char *xdg_token; /* XDG activation token, from daemon */