aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sway/desktop/launcher.h3
-rw-r--r--sway/desktop/launcher.c13
-rw-r--r--sway/xdg_activation_v1.c21
3 files changed, 31 insertions, 6 deletions
diff --git a/include/sway/desktop/launcher.h b/include/sway/desktop/launcher.h
index b7716e82..ad465a9e 100644
--- a/include/sway/desktop/launcher.h
+++ b/include/sway/desktop/launcher.h
@@ -3,12 +3,15 @@
#include <stdlib.h>
#include <wayland-server-core.h>
+#include "sway/input/seat.h"
struct launcher_ctx {
pid_t pid;
char *fallback_name;
struct wlr_xdg_activation_token_v1 *token;
struct wl_listener token_destroy;
+ struct sway_seat *seat;
+ struct wl_listener seat_destroy;
bool activated;
diff --git a/sway/desktop/launcher.c b/sway/desktop/launcher.c
index 00a7e38a..4a4255d7 100644
--- a/sway/desktop/launcher.c
+++ b/sway/desktop/launcher.c
@@ -67,6 +67,9 @@ void launcher_ctx_destroy(struct launcher_ctx *ctx) {
}
wl_list_remove(&ctx->node_destroy.link);
wl_list_remove(&ctx->token_destroy.link);
+ if (ctx->seat) {
+ wl_list_remove(&ctx->seat_destroy.link);
+ }
wl_list_remove(&ctx->link);
wlr_xdg_activation_token_v1_destroy(ctx->token);
free(ctx->fallback_name);
@@ -227,6 +230,12 @@ struct launcher_ctx *launcher_ctx_create(struct wlr_xdg_activation_token_v1 *tok
return ctx;
}
+static void launch_ctx_handle_seat_destroy(struct wl_listener *listener, void *data) {
+ struct launcher_ctx *ctx = wl_container_of(listener, ctx, seat_destroy);
+ ctx->seat = NULL;
+ wl_list_remove(&ctx->seat_destroy.link);
+}
+
// Creates a context with a new token for the internal launcher
struct launcher_ctx *launcher_ctx_create_internal(void) {
struct sway_seat *seat = input_manager_current_seat();
@@ -238,13 +247,15 @@ struct launcher_ctx *launcher_ctx_create_internal(void) {
struct wlr_xdg_activation_token_v1 *token =
wlr_xdg_activation_token_v1_create(server.xdg_activation_v1);
- token->seat = seat->wlr_seat;
struct launcher_ctx *ctx = launcher_ctx_create(token, &ws->node);
if (!ctx) {
wlr_xdg_activation_token_v1_destroy(token);
return NULL;
}
+ ctx->seat = seat;
+ ctx->seat_destroy.notify = launch_ctx_handle_seat_destroy;
+ wl_signal_add(&seat->wlr_seat->events.destroy, &ctx->seat_destroy);
return ctx;
}
diff --git a/sway/xdg_activation_v1.c b/sway/xdg_activation_v1.c
index 47270f73..72c7fa4c 100644
--- a/sway/xdg_activation_v1.c
+++ b/sway/xdg_activation_v1.c
@@ -18,11 +18,15 @@ void xdg_activation_v1_handle_request_activate(struct wl_listener *listener,
return;
}
+ struct launcher_ctx *ctx = event->token->data;
+ if (ctx == NULL) {
+ return;
+ }
+
if (!xdg_surface->surface->mapped) {
// This is a startup notification. If we are tracking it, the data
// field is a launcher_ctx.
- struct launcher_ctx *ctx = event->token->data;
- if (!ctx || ctx->activated) {
+ if (ctx->activated) {
// This ctx has already been activated and cannot be used again
// for a startup notification. It will be destroyed
return;
@@ -33,9 +37,16 @@ void xdg_activation_v1_handle_request_activate(struct wl_listener *listener,
return;
}
- struct wlr_seat *wlr_seat = event->token->seat;
- struct sway_seat *seat = wlr_seat ? wlr_seat->data : NULL;
- view_request_activate(view, seat);
+ // This is an activation request. If this context is internal we have ctx->seat.
+ struct sway_seat *seat = ctx->seat;
+ if (!seat) {
+ // Otherwise, use the seat indicated by the launcher client in set_serial
+ seat = ctx->token->seat ? ctx->token->seat->data : NULL;
+ }
+
+ if (seat) {
+ view_request_activate(view, seat);
+ }
}
void xdg_activation_v1_handle_new_token(struct wl_listener *listener, void *data) {