From f56da385fe4c4434bfc10c362cbdda58c63d238f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Ekl=C3=B6f?= Date: Wed, 24 Jul 2024 16:02:19 +0200 Subject: [PATCH] notify: try to read the daemon assigned notification ID from stdout And document the things we recognize in the notification helper's stdout. --- doc/foot.ini.5.scd | 15 +++++++++++++++ notify.c | 43 ++++++++++++++++++++++++++++++++++++++++--- notify.h | 1 + 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/doc/foot.ini.5.scd b/doc/foot.ini.5.scd index ef48323f..72e6d052 100644 --- a/doc/foot.ini.5.scd +++ b/doc/foot.ini.5.scd @@ -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}_. diff --git a/notify.c b/notify.c index 4efddec2..986b3b7b 100644 --- a/notify.c +++ b/notify.c @@ -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); diff --git a/notify.h b/notify.h index d78af5fa..231495dc 100644 --- a/notify.h +++ b/notify.h @@ -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 */