diff options
Diffstat (limited to 'sway/tree/workspace.c')
-rw-r--r-- | sway/tree/workspace.c | 124 |
1 files changed, 55 insertions, 69 deletions
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 8077de2e..316f01e4 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c | |||
@@ -14,6 +14,58 @@ | |||
14 | #include "log.h" | 14 | #include "log.h" |
15 | #include "util.h" | 15 | #include "util.h" |
16 | 16 | ||
17 | static struct sway_container *get_workspace_initial_output(const char *name) { | ||
18 | struct sway_container *parent; | ||
19 | // Search for workspace<->output pair | ||
20 | int e = config->workspace_outputs->length; | ||
21 | for (int i = 0; i < config->workspace_outputs->length; ++i) { | ||
22 | struct workspace_output *wso = config->workspace_outputs->items[i]; | ||
23 | if (strcasecmp(wso->workspace, name) == 0) { | ||
24 | // Find output to use if it exists | ||
25 | e = root_container.children->length; | ||
26 | for (i = 0; i < e; ++i) { | ||
27 | parent = root_container.children->items[i]; | ||
28 | if (strcmp(parent->name, wso->output) == 0) { | ||
29 | return parent; | ||
30 | } | ||
31 | } | ||
32 | break; | ||
33 | } | ||
34 | } | ||
35 | // Otherwise put it on the focused output | ||
36 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
37 | struct sway_container *focus = | ||
38 | seat_get_focus_inactive(seat, &root_container); | ||
39 | parent = focus; | ||
40 | parent = container_parent(parent, C_OUTPUT); | ||
41 | return parent; | ||
42 | } | ||
43 | |||
44 | struct sway_container *workspace_create(struct sway_container *output, | ||
45 | const char *name) { | ||
46 | if (output == NULL) { | ||
47 | output = get_workspace_initial_output(name); | ||
48 | } | ||
49 | |||
50 | wlr_log(L_DEBUG, "Added workspace %s for output %s", name, output->name); | ||
51 | struct sway_container *workspace = container_create(C_WORKSPACE); | ||
52 | |||
53 | workspace->x = output->x; | ||
54 | workspace->y = output->y; | ||
55 | workspace->width = output->width; | ||
56 | workspace->height = output->height; | ||
57 | workspace->name = !name ? NULL : strdup(name); | ||
58 | workspace->prev_layout = L_NONE; | ||
59 | workspace->layout = container_get_default_layout(output); | ||
60 | workspace->workspace_layout = workspace->layout; | ||
61 | |||
62 | container_add_child(output, workspace); | ||
63 | container_sort_workspaces(output); | ||
64 | container_create_notify(workspace); | ||
65 | |||
66 | return workspace; | ||
67 | } | ||
68 | |||
17 | char *prev_workspace_name = NULL; | 69 | char *prev_workspace_name = NULL; |
18 | struct workspace_by_number_data { | 70 | struct workspace_by_number_data { |
19 | int len; | 71 | int len; |
@@ -197,74 +249,6 @@ struct sway_container *workspace_by_name(const char *name) { | |||
197 | } | 249 | } |
198 | } | 250 | } |
199 | 251 | ||
200 | struct sway_container *workspace_create(const char *name) { | ||
201 | struct sway_container *parent; | ||
202 | // Search for workspace<->output pair | ||
203 | int i, e = config->workspace_outputs->length; | ||
204 | for (i = 0; i < e; ++i) { | ||
205 | struct workspace_output *wso = config->workspace_outputs->items[i]; | ||
206 | if (strcasecmp(wso->workspace, name) == 0) { | ||
207 | // Find output to use if it exists | ||
208 | e = root_container.children->length; | ||
209 | for (i = 0; i < e; ++i) { | ||
210 | parent = root_container.children->items[i]; | ||
211 | if (strcmp(parent->name, wso->output) == 0) { | ||
212 | return container_workspace_create(parent, name); | ||
213 | } | ||
214 | } | ||
215 | break; | ||
216 | } | ||
217 | } | ||
218 | // Otherwise create a new one | ||
219 | struct sway_seat *seat = input_manager_current_seat(input_manager); | ||
220 | struct sway_container *focus = | ||
221 | seat_get_focus_inactive(seat, &root_container); | ||
222 | parent = focus; | ||
223 | parent = container_parent(parent, C_OUTPUT); | ||
224 | struct sway_container *new_ws = container_workspace_create(parent, name); | ||
225 | ipc_event_workspace(NULL, new_ws, "init"); | ||
226 | return new_ws; | ||
227 | } | ||
228 | |||
229 | struct sway_container *container_workspace_destroy( | ||
230 | struct sway_container *workspace) { | ||
231 | if (!sway_assert(workspace, "cannot destroy null workspace")) { | ||
232 | return NULL; | ||
233 | } | ||
234 | |||
235 | // Do not destroy this if it's the last workspace on this output | ||
236 | struct sway_container *output = container_parent(workspace, C_OUTPUT); | ||
237 | if (output && output->children->length == 1) { | ||
238 | return NULL; | ||
239 | } | ||
240 | |||
241 | struct sway_container *parent = workspace->parent; | ||
242 | if (workspace->children->length == 0) { | ||
243 | // destroy the WS if there are no children (TODO check for floating) | ||
244 | wlr_log(L_DEBUG, "destroying workspace '%s'", workspace->name); | ||
245 | ipc_event_workspace(workspace, NULL, "empty"); | ||
246 | } else { | ||
247 | // Move children to a different workspace on this output | ||
248 | struct sway_container *new_workspace = NULL; | ||
249 | // TODO move floating | ||
250 | for (int i = 0; i < output->children->length; i++) { | ||
251 | if (output->children->items[i] != workspace) { | ||
252 | new_workspace = output->children->items[i]; | ||
253 | break; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | wlr_log(L_DEBUG, "moving children to different workspace '%s' -> '%s'", | ||
258 | workspace->name, new_workspace->name); | ||
259 | for (int i = 0; i < workspace->children->length; i++) { | ||
260 | container_move_to(workspace->children->items[i], new_workspace); | ||
261 | } | ||
262 | } | ||
263 | |||
264 | container_destroy(workspace); | ||
265 | return parent; | ||
266 | } | ||
267 | |||
268 | /** | 252 | /** |
269 | * Get the previous or next workspace on the specified output. Wraps around at | 253 | * Get the previous or next workspace on the specified output. Wraps around at |
270 | * the end and beginning. If next is false, the previous workspace is returned, | 254 | * the end and beginning. If next is false, the previous workspace is returned, |
@@ -376,7 +360,9 @@ bool workspace_switch(struct sway_container *workspace) { | |||
376 | && active_ws == workspace | 360 | && active_ws == workspace |
377 | && prev_workspace_name) { | 361 | && prev_workspace_name) { |
378 | struct sway_container *new_ws = workspace_by_name(prev_workspace_name); | 362 | struct sway_container *new_ws = workspace_by_name(prev_workspace_name); |
379 | workspace = new_ws ? new_ws : workspace_create(prev_workspace_name); | 363 | workspace = new_ws ? |
364 | new_ws : | ||
365 | workspace_create(NULL, prev_workspace_name); | ||
380 | } | 366 | } |
381 | 367 | ||
382 | if (!prev_workspace_name || (strcmp(prev_workspace_name, active_ws->name) | 368 | if (!prev_workspace_name || (strcmp(prev_workspace_name, active_ws->name) |