aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sway/desktop/launcher.h22
-rw-r--r--include/sway/tree/view.h3
-rw-r--r--sway/desktop/launcher.c50
-rw-r--r--sway/tree/view.c28
4 files changed, 64 insertions, 39 deletions
diff --git a/include/sway/desktop/launcher.h b/include/sway/desktop/launcher.h
index 7802bee1..927d7a37 100644
--- a/include/sway/desktop/launcher.h
+++ b/include/sway/desktop/launcher.h
@@ -3,10 +3,26 @@
#include <stdlib.h>
-struct sway_workspace *workspace_for_pid(pid_t pid);
+struct launcher_ctx {
+ pid_t pid;
+ char *name;
+ struct wlr_xdg_activation_token_v1 *token;
+ struct wl_listener token_destroy;
-void launcher_ctx_create(pid_t pid);
+ struct sway_node *node;
+ struct wl_listener node_destroy;
+
+ struct wl_list link; // sway_server::pending_launcher_ctxs
+};
+
+struct launcher_ctx *launcher_ctx_find_pid(pid_t pid);
+
+struct sway_workspace *launcher_ctx_get_workspace(struct launcher_ctx *ctx);
-void remove_workspace_pid(pid_t pid);
+void launcher_ctx_consume(struct launcher_ctx *ctx);
+
+void launcher_ctx_destroy(struct launcher_ctx *ctx);
+
+void launcher_ctx_create(pid_t pid);
#endif
diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h
index 0dcbf1aa..ca099431 100644
--- a/include/sway/tree/view.h
+++ b/include/sway/tree/view.h
@@ -74,6 +74,7 @@ struct sway_view {
struct sway_xdg_decoration *xdg_decoration;
pid_t pid;
+ struct launcher_ctx *ctx;
// The size the view would want to be if it weren't tiled.
// Used when changing a view from tiled to floating.
@@ -372,4 +373,6 @@ void view_save_buffer(struct sway_view *view);
bool view_is_transient_for(struct sway_view *child, struct sway_view *ancestor);
+void view_assign_ctx(struct sway_view *view, struct launcher_ctx *ctx);
+
#endif
diff --git a/sway/desktop/launcher.c b/sway/desktop/launcher.c
index 337ca975..810a04ef 100644
--- a/sway/desktop/launcher.c
+++ b/sway/desktop/launcher.c
@@ -13,18 +13,6 @@
static struct wl_list launcher_ctxs;
-struct launcher_ctx {
- pid_t pid;
- char *name;
- struct wlr_xdg_activation_token_v1 *token;
- struct wl_listener token_destroy;
-
- struct sway_node *node;
- struct wl_listener node_destroy;
-
- struct wl_list link;
-};
-
/**
* Get the pid of a parent process given the pid of a child process.
*
@@ -59,7 +47,20 @@ static pid_t get_parent_pid(pid_t child) {
return -1;
}
-static void launcher_ctx_destroy(struct launcher_ctx *ctx) {
+void launcher_ctx_consume(struct launcher_ctx *ctx) {
+ // The view is now responsible for destroying this ctx
+ wl_list_remove(&ctx->token_destroy.link);
+ wl_list_init(&ctx->token_destroy.link);
+
+ wlr_xdg_activation_token_v1_destroy(ctx->token);
+ ctx->token = NULL;
+
+ // Prevent additional matches
+ wl_list_remove(&ctx->link);
+ wl_list_init(&ctx->link);
+}
+
+void launcher_ctx_destroy(struct launcher_ctx *ctx) {
if (ctx == NULL) {
return;
}
@@ -71,7 +72,7 @@ static void launcher_ctx_destroy(struct launcher_ctx *ctx) {
free(ctx);
}
-static struct launcher_ctx *launcher_ctx_find_pid(pid_t pid) {
+struct launcher_ctx *launcher_ctx_find_pid(pid_t pid) {
if (!launcher_ctxs.prev && !launcher_ctxs.next) {
wl_list_init(&launcher_ctxs);
return NULL;
@@ -97,7 +98,7 @@ static struct launcher_ctx *launcher_ctx_find_pid(pid_t pid) {
return ctx;
}
-static struct sway_workspace *launcher_ctx_get_workspace(
+struct sway_workspace *launcher_ctx_get_workspace(
struct launcher_ctx *ctx) {
struct sway_workspace *ws = NULL;
struct sway_output *output = NULL;
@@ -135,16 +136,6 @@ static struct sway_workspace *launcher_ctx_get_workspace(
return ws;
}
-struct sway_workspace *workspace_for_pid(pid_t pid) {
- struct launcher_ctx *ctx = launcher_ctx_find_pid(pid);
- if (ctx == NULL) {
- return NULL;
- }
- struct sway_workspace *ws = launcher_ctx_get_workspace(ctx);
- launcher_ctx_destroy(ctx);
- return ws;
-}
-
static void ctx_handle_node_destroy(struct wl_listener *listener, void *data) {
struct launcher_ctx *ctx = wl_container_of(listener, ctx, node_destroy);
switch (ctx->node->type) {
@@ -217,12 +208,3 @@ void launcher_ctx_create(pid_t pid) {
wl_list_insert(&launcher_ctxs, &ctx->link);
}
-
-void remove_workspace_pid(pid_t pid) {
- if (!launcher_ctxs.prev || !launcher_ctxs.next) {
- return;
- }
-
- struct launcher_ctx *ctx = launcher_ctx_find_pid(pid);
- launcher_ctx_destroy(ctx);
-}
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 7482e7a4..31387aaa 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -64,6 +64,8 @@ void view_destroy(struct sway_view *view) {
}
list_free(view->executed_criteria);
+ view_assign_ctx(view, NULL);
+
free(view->title_format);
if (view->impl->destroy) {
@@ -534,6 +536,20 @@ static void view_populate_pid(struct sway_view *view) {
view->pid = pid;
}
+void view_assign_ctx(struct sway_view *view, struct launcher_ctx *ctx) {
+ if (view->ctx) {
+ // This ctx has been replaced
+ launcher_ctx_destroy(view->ctx);
+ view->ctx = NULL;
+ }
+ if (ctx == NULL) {
+ return;
+ }
+ launcher_ctx_consume(ctx);
+
+ view->ctx = ctx;
+}
+
static struct sway_workspace *select_workspace(struct sway_view *view) {
struct sway_seat *seat = input_manager_current_seat();
@@ -569,13 +585,14 @@ static struct sway_workspace *select_workspace(struct sway_view *view) {
}
list_free(criterias);
if (ws) {
- remove_workspace_pid(view->pid);
+ view_assign_ctx(view, NULL);
return ws;
}
// Check if there's a PID mapping
- ws = workspace_for_pid(view->pid);
+ ws = view->ctx ? launcher_ctx_get_workspace(view->ctx) : NULL;
if (ws) {
+ view_assign_ctx(view, NULL);
return ws;
}
@@ -718,6 +735,13 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
view_populate_pid(view);
view->container = container_create(view);
+ if (view->ctx == NULL) {
+ struct launcher_ctx *ctx = launcher_ctx_find_pid(view->pid);
+ if (ctx != NULL) {
+ view_assign_ctx(view, ctx);
+ }
+ }
+
// If there is a request to be opened fullscreen on a specific output, try
// to honor that request. Otherwise, fallback to assigns, pid mappings,
// focused workspace, etc