Merge branch 'xdga-launch'

This commit is contained in:
Daniel Eklöf 2021-11-03 12:58:55 +01:00
commit 347b90eaae
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
9 changed files with 51 additions and 11 deletions

View file

@ -12,15 +12,18 @@ struct client_string {
struct client_data { struct client_data {
bool hold:1; bool hold:1;
bool no_wait:1; bool no_wait:1;
uint8_t reserved:6; bool xdga_token:1;
uint8_t reserved:5;
uint8_t token_len;
uint16_t cwd_len; uint16_t cwd_len;
uint16_t override_count; uint16_t override_count;
uint16_t argc; uint16_t argc;
/* char cwd[static cwd_len]; */ /* char cwd[static cwd_len]; */
/* char token[static token_len]; */
/* struct client_string overrides[static override_count]; */ /* struct client_string overrides[static override_count]; */
/* struct client_string argv[static argc]; */ /* struct client_string argv[static argc]; */
} __attribute__((packed)); } __attribute__((packed));
_Static_assert(sizeof(struct client_data) == 7, "protocol struct size error"); _Static_assert(sizeof(struct client_data) == 8, "protocol struct size error");

View file

@ -156,6 +156,11 @@ main(int argc, char *const *argv)
/* Used to format overrides */ /* Used to format overrides */
bool no_wait = false; 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]; char buf[1024];
/* Total packet length, not (yet) including overrides or argv[] */ /* Total packet length, not (yet) including overrides or argv[] */
@ -373,13 +378,15 @@ main(int argc, char *const *argv)
const struct client_data data = { const struct client_data data = {
.hold = hold, .hold = hold,
.no_wait = no_wait, .no_wait = no_wait,
.xdga_token = xdga_token,
.token_len = token_len,
.cwd_len = cwd_len, .cwd_len = cwd_len,
.override_count = override_count, .override_count = override_count,
.argc = argc, .argc = argc,
}; };
/* Total packet length, not (yet) including argv[] */ /* 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 */ /* Add argv[] size to total packet length */
cargv = xmalloc(argc * sizeof(cargv[0])); cargv = xmalloc(argc * sizeof(cargv[0]));
@ -398,6 +405,7 @@ main(int argc, char *const *argv)
/* Check for size overflows */ /* Check for size overflows */
if (total_len >= 1llu << (8 * sizeof(uint32_t)) || if (total_len >= 1llu << (8 * sizeof(uint32_t)) ||
cwd_len >= 1 << (8 * sizeof(data.cwd_len)) || 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 || override_count > (size_t)(unsigned int)data.override_count ||
argc > (int)(unsigned int)data.argc) argc > (int)(unsigned int)data.argc)
{ {
@ -414,6 +422,15 @@ main(int argc, char *const *argv)
goto err; 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 */ /* Send overrides */
tll_foreach(overrides, it) { tll_foreach(overrides, it) {
const struct override *o = &it->item; const struct override *o = &it->item;

7
main.c
View file

@ -160,6 +160,10 @@ main(int argc, char *const *argv)
static const int foot_exit_failure = -26; static const int foot_exit_failure = -26;
int ret = foot_exit_failure; int ret = foot_exit_failure;
/* XDG startup notifications */
const char *token = getenv("XDG_ACTIVATION_TOKEN");
unsetenv("XDG_ACTIVATION_TOKEN");
/* Startup notifications; we don't support it, but must ensure we /* Startup notifications; we don't support it, but must ensure we
* don't pass this on to programs launched by us */ * don't pass this on to programs launched by us */
unsetenv("DESKTOP_STARTUP_ID"); unsetenv("DESKTOP_STARTUP_ID");
@ -530,7 +534,8 @@ main(int argc, char *const *argv)
goto out; goto out;
if (!as_server && (term = term_init( if (!as_server && (term = term_init(
&conf, fdm, reaper, wayl, "foot", cwd, argc, argv, &conf, fdm, reaper, wayl, "foot", cwd, token,
argc, argv,
&term_shutdown_cb, &shutdown_ctx)) == NULL) { &term_shutdown_cb, &shutdown_ctx)) == NULL) {
goto out; goto out;
} }

View file

@ -75,7 +75,7 @@ render_xcursor_set(struct seat *seat, struct terminal *term, const char *xcursor
} }
struct wl_window * struct wl_window *
wayl_win_init(struct terminal *term) wayl_win_init(struct terminal *term, const char *token)
{ {
return NULL; return NULL;
} }

View file

@ -244,6 +244,17 @@ fdm_client(struct fdm *fdm, int fd, int events, void *data)
const char *cwd = (const char *)p; p += cdata.cwd_len; const char *cwd = (const char *)p; p += cdata.cwd_len;
LOG_DBG("CWD = %.*s", cdata.cwd_len, cwd); LOG_DBG("CWD = %.*s", cdata.cwd_len, cwd);
/* XDGA token */
const char *token = NULL;
if (cdata.xdga_token) {
CHECK_BUF_AND_NULL(cdata.token_len);
token = (const char *)p; p += cdata.token_len;
LOG_DBG("XDGA = %.*s", cdata.token_len, token);
} else {
LOG_DBG("No XDGA token");
}
/* Overrides */ /* Overrides */
for (uint16_t i = 0; i < cdata.override_count; i++) { for (uint16_t i = 0; i < cdata.override_count; i++) {
struct client_string arg; struct client_string arg;
@ -303,7 +314,7 @@ fdm_client(struct fdm *fdm, int fd, int events, void *data)
instance->terminal = term_init( instance->terminal = term_init(
conf != NULL ? conf : server->conf, conf != NULL ? conf : server->conf,
server->fdm, server->reaper, server->wayl, "footclient", cwd, server->fdm, server->reaper, server->wayl, "footclient", cwd, token,
cdata.argc, argv, &term_shutdown_handler, instance); cdata.argc, argv, &term_shutdown_handler, instance);
if (instance->terminal == NULL) { if (instance->terminal == NULL) {

View file

@ -1033,7 +1033,7 @@ static void fdm_client_terminated(
struct terminal * struct terminal *
term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper, term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
struct wayland *wayl, const char *foot_exe, const char *cwd, struct wayland *wayl, const char *foot_exe, const char *cwd,
int argc, char *const *argv, const char *token, int argc, char *const *argv,
void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data) void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data)
{ {
int ptmx = -1; int ptmx = -1;
@ -1257,7 +1257,7 @@ term_init(const struct config *conf, struct fdm *fdm, struct reaper *reaper,
sizeof(term->colors.table)); sizeof(term->colors.table));
/* Initialize the Wayland window backend */ /* Initialize the Wayland window backend */
if ((term->window = wayl_win_init(term)) == NULL) if ((term->window = wayl_win_init(term, token)) == NULL)
goto err; goto err;
/* Load fonts */ /* Load fonts */

View file

@ -642,7 +642,7 @@ struct config;
struct terminal *term_init( struct terminal *term_init(
const struct config *conf, struct fdm *fdm, struct reaper *reaper, const struct config *conf, struct fdm *fdm, struct reaper *reaper,
struct wayland *wayl, const char *foot_exe, const char *cwd, struct wayland *wayl, const char *foot_exe, const char *cwd,
int argc, char *const *argv, const char *token, int argc, char *const *argv,
void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data); void (*shutdown_cb)(void *data, int exit_code), void *shutdown_data);
bool term_shutdown(struct terminal *term); bool term_shutdown(struct terminal *term);

View file

@ -1374,7 +1374,7 @@ wayl_destroy(struct wayland *wayl)
} }
struct wl_window * struct wl_window *
wayl_win_init(struct terminal *term) wayl_win_init(struct terminal *term, const char *token)
{ {
struct wayland *wayl = term->wl; struct wayland *wayl = term->wl;
const struct config *conf = term->conf; const struct config *conf = term->conf;
@ -1444,6 +1444,10 @@ wayl_win_init(struct terminal *term)
wl_surface_commit(win->surface); wl_surface_commit(win->surface);
/* Complete XDG startup notification */
if (token)
xdg_activation_v1_activate(wayl->xdg_activation, token, win->surface);
if (conf->tweak.render_timer_osd) { if (conf->tweak.render_timer_osd) {
if (!wayl_win_subsurface_new(win, &win->render_timer)) { if (!wayl_win_subsurface_new(win, &win->render_timer)) {
LOG_ERR("failed to create render timer surface"); LOG_ERR("failed to create render timer surface");

View file

@ -492,7 +492,7 @@ bool wayl_reload_xcursor_theme(struct seat *seat, int new_scale);
void wayl_flush(struct wayland *wayl); void wayl_flush(struct wayland *wayl);
void wayl_roundtrip(struct wayland *wayl); void wayl_roundtrip(struct wayland *wayl);
struct wl_window *wayl_win_init(struct terminal *term); struct wl_window *wayl_win_init(struct terminal *term, const char *token);
void wayl_win_destroy(struct wl_window *win); void wayl_win_destroy(struct wl_window *win);
bool wayl_win_set_urgent(struct wl_window *win); bool wayl_win_set_urgent(struct wl_window *win);