diff options
-rw-r--r-- | include/sway/desktop/launcher.h | 22 | ||||
-rw-r--r-- | include/sway/tree/view.h | 3 | ||||
-rw-r--r-- | sway/desktop/launcher.c | 50 | ||||
-rw-r--r-- | sway/tree/view.c | 28 |
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 @@ | |||
3 | 3 | ||
4 | #include <stdlib.h> | 4 | #include <stdlib.h> |
5 | 5 | ||
6 | struct sway_workspace *workspace_for_pid(pid_t pid); | 6 | struct launcher_ctx { |
7 | pid_t pid; | ||
8 | char *name; | ||
9 | struct wlr_xdg_activation_token_v1 *token; | ||
10 | struct wl_listener token_destroy; | ||
7 | 11 | ||
8 | void launcher_ctx_create(pid_t pid); | 12 | struct sway_node *node; |
13 | struct wl_listener node_destroy; | ||
14 | |||
15 | struct wl_list link; // sway_server::pending_launcher_ctxs | ||
16 | }; | ||
17 | |||
18 | struct launcher_ctx *launcher_ctx_find_pid(pid_t pid); | ||
19 | |||
20 | struct sway_workspace *launcher_ctx_get_workspace(struct launcher_ctx *ctx); | ||
9 | 21 | ||
10 | void remove_workspace_pid(pid_t pid); | 22 | void launcher_ctx_consume(struct launcher_ctx *ctx); |
23 | |||
24 | void launcher_ctx_destroy(struct launcher_ctx *ctx); | ||
25 | |||
26 | void launcher_ctx_create(pid_t pid); | ||
11 | 27 | ||
12 | #endif | 28 | #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 { | |||
74 | struct sway_xdg_decoration *xdg_decoration; | 74 | struct sway_xdg_decoration *xdg_decoration; |
75 | 75 | ||
76 | pid_t pid; | 76 | pid_t pid; |
77 | struct launcher_ctx *ctx; | ||
77 | 78 | ||
78 | // The size the view would want to be if it weren't tiled. | 79 | // The size the view would want to be if it weren't tiled. |
79 | // Used when changing a view from tiled to floating. | 80 | // Used when changing a view from tiled to floating. |
@@ -372,4 +373,6 @@ void view_save_buffer(struct sway_view *view); | |||
372 | 373 | ||
373 | bool view_is_transient_for(struct sway_view *child, struct sway_view *ancestor); | 374 | bool view_is_transient_for(struct sway_view *child, struct sway_view *ancestor); |
374 | 375 | ||
376 | void view_assign_ctx(struct sway_view *view, struct launcher_ctx *ctx); | ||
377 | |||
375 | #endif | 378 | #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 @@ | |||
13 | 13 | ||
14 | static struct wl_list launcher_ctxs; | 14 | static struct wl_list launcher_ctxs; |
15 | 15 | ||
16 | struct launcher_ctx { | ||
17 | pid_t pid; | ||
18 | char *name; | ||
19 | struct wlr_xdg_activation_token_v1 *token; | ||
20 | struct wl_listener token_destroy; | ||
21 | |||
22 | struct sway_node *node; | ||
23 | struct wl_listener node_destroy; | ||
24 | |||
25 | struct wl_list link; | ||
26 | }; | ||
27 | |||
28 | /** | 16 | /** |
29 | * Get the pid of a parent process given the pid of a child process. | 17 | * Get the pid of a parent process given the pid of a child process. |
30 | * | 18 | * |
@@ -59,7 +47,20 @@ static pid_t get_parent_pid(pid_t child) { | |||
59 | return -1; | 47 | return -1; |
60 | } | 48 | } |
61 | 49 | ||
62 | static void launcher_ctx_destroy(struct launcher_ctx *ctx) { | 50 | void launcher_ctx_consume(struct launcher_ctx *ctx) { |
51 | // The view is now responsible for destroying this ctx | ||
52 | wl_list_remove(&ctx->token_destroy.link); | ||
53 | wl_list_init(&ctx->token_destroy.link); | ||
54 | |||
55 | wlr_xdg_activation_token_v1_destroy(ctx->token); | ||
56 | ctx->token = NULL; | ||
57 | |||
58 | // Prevent additional matches | ||
59 | wl_list_remove(&ctx->link); | ||
60 | wl_list_init(&ctx->link); | ||
61 | } | ||
62 | |||
63 | void launcher_ctx_destroy(struct launcher_ctx *ctx) { | ||
63 | if (ctx == NULL) { | 64 | if (ctx == NULL) { |
64 | return; | 65 | return; |
65 | } | 66 | } |
@@ -71,7 +72,7 @@ static void launcher_ctx_destroy(struct launcher_ctx *ctx) { | |||
71 | free(ctx); | 72 | free(ctx); |
72 | } | 73 | } |
73 | 74 | ||
74 | static struct launcher_ctx *launcher_ctx_find_pid(pid_t pid) { | 75 | struct launcher_ctx *launcher_ctx_find_pid(pid_t pid) { |
75 | if (!launcher_ctxs.prev && !launcher_ctxs.next) { | 76 | if (!launcher_ctxs.prev && !launcher_ctxs.next) { |
76 | wl_list_init(&launcher_ctxs); | 77 | wl_list_init(&launcher_ctxs); |
77 | return NULL; | 78 | return NULL; |
@@ -97,7 +98,7 @@ static struct launcher_ctx *launcher_ctx_find_pid(pid_t pid) { | |||
97 | return ctx; | 98 | return ctx; |
98 | } | 99 | } |
99 | 100 | ||
100 | static struct sway_workspace *launcher_ctx_get_workspace( | 101 | struct sway_workspace *launcher_ctx_get_workspace( |
101 | struct launcher_ctx *ctx) { | 102 | struct launcher_ctx *ctx) { |
102 | struct sway_workspace *ws = NULL; | 103 | struct sway_workspace *ws = NULL; |
103 | struct sway_output *output = NULL; | 104 | struct sway_output *output = NULL; |
@@ -135,16 +136,6 @@ static struct sway_workspace *launcher_ctx_get_workspace( | |||
135 | return ws; | 136 | return ws; |
136 | } | 137 | } |
137 | 138 | ||
138 | struct sway_workspace *workspace_for_pid(pid_t pid) { | ||
139 | struct launcher_ctx *ctx = launcher_ctx_find_pid(pid); | ||
140 | if (ctx == NULL) { | ||
141 | return NULL; | ||
142 | } | ||
143 | struct sway_workspace *ws = launcher_ctx_get_workspace(ctx); | ||
144 | launcher_ctx_destroy(ctx); | ||
145 | return ws; | ||
146 | } | ||
147 | |||
148 | static void ctx_handle_node_destroy(struct wl_listener *listener, void *data) { | 139 | static void ctx_handle_node_destroy(struct wl_listener *listener, void *data) { |
149 | struct launcher_ctx *ctx = wl_container_of(listener, ctx, node_destroy); | 140 | struct launcher_ctx *ctx = wl_container_of(listener, ctx, node_destroy); |
150 | switch (ctx->node->type) { | 141 | switch (ctx->node->type) { |
@@ -217,12 +208,3 @@ void launcher_ctx_create(pid_t pid) { | |||
217 | 208 | ||
218 | wl_list_insert(&launcher_ctxs, &ctx->link); | 209 | wl_list_insert(&launcher_ctxs, &ctx->link); |
219 | } | 210 | } |
220 | |||
221 | void remove_workspace_pid(pid_t pid) { | ||
222 | if (!launcher_ctxs.prev || !launcher_ctxs.next) { | ||
223 | return; | ||
224 | } | ||
225 | |||
226 | struct launcher_ctx *ctx = launcher_ctx_find_pid(pid); | ||
227 | launcher_ctx_destroy(ctx); | ||
228 | } | ||
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) { | |||
64 | } | 64 | } |
65 | list_free(view->executed_criteria); | 65 | list_free(view->executed_criteria); |
66 | 66 | ||
67 | view_assign_ctx(view, NULL); | ||
68 | |||
67 | free(view->title_format); | 69 | free(view->title_format); |
68 | 70 | ||
69 | if (view->impl->destroy) { | 71 | if (view->impl->destroy) { |
@@ -534,6 +536,20 @@ static void view_populate_pid(struct sway_view *view) { | |||
534 | view->pid = pid; | 536 | view->pid = pid; |
535 | } | 537 | } |
536 | 538 | ||
539 | void view_assign_ctx(struct sway_view *view, struct launcher_ctx *ctx) { | ||
540 | if (view->ctx) { | ||
541 | // This ctx has been replaced | ||
542 | launcher_ctx_destroy(view->ctx); | ||
543 | view->ctx = NULL; | ||
544 | } | ||
545 | if (ctx == NULL) { | ||
546 | return; | ||
547 | } | ||
548 | launcher_ctx_consume(ctx); | ||
549 | |||
550 | view->ctx = ctx; | ||
551 | } | ||
552 | |||
537 | static struct sway_workspace *select_workspace(struct sway_view *view) { | 553 | static struct sway_workspace *select_workspace(struct sway_view *view) { |
538 | struct sway_seat *seat = input_manager_current_seat(); | 554 | struct sway_seat *seat = input_manager_current_seat(); |
539 | 555 | ||
@@ -569,13 +585,14 @@ static struct sway_workspace *select_workspace(struct sway_view *view) { | |||
569 | } | 585 | } |
570 | list_free(criterias); | 586 | list_free(criterias); |
571 | if (ws) { | 587 | if (ws) { |
572 | remove_workspace_pid(view->pid); | 588 | view_assign_ctx(view, NULL); |
573 | return ws; | 589 | return ws; |
574 | } | 590 | } |
575 | 591 | ||
576 | // Check if there's a PID mapping | 592 | // Check if there's a PID mapping |
577 | ws = workspace_for_pid(view->pid); | 593 | ws = view->ctx ? launcher_ctx_get_workspace(view->ctx) : NULL; |
578 | if (ws) { | 594 | if (ws) { |
595 | view_assign_ctx(view, NULL); | ||
579 | return ws; | 596 | return ws; |
580 | } | 597 | } |
581 | 598 | ||
@@ -718,6 +735,13 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface, | |||
718 | view_populate_pid(view); | 735 | view_populate_pid(view); |
719 | view->container = container_create(view); | 736 | view->container = container_create(view); |
720 | 737 | ||
738 | if (view->ctx == NULL) { | ||
739 | struct launcher_ctx *ctx = launcher_ctx_find_pid(view->pid); | ||
740 | if (ctx != NULL) { | ||
741 | view_assign_ctx(view, ctx); | ||
742 | } | ||
743 | } | ||
744 | |||
721 | // If there is a request to be opened fullscreen on a specific output, try | 745 | // If there is a request to be opened fullscreen on a specific output, try |
722 | // to honor that request. Otherwise, fallback to assigns, pid mappings, | 746 | // to honor that request. Otherwise, fallback to assigns, pid mappings, |
723 | // focused workspace, etc | 747 | // focused workspace, etc |