summaryrefslogtreecommitdiffstats
path: root/sway/tree/layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/layout.c')
-rw-r--r--sway/tree/layout.c136
1 files changed, 112 insertions, 24 deletions
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 0b637822..56d4e1d2 100644
--- a/sway/tree/layout.c
+++ b/sway/tree/layout.c
@@ -82,6 +82,37 @@ static int index_child(const struct sway_container *child) {
82 return i; 82 return i;
83} 83}
84 84
85static void container_handle_fullscreen_reparent(struct sway_container *viewcon,
86 struct sway_container *old_parent) {
87 if (viewcon->type != C_VIEW || !viewcon->sway_view->is_fullscreen) {
88 return;
89 }
90 struct sway_view *view = viewcon->sway_view;
91 struct sway_container *old_workspace = old_parent;
92 if (old_workspace && old_workspace->type != C_WORKSPACE) {
93 old_workspace = container_parent(old_workspace, C_WORKSPACE);
94 }
95 struct sway_container *new_workspace = container_parent(view->swayc,
96 C_WORKSPACE);
97 if (old_workspace == new_workspace) {
98 return;
99 }
100 // Unmark the old workspace as fullscreen
101 if (old_workspace) {
102 old_workspace->sway_workspace->fullscreen = NULL;
103 }
104
105 // Mark the new workspace as fullscreen
106 if (new_workspace->sway_workspace->fullscreen) {
107 view_set_fullscreen(new_workspace->sway_workspace->fullscreen, false);
108 }
109 new_workspace->sway_workspace->fullscreen = view;
110 // Resize view to new output dimensions
111 struct sway_output *output = new_workspace->parent->sway_output;
112 view_configure(view, 0, 0,
113 output->wlr_output->width, output->wlr_output->height);
114}
115
85void container_insert_child(struct sway_container *parent, 116void container_insert_child(struct sway_container *parent,
86 struct sway_container *child, int i) { 117 struct sway_container *child, int i) {
87 struct sway_container *old_parent = child->parent; 118 struct sway_container *old_parent = child->parent;
@@ -91,6 +122,7 @@ void container_insert_child(struct sway_container *parent,
91 wlr_log(L_DEBUG, "Inserting id:%zd at index %d", child->id, i); 122 wlr_log(L_DEBUG, "Inserting id:%zd at index %d", child->id, i);
92 list_insert(parent->children, i, child); 123 list_insert(parent->children, i, child);
93 child->parent = parent; 124 child->parent = parent;
125 container_handle_fullscreen_reparent(child, old_parent);
94 wl_signal_emit(&child->events.reparent, old_parent); 126 wl_signal_emit(&child->events.reparent, old_parent);
95} 127}
96 128
@@ -106,6 +138,7 @@ struct sway_container *container_add_sibling(struct sway_container *fixed,
106 int i = index_child(fixed); 138 int i = index_child(fixed);
107 list_insert(parent->children, i + 1, active); 139 list_insert(parent->children, i + 1, active);
108 active->parent = parent; 140 active->parent = parent;
141 container_handle_fullscreen_reparent(active, old_parent);
109 wl_signal_emit(&active->events.reparent, old_parent); 142 wl_signal_emit(&active->events.reparent, old_parent);
110 return active->parent; 143 return active->parent;
111} 144}
@@ -115,11 +148,18 @@ void container_add_child(struct sway_container *parent,
115 wlr_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)", 148 wlr_log(L_DEBUG, "Adding %p (%d, %fx%f) to %p (%d, %fx%f)",
116 child, child->type, child->width, child->height, 149 child, child->type, child->width, child->height,
117 parent, parent->type, parent->width, parent->height); 150 parent, parent->type, parent->width, parent->height);
151 struct sway_container *old_parent = child->parent;
118 list_add(parent->children, child); 152 list_add(parent->children, child);
153 container_handle_fullscreen_reparent(child, old_parent);
119 child->parent = parent; 154 child->parent = parent;
120} 155}
121 156
122struct sway_container *container_remove_child(struct sway_container *child) { 157struct sway_container *container_remove_child(struct sway_container *child) {
158 if (child->type == C_VIEW && child->sway_view->is_fullscreen) {
159 struct sway_container *workspace = container_parent(child, C_WORKSPACE);
160 workspace->sway_workspace->fullscreen = NULL;
161 }
162
123 struct sway_container *parent = child->parent; 163 struct sway_container *parent = child->parent;
124 for (int i = 0; i < parent->children->length; ++i) { 164 for (int i = 0; i < parent->children->length; ++i) {
125 if (parent->children->items[i] == child) { 165 if (parent->children->items[i] == child) {
@@ -164,6 +204,26 @@ void container_move_to(struct sway_container *container,
164 arrange_windows(old_parent, -1, -1); 204 arrange_windows(old_parent, -1, -1);
165 } 205 }
166 arrange_windows(new_parent, -1, -1); 206 arrange_windows(new_parent, -1, -1);
207 // If view was moved to a fullscreen workspace, refocus the fullscreen view
208 struct sway_container *new_workspace = container;
209 if (new_workspace->type != C_WORKSPACE) {
210 new_workspace = container_parent(new_workspace, C_WORKSPACE);
211 }
212 if (new_workspace->sway_workspace->fullscreen) {
213 struct sway_seat *seat;
214 struct sway_container *focus, *focus_ws;
215 wl_list_for_each(seat, &input_manager->seats, link) {
216 focus = seat_get_focus(seat);
217 focus_ws = focus;
218 if (focus_ws->type != C_WORKSPACE) {
219 focus_ws = container_parent(focus_ws, C_WORKSPACE);
220 }
221 seat_set_focus(seat, new_workspace->sway_workspace->fullscreen->swayc);
222 if (focus_ws != new_workspace) {
223 seat_set_focus(seat, focus);
224 }
225 }
226 }
167} 227}
168 228
169static bool sway_dir_to_wlr(enum movement_direction dir, 229static bool sway_dir_to_wlr(enum movement_direction dir,
@@ -268,6 +328,11 @@ void container_move(struct sway_container *container,
268 struct sway_container *current = container; 328 struct sway_container *current = container;
269 struct sway_container *parent = current->parent; 329 struct sway_container *parent = current->parent;
270 330
331 // If moving a fullscreen view, only consider outputs
332 if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
333 current = container_parent(container, C_OUTPUT);
334 }
335
271 if (parent != container_flatten(parent)) { 336 if (parent != container_flatten(parent)) {
272 // Special case: we were the last one in this container, so flatten it 337 // Special case: we were the last one in this container, so flatten it
273 // and leave 338 // and leave
@@ -531,6 +596,12 @@ void arrange_windows(struct sway_container *container,
531 container->name, container->width, container->height, container->x, 596 container->name, container->width, container->height, container->x,
532 container->y); 597 container->y);
533 598
599 if (container->type == C_WORKSPACE
600 && container->sway_workspace->fullscreen) {
601 view_configure(container->sway_workspace->fullscreen, 0, 0,
602 container->parent->width, container->parent->height);
603 }
604
534 double x = 0, y = 0; 605 double x = 0, y = 0;
535 switch (container->type) { 606 switch (container->type) {
536 case C_ROOT: 607 case C_ROOT:
@@ -557,6 +628,9 @@ void arrange_windows(struct sway_container *container,
557 return; 628 return;
558 case C_WORKSPACE: 629 case C_WORKSPACE:
559 { 630 {
631 if (container->sway_workspace->fullscreen) {
632 return;
633 }
560 struct sway_container *output = 634 struct sway_container *output =
561 container_parent(container, C_OUTPUT); 635 container_parent(container, C_OUTPUT);
562 struct wlr_box *area = &output->sway_output->usable_area; 636 struct wlr_box *area = &output->sway_output->usable_area;
@@ -813,37 +887,29 @@ static struct sway_container *sway_output_from_wlr(struct wlr_output *output) {
813 return NULL; 887 return NULL;
814} 888}
815 889
816struct sway_container *container_get_in_direction( 890static struct sway_container *container_get_in_direction_naive(
817 struct sway_container *container, struct sway_seat *seat, 891 struct sway_container *container, struct sway_seat *seat,
818 enum movement_direction dir) { 892 enum movement_direction dir) {
819 if (dir == MOVE_CHILD) {
820 return seat_get_focus_inactive(seat, container);
821 }
822
823 struct sway_container *parent = container->parent; 893 struct sway_container *parent = container->parent;
824 if (dir == MOVE_PARENT) { 894
825 if (parent->type == C_OUTPUT) { 895 if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
896 if (dir == MOVE_PARENT || dir == MOVE_CHILD) {
826 return NULL; 897 return NULL;
827 } else {
828 return parent;
829 } 898 }
830 }
831
832 // TODO WLR fullscreen
833 /*
834 if (container->type == C_VIEW && swayc_is_fullscreen(container)) {
835 wlr_log(L_DEBUG, "Moving from fullscreen view, skipping to output");
836 container = container_parent(container, C_OUTPUT); 899 container = container_parent(container, C_OUTPUT);
837 get_layout_center_position(container, &abs_pos); 900 parent = container->parent;
838 struct sway_container *output = 901 } else {
839 swayc_adjacent_output(container, dir, &abs_pos, true); 902 if (dir == MOVE_CHILD) {
840 return get_swayc_in_output_direction(output, dir); 903 return seat_get_focus_inactive(seat, container);
841 } 904 }
842 if (container->type == C_WORKSPACE && container->fullscreen) { 905 if (dir == MOVE_PARENT) {
843 sway_log(L_DEBUG, "Moving to fullscreen view"); 906 if (parent->type == C_OUTPUT) {
844 return container->fullscreen; 907 return NULL;
908 } else {
909 return parent;
910 }
911 }
845 } 912 }
846 */
847 913
848 struct sway_container *wrap_candidate = NULL; 914 struct sway_container *wrap_candidate = NULL;
849 while (true) { 915 while (true) {
@@ -930,6 +996,28 @@ struct sway_container *container_get_in_direction(
930 } 996 }
931} 997}
932 998
999struct sway_container *container_get_in_direction(
1000 struct sway_container *container, struct sway_seat *seat,
1001 enum movement_direction dir) {
1002 struct sway_container *result = container_get_in_direction_naive(container,
1003 seat, dir);
1004 if (!result) {
1005 return NULL;
1006 }
1007 struct sway_container *old_workspace = container;
1008 if (old_workspace->type != C_WORKSPACE) {
1009 old_workspace = container_parent(old_workspace, C_WORKSPACE);
1010 }
1011 struct sway_container *new_workspace = result;
1012 if (new_workspace->type != C_WORKSPACE) {
1013 new_workspace = container_parent(new_workspace, C_WORKSPACE);
1014 }
1015 if (old_workspace != new_workspace && new_workspace->sway_workspace->fullscreen) {
1016 result = new_workspace->sway_workspace->fullscreen->swayc;
1017 }
1018 return result;
1019}
1020
933struct sway_container *container_replace_child(struct sway_container *child, 1021struct sway_container *container_replace_child(struct sway_container *child,
934 struct sway_container *new_child) { 1022 struct sway_container *new_child) {
935 struct sway_container *parent = child->parent; 1023 struct sway_container *parent = child->parent;