diff options
-rw-r--r-- | include/sway/desktop/launcher.h | 7 | ||||
-rw-r--r-- | sway/commands/exec_always.c | 2 | ||||
-rw-r--r-- | sway/desktop/launcher.c | 80 |
3 files changed, 68 insertions, 21 deletions
diff --git a/include/sway/desktop/launcher.h b/include/sway/desktop/launcher.h index d5651adf..b7716e82 100644 --- a/include/sway/desktop/launcher.h +++ b/include/sway/desktop/launcher.h | |||
@@ -6,7 +6,7 @@ | |||
6 | 6 | ||
7 | struct launcher_ctx { | 7 | struct launcher_ctx { |
8 | pid_t pid; | 8 | pid_t pid; |
9 | char *name; | 9 | char *fallback_name; |
10 | struct wlr_xdg_activation_token_v1 *token; | 10 | struct wlr_xdg_activation_token_v1 *token; |
11 | struct wl_listener token_destroy; | 11 | struct wl_listener token_destroy; |
12 | 12 | ||
@@ -26,7 +26,10 @@ void launcher_ctx_consume(struct launcher_ctx *ctx); | |||
26 | 26 | ||
27 | void launcher_ctx_destroy(struct launcher_ctx *ctx); | 27 | void launcher_ctx_destroy(struct launcher_ctx *ctx); |
28 | 28 | ||
29 | struct launcher_ctx *launcher_ctx_create(void); | 29 | struct launcher_ctx *launcher_ctx_create_internal(void); |
30 | |||
31 | struct launcher_ctx *launcher_ctx_create( | ||
32 | struct wlr_xdg_activation_token_v1 *token, struct sway_node *node); | ||
30 | 33 | ||
31 | const char *launcher_ctx_get_token_name(struct launcher_ctx *ctx); | 34 | const char *launcher_ctx_get_token_name(struct launcher_ctx *ctx); |
32 | 35 | ||
diff --git a/sway/commands/exec_always.c b/sway/commands/exec_always.c index bb982621..8fca1909 100644 --- a/sway/commands/exec_always.c +++ b/sway/commands/exec_always.c | |||
@@ -63,7 +63,7 @@ struct cmd_results *cmd_exec_process(int argc, char **argv) { | |||
63 | } | 63 | } |
64 | 64 | ||
65 | pid_t pid, child; | 65 | pid_t pid, child; |
66 | struct launcher_ctx *ctx = launcher_ctx_create(); | 66 | struct launcher_ctx *ctx = launcher_ctx_create_internal(); |
67 | // Fork process | 67 | // Fork process |
68 | if ((pid = fork()) == 0) { | 68 | if ((pid = fork()) == 0) { |
69 | // Fork child process again | 69 | // Fork child process again |
diff --git a/sway/desktop/launcher.c b/sway/desktop/launcher.c index 48e5d24c..b666da1e 100644 --- a/sway/desktop/launcher.c +++ b/sway/desktop/launcher.c | |||
@@ -69,7 +69,7 @@ void launcher_ctx_destroy(struct launcher_ctx *ctx) { | |||
69 | wl_list_remove(&ctx->token_destroy.link); | 69 | wl_list_remove(&ctx->token_destroy.link); |
70 | wl_list_remove(&ctx->link); | 70 | wl_list_remove(&ctx->link); |
71 | wlr_xdg_activation_token_v1_destroy(ctx->token); | 71 | wlr_xdg_activation_token_v1_destroy(ctx->token); |
72 | free(ctx->name); | 72 | free(ctx->fallback_name); |
73 | free(ctx); | 73 | free(ctx); |
74 | } | 74 | } |
75 | 75 | ||
@@ -114,22 +114,22 @@ struct sway_workspace *launcher_ctx_get_workspace( | |||
114 | break; | 114 | break; |
115 | case N_OUTPUT: | 115 | case N_OUTPUT: |
116 | output = ctx->node->sway_output; | 116 | output = ctx->node->sway_output; |
117 | ws = workspace_by_name(ctx->name); | 117 | ws = workspace_by_name(ctx->fallback_name); |
118 | if (!ws) { | 118 | if (!ws) { |
119 | sway_log(SWAY_DEBUG, | 119 | sway_log(SWAY_DEBUG, |
120 | "Creating workspace %s for pid %d because it disappeared", | 120 | "Creating workspace %s for pid %d because it disappeared", |
121 | ctx->name, ctx->pid); | 121 | ctx->fallback_name, ctx->pid); |
122 | if (!output->enabled) { | 122 | if (!output->enabled) { |
123 | sway_log(SWAY_DEBUG, | 123 | sway_log(SWAY_DEBUG, |
124 | "Workspace output %s is disabled, trying another one", | 124 | "Workspace output %s is disabled, trying another one", |
125 | output->wlr_output->name); | 125 | output->wlr_output->name); |
126 | output = NULL; | 126 | output = NULL; |
127 | } | 127 | } |
128 | ws = workspace_create(output, ctx->name); | 128 | ws = workspace_create(output, ctx->fallback_name); |
129 | } | 129 | } |
130 | break; | 130 | break; |
131 | case N_ROOT: | 131 | case N_ROOT: |
132 | ws = workspace_create(NULL, ctx->name); | 132 | ws = workspace_create(NULL, ctx->fallback_name); |
133 | break; | 133 | break; |
134 | } | 134 | } |
135 | 135 | ||
@@ -148,8 +148,8 @@ static void ctx_handle_node_destroy(struct wl_listener *listener, void *data) { | |||
148 | wl_list_init(&ctx->node_destroy.link); | 148 | wl_list_init(&ctx->node_destroy.link); |
149 | // We want to save this ws name to recreate later, hopefully on the | 149 | // We want to save this ws name to recreate later, hopefully on the |
150 | // same output | 150 | // same output |
151 | free(ctx->name); | 151 | free(ctx->fallback_name); |
152 | ctx->name = strdup(ws->name); | 152 | ctx->fallback_name = strdup(ws->name); |
153 | if (!ws->output || ws->output->node.destroying) { | 153 | if (!ws->output || ws->output->node.destroying) { |
154 | // If the output is being destroyed it would be pointless to track | 154 | // If the output is being destroyed it would be pointless to track |
155 | // If the output is being disabled, we'll find out if it's still | 155 | // If the output is being disabled, we'll find out if it's still |
@@ -178,21 +178,41 @@ static void token_handle_destroy(struct wl_listener *listener, void *data) { | |||
178 | launcher_ctx_destroy(ctx); | 178 | launcher_ctx_destroy(ctx); |
179 | } | 179 | } |
180 | 180 | ||
181 | struct launcher_ctx *launcher_ctx_create() { | 181 | struct launcher_ctx *launcher_ctx_create(struct wlr_xdg_activation_token_v1 *token, |
182 | struct sway_seat *seat = input_manager_current_seat(); | 182 | struct sway_node *node) { |
183 | struct sway_workspace *ws = seat_get_focused_workspace(seat); | 183 | struct launcher_ctx *ctx = calloc(1, sizeof(struct launcher_ctx)); |
184 | if (!ws) { | 184 | |
185 | sway_log(SWAY_DEBUG, "Failed to create launch context. No workspace."); | 185 | const char *fallback_name = NULL; |
186 | struct sway_workspace *ws = NULL; | ||
187 | switch (node->type) { | ||
188 | case N_CONTAINER: | ||
189 | // Unimplemented | ||
190 | free(ctx); | ||
191 | return NULL; | ||
192 | case N_WORKSPACE: | ||
193 | ws = node->sway_workspace; | ||
194 | fallback_name = ws->name; | ||
195 | break; | ||
196 | case N_OUTPUT:; | ||
197 | struct sway_output *output = node->sway_output; | ||
198 | ws = output_get_active_workspace(output); | ||
199 | fallback_name = ws ? ws->name : NULL; | ||
200 | break; | ||
201 | case N_ROOT: | ||
202 | // Unimplemented | ||
203 | free(ctx); | ||
186 | return NULL; | 204 | return NULL; |
187 | } | 205 | } |
188 | 206 | ||
189 | struct launcher_ctx *ctx = calloc(1, sizeof(struct launcher_ctx)); | 207 | if (!fallback_name) { |
190 | struct wlr_xdg_activation_token_v1 *token = | 208 | // TODO: implement a better fallback. |
191 | wlr_xdg_activation_token_v1_create(server.xdg_activation_v1); | 209 | free(ctx); |
192 | token->data = ctx; | 210 | return NULL; |
193 | ctx->name = strdup(ws->name); | 211 | } |
212 | |||
213 | ctx->fallback_name = strdup(fallback_name); | ||
194 | ctx->token = token; | 214 | ctx->token = token; |
195 | ctx->node = &ws->node; | 215 | ctx->node = node; |
196 | 216 | ||
197 | ctx->node_destroy.notify = ctx_handle_node_destroy; | 217 | ctx->node_destroy.notify = ctx_handle_node_destroy; |
198 | wl_signal_add(&ctx->node->events.destroy, &ctx->node_destroy); | 218 | wl_signal_add(&ctx->node->events.destroy, &ctx->node_destroy); |
@@ -202,6 +222,30 @@ struct launcher_ctx *launcher_ctx_create() { | |||
202 | 222 | ||
203 | wl_list_init(&ctx->link); | 223 | wl_list_init(&ctx->link); |
204 | wl_list_insert(&server.pending_launcher_ctxs, &ctx->link); | 224 | wl_list_insert(&server.pending_launcher_ctxs, &ctx->link); |
225 | |||
226 | token->data = ctx; | ||
227 | return ctx; | ||
228 | } | ||
229 | |||
230 | // Creates a context with a new token for the internal launcher | ||
231 | struct launcher_ctx *launcher_ctx_create_internal() { | ||
232 | struct sway_seat *seat = input_manager_current_seat(); | ||
233 | struct sway_workspace *ws = seat_get_focused_workspace(seat); | ||
234 | if (!ws) { | ||
235 | sway_log(SWAY_DEBUG, "Failed to create launch context. No workspace."); | ||
236 | return NULL; | ||
237 | } | ||
238 | |||
239 | struct wlr_xdg_activation_token_v1 *token = | ||
240 | wlr_xdg_activation_token_v1_create(server.xdg_activation_v1); | ||
241 | token->seat = seat->wlr_seat; | ||
242 | |||
243 | struct launcher_ctx *ctx = launcher_ctx_create(token, &ws->node); | ||
244 | if (!ctx) { | ||
245 | wlr_xdg_activation_token_v1_destroy(token); | ||
246 | return NULL; | ||
247 | } | ||
248 | |||
205 | return ctx; | 249 | return ctx; |
206 | } | 250 | } |
207 | 251 | ||