foot/client: implement xdga client activation

This is an application of the xdg activation protocol that will allow
compositors to associate new foot toplevels with the command that
launched them.

footclient receives an activation token from the launcher which the
compositor can use to track application startup. It passes the token
to the foot server, which then activates the new window with the token
to complete the startup sequence.
This commit is contained in:
Ronan Pigott 2021-10-28 17:51:44 -07:00
parent 347e79f8a1
commit 99d5bf64bc
9 changed files with 51 additions and 11 deletions

View file

@ -156,6 +156,11 @@ main(int argc, char *const *argv)
/* Used to format overrides */
bool no_wait = false;
/* For XDG activation */
const char *token = getenv("XDG_ACTIVATION_TOKEN");
bool xdga_token = token != NULL;
size_t token_len = xdga_token ? strlen(token) + 1 : 0;
char buf[1024];
/* Total packet length, not (yet) including overrides or argv[] */
@ -373,13 +378,15 @@ main(int argc, char *const *argv)
const struct client_data data = {
.hold = hold,
.no_wait = no_wait,
.xdga_token = xdga_token,
.token_len = token_len,
.cwd_len = cwd_len,
.override_count = override_count,
.argc = argc,
};
/* Total packet length, not (yet) including argv[] */
total_len += sizeof(data) + cwd_len;
total_len += sizeof(data) + cwd_len + token_len;
/* Add argv[] size to total packet length */
cargv = xmalloc(argc * sizeof(cargv[0]));
@ -398,6 +405,7 @@ main(int argc, char *const *argv)
/* Check for size overflows */
if (total_len >= 1llu << (8 * sizeof(uint32_t)) ||
cwd_len >= 1 << (8 * sizeof(data.cwd_len)) ||
token_len >= 1 << (8 * sizeof(data.token_len)) ||
override_count > (size_t)(unsigned int)data.override_count ||
argc > (int)(unsigned int)data.argc)
{
@ -414,6 +422,15 @@ main(int argc, char *const *argv)
goto err;
}
/* Send XDGA token, if we have one */
if (xdga_token) {
if (sendall(fd, token, token_len) != token_len)
{
LOG_ERRNO("failed to send xdg activation token to server");
goto err;
}
}
/* Send overrides */
tll_foreach(overrides, it) {
const struct override *o = &it->item;