2020-12-10 18:06:24 +01:00
|
|
|
#include "notify.h"
|
|
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
|
|
#include <sys/stat.h>
|
|
|
|
|
#include <fcntl.h>
|
|
|
|
|
|
|
|
|
|
#define LOG_MODULE "notify"
|
|
|
|
|
#define LOG_ENABLE_DBG 0
|
|
|
|
|
#include "log.h"
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#include "spawn.h"
|
osc/notify: add support for OSC-99, kitty desktop notifications
This adds limited support for OSC-99, kitty desktop notifications[^1]. We
support everything defined by the "protocol", except:
* 'a': action to perform on notification activation. Since we don't
trigger the notification ourselves (over D-Bus), we don't know a)
which ID the notification got, or b) when it is clicked.
* ... and that's it. Everything else is supported
To be explicit, we *do* support:
* Chunked notifications (d=0|1), allowing the application to append
data to a notification in chunks, before it's finally displayed.
* Plain UTF-8, or base64-encoded UTF-8 payload (e=0|1).
* Notification identifier (i=xyz).
* Payload type (p=title|body).
* When to honor the notification (o=always|unfocused|invisible), with
the following quirks:
- we don't know when the window is invisible, thus it's treated as
'unfocused'.
- the foot option 'notify-focus-inhibit' overrides 'always'
* Urgency (u=0|1|2)
[^1]: https://sw.kovidgoyal.net/kitty/desktop-notifications/
2024-07-19 15:04:28 +02:00
|
|
|
#include "terminal.h"
|
2020-12-10 18:06:24 +01:00
|
|
|
#include "xmalloc.h"
|
|
|
|
|
|
|
|
|
|
void
|
osc/notify: add support for OSC-99, kitty desktop notifications
This adds limited support for OSC-99, kitty desktop notifications[^1]. We
support everything defined by the "protocol", except:
* 'a': action to perform on notification activation. Since we don't
trigger the notification ourselves (over D-Bus), we don't know a)
which ID the notification got, or b) when it is clicked.
* ... and that's it. Everything else is supported
To be explicit, we *do* support:
* Chunked notifications (d=0|1), allowing the application to append
data to a notification in chunks, before it's finally displayed.
* Plain UTF-8, or base64-encoded UTF-8 payload (e=0|1).
* Notification identifier (i=xyz).
* Payload type (p=title|body).
* When to honor the notification (o=always|unfocused|invisible), with
the following quirks:
- we don't know when the window is invisible, thus it's treated as
'unfocused'.
- the foot option 'notify-focus-inhibit' overrides 'always'
* Urgency (u=0|1|2)
[^1]: https://sw.kovidgoyal.net/kitty/desktop-notifications/
2024-07-19 15:04:28 +02:00
|
|
|
notify_notify(const struct terminal *term, const char *title, const char *body,
|
|
|
|
|
enum notify_when when, enum notify_urgency urgency)
|
2020-12-10 18:06:24 +01:00
|
|
|
{
|
2021-01-31 10:26:36 +01:00
|
|
|
LOG_DBG("notify: title=\"%s\", msg=\"%s\"", title, body);
|
2020-12-10 18:06:24 +01:00
|
|
|
|
osc/notify: add support for OSC-99, kitty desktop notifications
This adds limited support for OSC-99, kitty desktop notifications[^1]. We
support everything defined by the "protocol", except:
* 'a': action to perform on notification activation. Since we don't
trigger the notification ourselves (over D-Bus), we don't know a)
which ID the notification got, or b) when it is clicked.
* ... and that's it. Everything else is supported
To be explicit, we *do* support:
* Chunked notifications (d=0|1), allowing the application to append
data to a notification in chunks, before it's finally displayed.
* Plain UTF-8, or base64-encoded UTF-8 payload (e=0|1).
* Notification identifier (i=xyz).
* Payload type (p=title|body).
* When to honor the notification (o=always|unfocused|invisible), with
the following quirks:
- we don't know when the window is invisible, thus it's treated as
'unfocused'.
- the foot option 'notify-focus-inhibit' overrides 'always'
* Urgency (u=0|1|2)
[^1]: https://sw.kovidgoyal.net/kitty/desktop-notifications/
2024-07-19 15:04:28 +02:00
|
|
|
if ((term->conf->notify_focus_inhibit || when != NOTIFY_ALWAYS)
|
|
|
|
|
&& term->kbd_focus)
|
|
|
|
|
{
|
2024-02-06 12:36:45 +01:00
|
|
|
/* No notifications while we're focused */
|
2020-12-10 18:07:50 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-10 18:06:24 +01:00
|
|
|
if (title == NULL || body == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
2021-06-18 16:18:41 +02:00
|
|
|
if (term->conf->notify.argv.args == NULL)
|
2020-12-10 18:06:24 +01:00
|
|
|
return;
|
|
|
|
|
|
2021-01-31 14:40:27 +01:00
|
|
|
char **argv = NULL;
|
|
|
|
|
size_t argc = 0;
|
|
|
|
|
|
osc/notify: add support for OSC-99, kitty desktop notifications
This adds limited support for OSC-99, kitty desktop notifications[^1]. We
support everything defined by the "protocol", except:
* 'a': action to perform on notification activation. Since we don't
trigger the notification ourselves (over D-Bus), we don't know a)
which ID the notification got, or b) when it is clicked.
* ... and that's it. Everything else is supported
To be explicit, we *do* support:
* Chunked notifications (d=0|1), allowing the application to append
data to a notification in chunks, before it's finally displayed.
* Plain UTF-8, or base64-encoded UTF-8 payload (e=0|1).
* Notification identifier (i=xyz).
* Payload type (p=title|body).
* When to honor the notification (o=always|unfocused|invisible), with
the following quirks:
- we don't know when the window is invisible, thus it's treated as
'unfocused'.
- the foot option 'notify-focus-inhibit' overrides 'always'
* Urgency (u=0|1|2)
[^1]: https://sw.kovidgoyal.net/kitty/desktop-notifications/
2024-07-19 15:04:28 +02:00
|
|
|
const char *urgency_str =
|
|
|
|
|
urgency == NOTIFY_URGENCY_LOW
|
|
|
|
|
? "low"
|
|
|
|
|
: urgency == NOTIFY_URGENCY_NORMAL
|
|
|
|
|
? "normal" : "critical";
|
|
|
|
|
|
2021-01-31 14:40:27 +01:00
|
|
|
if (!spawn_expand_template(
|
osc/notify: add support for OSC-99, kitty desktop notifications
This adds limited support for OSC-99, kitty desktop notifications[^1]. We
support everything defined by the "protocol", except:
* 'a': action to perform on notification activation. Since we don't
trigger the notification ourselves (over D-Bus), we don't know a)
which ID the notification got, or b) when it is clicked.
* ... and that's it. Everything else is supported
To be explicit, we *do* support:
* Chunked notifications (d=0|1), allowing the application to append
data to a notification in chunks, before it's finally displayed.
* Plain UTF-8, or base64-encoded UTF-8 payload (e=0|1).
* Notification identifier (i=xyz).
* Payload type (p=title|body).
* When to honor the notification (o=always|unfocused|invisible), with
the following quirks:
- we don't know when the window is invisible, thus it's treated as
'unfocused'.
- the foot option 'notify-focus-inhibit' overrides 'always'
* Urgency (u=0|1|2)
[^1]: https://sw.kovidgoyal.net/kitty/desktop-notifications/
2024-07-19 15:04:28 +02:00
|
|
|
&term->conf->notify, 5,
|
|
|
|
|
(const char *[]){"app-id", "window-title", "title", "body", "urgency"},
|
|
|
|
|
(const char *[]){term->app_id ? term->app_id : term->conf->app_id,
|
|
|
|
|
term->window_title, title, body, urgency_str},
|
2021-01-31 14:40:27 +01:00
|
|
|
&argc, &argv))
|
|
|
|
|
{
|
|
|
|
|
return;
|
2020-12-10 18:06:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
LOG_DBG("notify command:");
|
2021-01-31 14:40:27 +01:00
|
|
|
for (size_t i = 0; i < argc; i++)
|
2020-12-10 18:06:24 +01:00
|
|
|
LOG_DBG(" argv[%zu] = \"%s\"", i, argv[i]);
|
|
|
|
|
|
|
|
|
|
/* Redirect stdin to /dev/null, but ignore failure to open */
|
|
|
|
|
int devnull = open("/dev/null", O_RDONLY);
|
url-mode: add support for XDG activation when opening URLs
First, add a ‘token’ argument to spawn(). When non-NULL, spawn() will
set the ‘XDG_ACTIVATION_TOKEN’ environment variable in the forked
process. If DISPLAY is non-NULL, we also set DESKTOP_STARTUP_ID, for
compatibility with X11 applications. Note that failing to set either
of these environment variables are considered non-fatal - i.e. we
ignore failures.
Next, add a helper function, wayl_get_activation_token(), to generate
an XDG activation token, and call a user-provided callback when it’s
‘done (since token generation is asynchronous). This function takes an
optional ‘seat’ and ‘serial’ arguments - when both are non-NULL/zero,
we set the serial on the token. ‘win’ is a required argument, used to
set the surface on the token.
Re-write wayl_win_set_urgent() to use the new helper function.
Finally, rewrite activate_url() to first try to get an activation
token (and spawn the URL launcher in the token callback). If that
fails, or if we don’t have XDG activation support, spawn the URL
launcher immediately (like before this patch).
Closes #1058
2022-05-03 19:37:04 +02:00
|
|
|
spawn(term->reaper, NULL, argv, devnull, -1, -1, NULL);
|
2020-12-10 18:06:24 +01:00
|
|
|
|
|
|
|
|
if (devnull >= 0)
|
|
|
|
|
close(devnull);
|
|
|
|
|
|
2021-01-31 14:40:27 +01:00
|
|
|
for (size_t i = 0; i < argc; i++)
|
2020-12-10 18:06:24 +01:00
|
|
|
free(argv[i]);
|
|
|
|
|
free(argv);
|
|
|
|
|
}
|