diff options
Diffstat (limited to 'sway/tree/workspace.c')
-rw-r--r-- | sway/tree/workspace.c | 175 |
1 files changed, 93 insertions, 82 deletions
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index 921b7d19..a68dc927 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c | |||
@@ -1,4 +1,3 @@ | |||
1 | #define _POSIX_C_SOURCE 200809 | ||
2 | #include <ctype.h> | 1 | #include <ctype.h> |
3 | #include <limits.h> | 2 | #include <limits.h> |
4 | #include <stdbool.h> | 3 | #include <stdbool.h> |
@@ -48,14 +47,16 @@ struct sway_output *workspace_get_initial_output(const char *name) { | |||
48 | if (focus && focus->type == N_WORKSPACE) { | 47 | if (focus && focus->type == N_WORKSPACE) { |
49 | return focus->sway_workspace->output; | 48 | return focus->sway_workspace->output; |
50 | } else if (focus && focus->type == N_CONTAINER) { | 49 | } else if (focus && focus->type == N_CONTAINER) { |
51 | return focus->sway_container->workspace->output; | 50 | return focus->sway_container->pending.workspace->output; |
52 | } | 51 | } |
53 | // Fallback to the first output or noop output for headless | 52 | // Fallback to the first output or the headless output |
54 | return root->outputs->length ? root->outputs->items[0] : root->noop_output; | 53 | return root->outputs->length ? root->outputs->items[0] : root->fallback_output; |
55 | } | 54 | } |
56 | 55 | ||
57 | struct sway_workspace *workspace_create(struct sway_output *output, | 56 | struct sway_workspace *workspace_create(struct sway_output *output, |
58 | const char *name) { | 57 | const char *name) { |
58 | sway_assert(name, "NULL name given to workspace_create"); | ||
59 | |||
59 | if (output == NULL) { | 60 | if (output == NULL) { |
60 | output = workspace_get_initial_output(name); | 61 | output = workspace_get_initial_output(name); |
61 | } | 62 | } |
@@ -69,7 +70,19 @@ struct sway_workspace *workspace_create(struct sway_output *output, | |||
69 | return NULL; | 70 | return NULL; |
70 | } | 71 | } |
71 | node_init(&ws->node, N_WORKSPACE, ws); | 72 | node_init(&ws->node, N_WORKSPACE, ws); |
72 | ws->name = name ? strdup(name) : NULL; | 73 | |
74 | bool failed = false; | ||
75 | ws->layers.tiling = alloc_scene_tree(root->staging, &failed); | ||
76 | ws->layers.fullscreen = alloc_scene_tree(root->staging, &failed); | ||
77 | |||
78 | if (failed) { | ||
79 | wlr_scene_node_destroy(&ws->layers.tiling->node); | ||
80 | wlr_scene_node_destroy(&ws->layers.fullscreen->node); | ||
81 | free(ws); | ||
82 | return NULL; | ||
83 | } | ||
84 | |||
85 | ws->name = strdup(name); | ||
73 | ws->prev_split_layout = L_NONE; | 86 | ws->prev_split_layout = L_NONE; |
74 | ws->layout = output_get_default_layout(output); | 87 | ws->layout = output_get_default_layout(output); |
75 | ws->floating = create_list(); | 88 | ws->floating = create_list(); |
@@ -114,7 +127,7 @@ struct sway_workspace *workspace_create(struct sway_output *output, | |||
114 | output_sort_workspaces(output); | 127 | output_sort_workspaces(output); |
115 | 128 | ||
116 | ipc_event_workspace(NULL, ws, "init"); | 129 | ipc_event_workspace(NULL, ws, "init"); |
117 | wl_signal_emit(&root->events.new_node, &ws->node); | 130 | wl_signal_emit_mutable(&root->events.new_node, &ws->node); |
118 | 131 | ||
119 | return ws; | 132 | return ws; |
120 | } | 133 | } |
@@ -129,6 +142,11 @@ void workspace_destroy(struct sway_workspace *workspace) { | |||
129 | return; | 142 | return; |
130 | } | 143 | } |
131 | 144 | ||
145 | scene_node_disown_children(workspace->layers.tiling); | ||
146 | scene_node_disown_children(workspace->layers.fullscreen); | ||
147 | wlr_scene_node_destroy(&workspace->layers.tiling->node); | ||
148 | wlr_scene_node_destroy(&workspace->layers.fullscreen->node); | ||
149 | |||
132 | free(workspace->name); | 150 | free(workspace->name); |
133 | free(workspace->representation); | 151 | free(workspace->representation); |
134 | list_free_items_and_destroy(workspace->output_priority); | 152 | list_free_items_and_destroy(workspace->output_priority); |
@@ -142,7 +160,7 @@ void workspace_destroy(struct sway_workspace *workspace) { | |||
142 | void workspace_begin_destroy(struct sway_workspace *workspace) { | 160 | void workspace_begin_destroy(struct sway_workspace *workspace) { |
143 | sway_log(SWAY_DEBUG, "Destroying workspace '%s'", workspace->name); | 161 | sway_log(SWAY_DEBUG, "Destroying workspace '%s'", workspace->name); |
144 | ipc_event_workspace(NULL, workspace, "empty"); // intentional | 162 | ipc_event_workspace(NULL, workspace, "empty"); // intentional |
145 | wl_signal_emit(&workspace->node.events.destroy, &workspace->node); | 163 | wl_signal_emit_mutable(&workspace->node.events.destroy, &workspace->node); |
146 | 164 | ||
147 | if (workspace->output) { | 165 | if (workspace->output) { |
148 | workspace_detach(workspace); | 166 | workspace_detach(workspace); |
@@ -174,22 +192,16 @@ void workspace_consider_destroy(struct sway_workspace *ws) { | |||
174 | static bool workspace_valid_on_output(const char *output_name, | 192 | static bool workspace_valid_on_output(const char *output_name, |
175 | const char *ws_name) { | 193 | const char *ws_name) { |
176 | struct workspace_config *wsc = workspace_find_config(ws_name); | 194 | struct workspace_config *wsc = workspace_find_config(ws_name); |
177 | char identifier[128]; | ||
178 | struct sway_output *output = output_by_name_or_id(output_name); | 195 | struct sway_output *output = output_by_name_or_id(output_name); |
179 | if (!output) { | 196 | if (!output) { |
180 | return false; | 197 | return false; |
181 | } | 198 | } |
182 | output_name = output->wlr_output->name; | ||
183 | output_get_identifier(identifier, sizeof(identifier), output); | ||
184 | |||
185 | if (!wsc) { | 199 | if (!wsc) { |
186 | return true; | 200 | return true; |
187 | } | 201 | } |
188 | 202 | ||
189 | for (int i = 0; i < wsc->outputs->length; i++) { | 203 | for (int i = 0; i < wsc->outputs->length; i++) { |
190 | if (strcmp(wsc->outputs->items[i], "*") == 0 || | 204 | if (output_match_name_or_id(output, wsc->outputs->items[i])) { |
191 | strcmp(wsc->outputs->items[i], output_name) == 0 || | ||
192 | strcmp(wsc->outputs->items[i], identifier) == 0) { | ||
193 | return true; | 205 | return true; |
194 | } | 206 | } |
195 | } | 207 | } |
@@ -222,10 +234,8 @@ static void workspace_name_from_binding(const struct sway_binding * binding, | |||
222 | // not a command about workspaces | 234 | // not a command about workspaces |
223 | if (strcmp(_target, "next") == 0 || | 235 | if (strcmp(_target, "next") == 0 || |
224 | strcmp(_target, "prev") == 0 || | 236 | strcmp(_target, "prev") == 0 || |
225 | strncmp(_target, "next_on_output", | 237 | strcmp(_target, "next_on_output") == 0 || |
226 | strlen("next_on_output")) == 0 || | 238 | strcmp(_target, "prev_on_output") == 0 || |
227 | strncmp(_target, "prev_on_output", | ||
228 | strlen("next_on_output")) == 0 || | ||
229 | strcmp(_target, "number") == 0 || | 239 | strcmp(_target, "number") == 0 || |
230 | strcmp(_target, "back_and_forth") == 0 || | 240 | strcmp(_target, "back_and_forth") == 0 || |
231 | strcmp(_target, "current") == 0) { | 241 | strcmp(_target, "current") == 0) { |
@@ -286,13 +296,10 @@ char *workspace_next_name(const char *output_name) { | |||
286 | // assignments primarily, falling back to bindings and numbers. | 296 | // assignments primarily, falling back to bindings and numbers. |
287 | struct sway_mode *mode = config->current_mode; | 297 | struct sway_mode *mode = config->current_mode; |
288 | 298 | ||
289 | char identifier[128]; | ||
290 | struct sway_output *output = output_by_name_or_id(output_name); | 299 | struct sway_output *output = output_by_name_or_id(output_name); |
291 | if (!output) { | 300 | if (!output) { |
292 | return NULL; | 301 | return NULL; |
293 | } | 302 | } |
294 | output_name = output->wlr_output->name; | ||
295 | output_get_identifier(identifier, sizeof(identifier), output); | ||
296 | 303 | ||
297 | int order = INT_MAX; | 304 | int order = INT_MAX; |
298 | char *target = NULL; | 305 | char *target = NULL; |
@@ -312,9 +319,7 @@ char *workspace_next_name(const char *output_name) { | |||
312 | } | 319 | } |
313 | bool found = false; | 320 | bool found = false; |
314 | for (int j = 0; j < wsc->outputs->length; ++j) { | 321 | for (int j = 0; j < wsc->outputs->length; ++j) { |
315 | if (strcmp(wsc->outputs->items[j], "*") == 0 || | 322 | if (output_match_name_or_id(output, wsc->outputs->items[j])) { |
316 | strcmp(wsc->outputs->items[j], output_name) == 0 || | ||
317 | strcmp(wsc->outputs->items[j], identifier) == 0) { | ||
318 | found = true; | 323 | found = true; |
319 | free(target); | 324 | free(target); |
320 | target = strdup(wsc->workspace); | 325 | target = strdup(wsc->workspace); |
@@ -363,11 +368,11 @@ struct sway_workspace *workspace_by_name(const char *name) { | |||
363 | if (current && strcmp(name, "prev") == 0) { | 368 | if (current && strcmp(name, "prev") == 0) { |
364 | return workspace_prev(current); | 369 | return workspace_prev(current); |
365 | } else if (current && strcmp(name, "prev_on_output") == 0) { | 370 | } else if (current && strcmp(name, "prev_on_output") == 0) { |
366 | return workspace_output_prev(current, false); | 371 | return workspace_output_prev(current); |
367 | } else if (current && strcmp(name, "next") == 0) { | 372 | } else if (current && strcmp(name, "next") == 0) { |
368 | return workspace_next(current); | 373 | return workspace_next(current); |
369 | } else if (current && strcmp(name, "next_on_output") == 0) { | 374 | } else if (current && strcmp(name, "next_on_output") == 0) { |
370 | return workspace_output_next(current, false); | 375 | return workspace_output_next(current); |
371 | } else if (strcmp(name, "current") == 0) { | 376 | } else if (strcmp(name, "current") == 0) { |
372 | return current; | 377 | return current; |
373 | } else if (strcasecmp(name, "back_and_forth") == 0) { | 378 | } else if (strcasecmp(name, "back_and_forth") == 0) { |
@@ -530,7 +535,7 @@ struct sway_workspace *workspace_next(struct sway_workspace *workspace) { | |||
530 | * otherwise the next one is returned. | 535 | * otherwise the next one is returned. |
531 | */ | 536 | */ |
532 | static struct sway_workspace *workspace_output_prev_next_impl( | 537 | static struct sway_workspace *workspace_output_prev_next_impl( |
533 | struct sway_output *output, int dir, bool create) { | 538 | struct sway_output *output, int dir) { |
534 | struct sway_seat *seat = input_manager_current_seat(); | 539 | struct sway_seat *seat = input_manager_current_seat(); |
535 | struct sway_workspace *workspace = seat_get_focused_workspace(seat); | 540 | struct sway_workspace *workspace = seat_get_focused_workspace(seat); |
536 | if (!workspace) { | 541 | if (!workspace) { |
@@ -540,46 +545,43 @@ static struct sway_workspace *workspace_output_prev_next_impl( | |||
540 | } | 545 | } |
541 | 546 | ||
542 | int index = list_find(output->workspaces, workspace); | 547 | int index = list_find(output->workspaces, workspace); |
543 | if (!workspace_is_empty(workspace) && create && | ||
544 | (index + dir < 0 || index + dir == output->workspaces->length)) { | ||
545 | struct sway_output *output = workspace->output; | ||
546 | char *next = workspace_next_name(output->wlr_output->name); | ||
547 | workspace_create(output, next); | ||
548 | free(next); | ||
549 | } | ||
550 | size_t new_index = wrap(index + dir, output->workspaces->length); | 548 | size_t new_index = wrap(index + dir, output->workspaces->length); |
551 | return output->workspaces->items[new_index]; | 549 | return output->workspaces->items[new_index]; |
552 | } | 550 | } |
553 | 551 | ||
554 | struct sway_workspace *workspace_output_next( | 552 | |
555 | struct sway_workspace *current, bool create) { | 553 | struct sway_workspace *workspace_output_next(struct sway_workspace *current) { |
556 | return workspace_output_prev_next_impl(current->output, 1, create); | 554 | return workspace_output_prev_next_impl(current->output, 1); |
557 | } | 555 | } |
558 | 556 | ||
559 | struct sway_workspace *workspace_output_prev( | 557 | struct sway_workspace *workspace_output_prev(struct sway_workspace *current) { |
560 | struct sway_workspace *current, bool create) { | 558 | return workspace_output_prev_next_impl(current->output, -1); |
561 | return workspace_output_prev_next_impl(current->output, -1, create); | ||
562 | } | 559 | } |
563 | 560 | ||
564 | bool workspace_switch(struct sway_workspace *workspace, | 561 | struct sway_workspace *workspace_auto_back_and_forth( |
565 | bool no_auto_back_and_forth) { | 562 | struct sway_workspace *workspace) { |
566 | struct sway_seat *seat = input_manager_current_seat(); | 563 | struct sway_seat *seat = input_manager_current_seat(); |
567 | struct sway_workspace *active_ws = NULL; | 564 | struct sway_workspace *active_ws = NULL; |
568 | struct sway_node *focus = seat_get_focus_inactive(seat, &root->node); | 565 | struct sway_node *focus = seat_get_focus_inactive(seat, &root->node); |
569 | if (focus && focus->type == N_WORKSPACE) { | 566 | if (focus && focus->type == N_WORKSPACE) { |
570 | active_ws = focus->sway_workspace; | 567 | active_ws = focus->sway_workspace; |
571 | } else if (focus && focus->type == N_CONTAINER) { | 568 | } else if (focus && focus->type == N_CONTAINER) { |
572 | active_ws = focus->sway_container->workspace; | 569 | active_ws = focus->sway_container->pending.workspace; |
573 | } | 570 | } |
574 | 571 | ||
575 | if (!no_auto_back_and_forth && config->auto_back_and_forth && active_ws | 572 | if (config->auto_back_and_forth && active_ws && active_ws == workspace && |
576 | && active_ws == workspace && seat->prev_workspace_name) { | 573 | seat->prev_workspace_name) { |
577 | struct sway_workspace *new_ws = | 574 | struct sway_workspace *new_ws = |
578 | workspace_by_name(seat->prev_workspace_name); | 575 | workspace_by_name(seat->prev_workspace_name); |
579 | workspace = new_ws ? | 576 | workspace = new_ws ? |
580 | new_ws : | 577 | new_ws : |
581 | workspace_create(NULL, seat->prev_workspace_name); | 578 | workspace_create(NULL, seat->prev_workspace_name); |
582 | } | 579 | } |
580 | return workspace; | ||
581 | } | ||
582 | |||
583 | bool workspace_switch(struct sway_workspace *workspace) { | ||
584 | struct sway_seat *seat = input_manager_current_seat(); | ||
583 | 585 | ||
584 | sway_log(SWAY_DEBUG, "Switching to workspace %p:%s", | 586 | sway_log(SWAY_DEBUG, "Switching to workspace %p:%s", |
585 | workspace, workspace->name); | 587 | workspace, workspace->name); |
@@ -657,15 +659,9 @@ void workspace_output_add_priority(struct sway_workspace *workspace, | |||
657 | 659 | ||
658 | struct sway_output *workspace_output_get_highest_available( | 660 | struct sway_output *workspace_output_get_highest_available( |
659 | struct sway_workspace *ws, struct sway_output *exclude) { | 661 | struct sway_workspace *ws, struct sway_output *exclude) { |
660 | char exclude_id[128] = {'\0'}; | ||
661 | if (exclude) { | ||
662 | output_get_identifier(exclude_id, sizeof(exclude_id), exclude); | ||
663 | } | ||
664 | |||
665 | for (int i = 0; i < ws->output_priority->length; i++) { | 662 | for (int i = 0; i < ws->output_priority->length; i++) { |
666 | char *name = ws->output_priority->items[i]; | 663 | const char *name = ws->output_priority->items[i]; |
667 | if (exclude && (strcmp(name, exclude->wlr_output->name) == 0 | 664 | if (exclude && output_match_name_or_id(exclude, name)) { |
668 | || strcmp(name, exclude_id) == 0)) { | ||
669 | continue; | 665 | continue; |
670 | } | 666 | } |
671 | 667 | ||
@@ -689,7 +685,6 @@ void workspace_detect_urgent(struct sway_workspace *workspace) { | |||
689 | if (workspace->urgent != new_urgent) { | 685 | if (workspace->urgent != new_urgent) { |
690 | workspace->urgent = new_urgent; | 686 | workspace->urgent = new_urgent; |
691 | ipc_event_workspace(NULL, workspace, "urgent"); | 687 | ipc_event_workspace(NULL, workspace, "urgent"); |
692 | output_damage_whole(workspace->output); | ||
693 | } | 688 | } |
694 | } | 689 | } |
695 | 690 | ||
@@ -736,13 +731,13 @@ struct sway_container *workspace_find_container(struct sway_workspace *ws, | |||
736 | } | 731 | } |
737 | 732 | ||
738 | static void set_workspace(struct sway_container *container, void *data) { | 733 | static void set_workspace(struct sway_container *container, void *data) { |
739 | container->workspace = container->parent->workspace; | 734 | container->pending.workspace = container->pending.parent->pending.workspace; |
740 | } | 735 | } |
741 | 736 | ||
742 | static void workspace_attach_tiling(struct sway_workspace *ws, | 737 | static void workspace_attach_tiling(struct sway_workspace *ws, |
743 | struct sway_container *con) { | 738 | struct sway_container *con) { |
744 | list_add(ws->tiling, con); | 739 | list_add(ws->tiling, con); |
745 | con->workspace = ws; | 740 | con->pending.workspace = ws; |
746 | container_for_each_child(con, set_workspace, NULL); | 741 | container_for_each_child(con, set_workspace, NULL); |
747 | container_handle_fullscreen_reparent(con); | 742 | container_handle_fullscreen_reparent(con); |
748 | workspace_update_representation(ws); | 743 | workspace_update_representation(ws); |
@@ -753,7 +748,7 @@ static void workspace_attach_tiling(struct sway_workspace *ws, | |||
753 | struct sway_container *workspace_wrap_children(struct sway_workspace *ws) { | 748 | struct sway_container *workspace_wrap_children(struct sway_workspace *ws) { |
754 | struct sway_container *fs = ws->fullscreen; | 749 | struct sway_container *fs = ws->fullscreen; |
755 | struct sway_container *middle = container_create(NULL); | 750 | struct sway_container *middle = container_create(NULL); |
756 | middle->layout = ws->layout; | 751 | middle->pending.layout = ws->layout; |
757 | while (ws->tiling->length) { | 752 | while (ws->tiling->length) { |
758 | struct sway_container *child = ws->tiling->items[0]; | 753 | struct sway_container *child = ws->tiling->items[0]; |
759 | container_detach(child); | 754 | container_detach(child); |
@@ -771,9 +766,9 @@ void workspace_unwrap_children(struct sway_workspace *ws, | |||
771 | return; | 766 | return; |
772 | } | 767 | } |
773 | 768 | ||
774 | ws->layout = wrap->layout; | 769 | ws->layout = wrap->pending.layout; |
775 | while (wrap->children->length) { | 770 | while (wrap->pending.children->length) { |
776 | struct sway_container *child = wrap->children->items[0]; | 771 | struct sway_container *child = wrap->pending.children->items[0]; |
777 | container_detach(child); | 772 | container_detach(child); |
778 | workspace_add_tiling(ws, child); | 773 | workspace_add_tiling(ws, child); |
779 | } | 774 | } |
@@ -793,14 +788,18 @@ void workspace_detach(struct sway_workspace *workspace) { | |||
793 | 788 | ||
794 | struct sway_container *workspace_add_tiling(struct sway_workspace *workspace, | 789 | struct sway_container *workspace_add_tiling(struct sway_workspace *workspace, |
795 | struct sway_container *con) { | 790 | struct sway_container *con) { |
796 | if (con->workspace) { | 791 | if (con->pending.workspace) { |
792 | struct sway_container *old_parent = con->pending.parent; | ||
797 | container_detach(con); | 793 | container_detach(con); |
794 | if (old_parent) { | ||
795 | container_reap_empty(old_parent); | ||
796 | } | ||
798 | } | 797 | } |
799 | if (config->default_layout != L_NONE) { | 798 | if (config->default_layout != L_NONE) { |
800 | con = container_split(con, config->default_layout); | 799 | con = container_split(con, config->default_layout); |
801 | } | 800 | } |
802 | list_add(workspace->tiling, con); | 801 | list_add(workspace->tiling, con); |
803 | con->workspace = workspace; | 802 | con->pending.workspace = workspace; |
804 | container_for_each_child(con, set_workspace, NULL); | 803 | container_for_each_child(con, set_workspace, NULL); |
805 | container_handle_fullscreen_reparent(con); | 804 | container_handle_fullscreen_reparent(con); |
806 | workspace_update_representation(workspace); | 805 | workspace_update_representation(workspace); |
@@ -811,11 +810,11 @@ struct sway_container *workspace_add_tiling(struct sway_workspace *workspace, | |||
811 | 810 | ||
812 | void workspace_add_floating(struct sway_workspace *workspace, | 811 | void workspace_add_floating(struct sway_workspace *workspace, |
813 | struct sway_container *con) { | 812 | struct sway_container *con) { |
814 | if (con->workspace) { | 813 | if (con->pending.workspace) { |
815 | container_detach(con); | 814 | container_detach(con); |
816 | } | 815 | } |
817 | list_add(workspace->floating, con); | 816 | list_add(workspace->floating, con); |
818 | con->workspace = workspace; | 817 | con->pending.workspace = workspace; |
819 | container_for_each_child(con, set_workspace, NULL); | 818 | container_for_each_child(con, set_workspace, NULL); |
820 | container_handle_fullscreen_reparent(con); | 819 | container_handle_fullscreen_reparent(con); |
821 | node_set_dirty(&workspace->node); | 820 | node_set_dirty(&workspace->node); |
@@ -825,7 +824,7 @@ void workspace_add_floating(struct sway_workspace *workspace, | |||
825 | void workspace_insert_tiling_direct(struct sway_workspace *workspace, | 824 | void workspace_insert_tiling_direct(struct sway_workspace *workspace, |
826 | struct sway_container *con, int index) { | 825 | struct sway_container *con, int index) { |
827 | list_insert(workspace->tiling, index, con); | 826 | list_insert(workspace->tiling, index, con); |
828 | con->workspace = workspace; | 827 | con->pending.workspace = workspace; |
829 | container_for_each_child(con, set_workspace, NULL); | 828 | container_for_each_child(con, set_workspace, NULL); |
830 | container_handle_fullscreen_reparent(con); | 829 | container_handle_fullscreen_reparent(con); |
831 | workspace_update_representation(workspace); | 830 | workspace_update_representation(workspace); |
@@ -835,7 +834,7 @@ void workspace_insert_tiling_direct(struct sway_workspace *workspace, | |||
835 | 834 | ||
836 | struct sway_container *workspace_insert_tiling(struct sway_workspace *workspace, | 835 | struct sway_container *workspace_insert_tiling(struct sway_workspace *workspace, |
837 | struct sway_container *con, int index) { | 836 | struct sway_container *con, int index) { |
838 | if (con->workspace) { | 837 | if (con->pending.workspace) { |
839 | container_detach(con); | 838 | container_detach(con); |
840 | } | 839 | } |
841 | if (config->default_layout != L_NONE) { | 840 | if (config->default_layout != L_NONE) { |
@@ -845,24 +844,36 @@ struct sway_container *workspace_insert_tiling(struct sway_workspace *workspace, | |||
845 | return con; | 844 | return con; |
846 | } | 845 | } |
847 | 846 | ||
847 | bool workspace_has_single_visible_container(struct sway_workspace *ws) { | ||
848 | struct sway_seat *seat = input_manager_get_default_seat(); | ||
849 | struct sway_container *focus = | ||
850 | seat_get_focus_inactive_tiling(seat, ws); | ||
851 | if (focus && !focus->view) { | ||
852 | focus = seat_get_focus_inactive_view(seat, &focus->node); | ||
853 | } | ||
854 | return (focus && focus->view && view_ancestor_is_only_visible(focus->view)); | ||
855 | } | ||
856 | |||
848 | void workspace_add_gaps(struct sway_workspace *ws) { | 857 | void workspace_add_gaps(struct sway_workspace *ws) { |
849 | if (config->smart_gaps) { | 858 | if (config->smart_gaps == SMART_GAPS_ON |
850 | struct sway_seat *seat = input_manager_get_default_seat(); | 859 | && workspace_has_single_visible_container(ws)) { |
851 | struct sway_container *focus = | 860 | ws->current_gaps.top = 0; |
852 | seat_get_focus_inactive_tiling(seat, ws); | 861 | ws->current_gaps.right = 0; |
853 | if (focus && !focus->view) { | 862 | ws->current_gaps.bottom = 0; |
854 | focus = seat_get_focus_inactive_view(seat, &focus->node); | 863 | ws->current_gaps.left = 0; |
855 | } | 864 | return; |
856 | if (focus && focus->view && view_ancestor_is_only_visible(focus->view)) { | 865 | } |
857 | ws->current_gaps.top = 0; | 866 | |
858 | ws->current_gaps.right = 0; | 867 | if (config->smart_gaps == SMART_GAPS_INVERSE_OUTER |
859 | ws->current_gaps.bottom = 0; | 868 | && !workspace_has_single_visible_container(ws)) { |
860 | ws->current_gaps.left = 0; | 869 | ws->current_gaps.top = 0; |
861 | return; | 870 | ws->current_gaps.right = 0; |
862 | } | 871 | ws->current_gaps.bottom = 0; |
872 | ws->current_gaps.left = 0; | ||
873 | } else { | ||
874 | ws->current_gaps = ws->gaps_outer; | ||
863 | } | 875 | } |
864 | 876 | ||
865 | ws->current_gaps = ws->gaps_outer; | ||
866 | // Add inner gaps and make sure we don't turn out negative | 877 | // Add inner gaps and make sure we don't turn out negative |
867 | ws->current_gaps.top = fmax(0, ws->current_gaps.top + ws->gaps_inner); | 878 | ws->current_gaps.top = fmax(0, ws->current_gaps.top + ws->gaps_inner); |
868 | ws->current_gaps.right = fmax(0, ws->current_gaps.right + ws->gaps_inner); | 879 | ws->current_gaps.right = fmax(0, ws->current_gaps.right + ws->gaps_inner); |
@@ -905,7 +916,7 @@ struct sway_container *workspace_split(struct sway_workspace *workspace, | |||
905 | enum sway_container_layout old_layout = workspace->layout; | 916 | enum sway_container_layout old_layout = workspace->layout; |
906 | struct sway_container *middle = workspace_wrap_children(workspace); | 917 | struct sway_container *middle = workspace_wrap_children(workspace); |
907 | workspace->layout = layout; | 918 | workspace->layout = layout; |
908 | middle->layout = old_layout; | 919 | middle->pending.layout = old_layout; |
909 | 920 | ||
910 | struct sway_seat *seat; | 921 | struct sway_seat *seat; |
911 | wl_list_for_each(seat, &server.input->seats, link) { | 922 | wl_list_for_each(seat, &server.input->seats, link) { |