diff options
Diffstat (limited to 'sway')
-rw-r--r-- | sway/tree/container.c | 26 | ||||
-rw-r--r-- | sway/tree/layout.c | 2 | ||||
-rw-r--r-- | sway/tree/output.c | 52 | ||||
-rw-r--r-- | sway/tree/workspace.c | 59 |
4 files changed, 122 insertions, 17 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c index ca993c41..cd2c083c 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -213,6 +213,9 @@ static struct sway_container *container_workspace_destroy( | |||
213 | sway_workspace->floating->parent = NULL; | 213 | sway_workspace->floating->parent = NULL; |
214 | _container_destroy(sway_workspace->floating); | 214 | _container_destroy(sway_workspace->floating); |
215 | 215 | ||
216 | list_foreach(sway_workspace->output_priority, free); | ||
217 | list_free(sway_workspace->output_priority); | ||
218 | |||
216 | free(sway_workspace); | 219 | free(sway_workspace); |
217 | 220 | ||
218 | if (output) { | 221 | if (output) { |
@@ -234,24 +237,33 @@ static struct sway_container *container_output_destroy( | |||
234 | // program | 237 | // program |
235 | if (root_container.children->length > 1) { | 238 | if (root_container.children->length > 1) { |
236 | // Move workspace from this output to another output | 239 | // Move workspace from this output to another output |
237 | struct sway_container *other_output = | 240 | struct sway_container *fallback_output = |
238 | root_container.children->items[0]; | 241 | root_container.children->items[0]; |
239 | if (other_output == output) { | 242 | if (fallback_output == output) { |
240 | other_output = root_container.children->items[1]; | 243 | fallback_output = root_container.children->items[1]; |
241 | } | 244 | } |
242 | 245 | ||
243 | while (output->children->length) { | 246 | while (output->children->length) { |
244 | struct sway_container *workspace = output->children->items[0]; | 247 | struct sway_container *workspace = output->children->items[0]; |
248 | |||
249 | struct sway_container *new_output = | ||
250 | workspace_output_get_highest_available(workspace, output); | ||
251 | if (!new_output) { | ||
252 | new_output = fallback_output; | ||
253 | workspace_output_add_priority(workspace, new_output); | ||
254 | } | ||
255 | |||
245 | container_remove_child(workspace); | 256 | container_remove_child(workspace); |
246 | if (workspace->children->length > 0) { | 257 | if (!workspace_is_empty(workspace)) { |
247 | container_add_child(other_output, workspace); | 258 | container_add_child(new_output, workspace); |
248 | ipc_event_workspace(workspace, NULL, "move"); | 259 | ipc_event_workspace(workspace, NULL, "move"); |
249 | } else { | 260 | } else { |
250 | container_workspace_destroy(workspace); | 261 | container_workspace_destroy(workspace); |
251 | } | 262 | } |
263 | |||
264 | container_sort_workspaces(new_output); | ||
265 | arrange_output(new_output); | ||
252 | } | 266 | } |
253 | container_sort_workspaces(other_output); | ||
254 | arrange_output(other_output); | ||
255 | } | 267 | } |
256 | } | 268 | } |
257 | 269 | ||
diff --git a/sway/tree/layout.c b/sway/tree/layout.c index b54dc2fe..6d4cd088 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c | |||
@@ -183,6 +183,8 @@ void container_move_to(struct sway_container *container, | |||
183 | } | 183 | } |
184 | container_sort_workspaces(new_parent); | 184 | container_sort_workspaces(new_parent); |
185 | seat_set_focus(seat, new_parent); | 185 | seat_set_focus(seat, new_parent); |
186 | workspace_output_raise_priority(container, old_parent, new_parent); | ||
187 | ipc_event_workspace(container, NULL, "move"); | ||
186 | } | 188 | } |
187 | container_notify_subtree_changed(old_parent); | 189 | container_notify_subtree_changed(old_parent); |
188 | container_notify_subtree_changed(new_parent); | 190 | container_notify_subtree_changed(new_parent); |
diff --git a/sway/tree/output.c b/sway/tree/output.c index 8823eba0..ed7e941e 100644 --- a/sway/tree/output.c +++ b/sway/tree/output.c | |||
@@ -1,11 +1,39 @@ | |||
1 | #define _POSIX_C_SOURCE 200809L | 1 | #define _POSIX_C_SOURCE 200809L |
2 | #include <string.h> | 2 | #include <string.h> |
3 | #include <strings.h> | 3 | #include <strings.h> |
4 | #include "sway/ipc-server.h" | ||
4 | #include "sway/output.h" | 5 | #include "sway/output.h" |
6 | #include "sway/tree/arrange.h" | ||
5 | #include "sway/tree/output.h" | 7 | #include "sway/tree/output.h" |
6 | #include "sway/tree/workspace.h" | 8 | #include "sway/tree/workspace.h" |
7 | #include "log.h" | 9 | #include "log.h" |
8 | 10 | ||
11 | static void restore_workspaces(struct sway_container *output) { | ||
12 | for (int i = 0; i < root_container.children->length; i++) { | ||
13 | struct sway_container *other = root_container.children->items[i]; | ||
14 | if (other == output) { | ||
15 | continue; | ||
16 | } | ||
17 | |||
18 | for (int j = 0; j < other->children->length; j++) { | ||
19 | struct sway_container *ws = other->children->items[j]; | ||
20 | struct sway_container *highest = | ||
21 | workspace_output_get_highest_available(ws, NULL); | ||
22 | if (highest == output) { | ||
23 | container_remove_child(ws); | ||
24 | container_add_child(output, ws); | ||
25 | ipc_event_workspace(ws, NULL, "move"); | ||
26 | j--; | ||
27 | } | ||
28 | } | ||
29 | |||
30 | arrange_output(other); | ||
31 | } | ||
32 | |||
33 | container_sort_workspaces(output); | ||
34 | arrange_output(output); | ||
35 | } | ||
36 | |||
9 | struct sway_container *output_create( | 37 | struct sway_container *output_create( |
10 | struct sway_output *sway_output) { | 38 | struct sway_output *sway_output) { |
11 | const char *name = sway_output->wlr_output->name; | 39 | const char *name = sway_output->wlr_output->name; |
@@ -56,19 +84,23 @@ struct sway_container *output_create( | |||
56 | output->width = size.width; | 84 | output->width = size.width; |
57 | output->height = size.height; | 85 | output->height = size.height; |
58 | 86 | ||
59 | // Create workspace | 87 | restore_workspaces(output); |
60 | char *ws_name = workspace_next_name(output->name); | 88 | |
61 | wlr_log(L_DEBUG, "Creating default workspace %s", ws_name); | 89 | if (!output->children->length) { |
62 | struct sway_container *ws = workspace_create(output, ws_name); | 90 | // Create workspace |
63 | // Set each seat's focus if not already set | 91 | char *ws_name = workspace_next_name(output->name); |
64 | struct sway_seat *seat = NULL; | 92 | wlr_log(L_DEBUG, "Creating default workspace %s", ws_name); |
65 | wl_list_for_each(seat, &input_manager->seats, link) { | 93 | struct sway_container *ws = workspace_create(output, ws_name); |
66 | if (!seat->has_focus) { | 94 | // Set each seat's focus if not already set |
67 | seat_set_focus(seat, ws); | 95 | struct sway_seat *seat = NULL; |
96 | wl_list_for_each(seat, &input_manager->seats, link) { | ||
97 | if (!seat->has_focus) { | ||
98 | seat_set_focus(seat, ws); | ||
99 | } | ||
68 | } | 100 | } |
101 | free(ws_name); | ||
69 | } | 102 | } |
70 | 103 | ||
71 | free(ws_name); | ||
72 | container_create_notify(output); | 104 | container_create_notify(output); |
73 | return output; | 105 | return output; |
74 | } | 106 | } |
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 3c42e259..9ba210fd 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c | |||
@@ -68,7 +68,9 @@ struct sway_container *workspace_create(struct sway_container *output, | |||
68 | swayws->floating = container_create(C_CONTAINER); | 68 | swayws->floating = container_create(C_CONTAINER); |
69 | swayws->floating->parent = swayws->swayc; | 69 | swayws->floating->parent = swayws->swayc; |
70 | swayws->floating->layout = L_FLOATING; | 70 | swayws->floating->layout = L_FLOATING; |
71 | swayws->output_priority = create_list(); | ||
71 | workspace->sway_workspace = swayws; | 72 | workspace->sway_workspace = swayws; |
73 | workspace_output_add_priority(workspace, output); | ||
72 | 74 | ||
73 | container_add_child(output, workspace); | 75 | container_add_child(output, workspace); |
74 | container_sort_workspaces(output); | 76 | container_sort_workspaces(output); |
@@ -454,3 +456,60 @@ bool workspace_is_empty(struct sway_container *ws) { | |||
454 | } | 456 | } |
455 | return true; | 457 | return true; |
456 | } | 458 | } |
459 | |||
460 | static int find_output(const void *id1, const void *id2) { | ||
461 | return strcmp(id1, id2) ? 0 : 1; | ||
462 | } | ||
463 | |||
464 | void workspace_output_raise_priority(struct sway_container *workspace, | ||
465 | struct sway_container *old_output, struct sway_container *output) { | ||
466 | struct sway_workspace *ws = workspace->sway_workspace; | ||
467 | |||
468 | int old_index = list_seq_find(ws->output_priority, find_output, | ||
469 | old_output->name); | ||
470 | if (old_index < 0) { | ||
471 | return; | ||
472 | } | ||
473 | |||
474 | int new_index = list_seq_find(ws->output_priority, find_output, | ||
475 | output->name); | ||
476 | if (new_index < 0) { | ||
477 | list_insert(ws->output_priority, old_index, strdup(output->name)); | ||
478 | } else if (new_index > old_index) { | ||
479 | char *name = ws->output_priority->items[new_index]; | ||
480 | list_del(ws->output_priority, new_index); | ||
481 | list_insert(ws->output_priority, old_index, name); | ||
482 | } | ||
483 | } | ||
484 | |||
485 | void workspace_output_add_priority(struct sway_container *workspace, | ||
486 | struct sway_container *output) { | ||
487 | int index = list_seq_find(workspace->sway_workspace->output_priority, | ||
488 | find_output, output->name); | ||
489 | if (index < 0) { | ||
490 | list_add(workspace->sway_workspace->output_priority, | ||
491 | strdup(output->name)); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | static bool _output_by_name(struct sway_container *output, void *data) { | ||
496 | return output->type == C_OUTPUT && strcasecmp(output->name, data) == 0; | ||
497 | } | ||
498 | |||
499 | struct sway_container *workspace_output_get_highest_available( | ||
500 | struct sway_container *ws, struct sway_container *exclude) { | ||
501 | for (int i = 0; i < ws->sway_workspace->output_priority->length; i++) { | ||
502 | char *name = ws->sway_workspace->output_priority->items[i]; | ||
503 | if (exclude && strcasecmp(name, exclude->name) == 0) { | ||
504 | continue; | ||
505 | } | ||
506 | |||
507 | struct sway_container *output = container_find(&root_container, | ||
508 | _output_by_name, name); | ||
509 | if (output) { | ||
510 | return output; | ||
511 | } | ||
512 | } | ||
513 | |||
514 | return NULL; | ||
515 | } | ||