aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/tree/layout.c')
-rw-r--r--sway/tree/layout.c116
1 files changed, 93 insertions, 23 deletions
diff --git a/sway/tree/layout.c b/sway/tree/layout.c
index 0b637822..7ffc2484 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
@@ -568,6 +633,11 @@ void arrange_windows(struct sway_container *container,
568 container->y = y = area->y; 633 container->y = y = area->y;
569 wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f", 634 wlr_log(L_DEBUG, "Arranging workspace '%s' at %f, %f",
570 container->name, container->x, container->y); 635 container->name, container->x, container->y);
636 if (container->sway_workspace->fullscreen) {
637 view_configure(container->sway_workspace->fullscreen, 0, 0,
638 output->width, output->height);
639 return;
640 }
571 } 641 }
572 // children are properly handled below 642 // children are properly handled below
573 break; 643 break;
@@ -816,34 +886,26 @@ static struct sway_container *sway_output_from_wlr(struct wlr_output *output) {
816struct sway_container *container_get_in_direction( 886struct sway_container *container_get_in_direction(
817 struct sway_container *container, struct sway_seat *seat, 887 struct sway_container *container, struct sway_seat *seat,
818 enum movement_direction dir) { 888 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; 889 struct sway_container *parent = container->parent;
824 if (dir == MOVE_PARENT) { 890
825 if (parent->type == C_OUTPUT) { 891 if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
892 if (dir == MOVE_PARENT || dir == MOVE_CHILD) {
826 return NULL; 893 return NULL;
827 } else {
828 return parent;
829 } 894 }
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); 895 container = container_parent(container, C_OUTPUT);
837 get_layout_center_position(container, &abs_pos); 896 parent = container->parent;
838 struct sway_container *output = 897 } else {
839 swayc_adjacent_output(container, dir, &abs_pos, true); 898 if (dir == MOVE_CHILD) {
840 return get_swayc_in_output_direction(output, dir); 899 return seat_get_focus_inactive(seat, container);
841 } 900 }
842 if (container->type == C_WORKSPACE && container->fullscreen) { 901 if (dir == MOVE_PARENT) {
843 sway_log(L_DEBUG, "Moving to fullscreen view"); 902 if (parent->type == C_OUTPUT) {
844 return container->fullscreen; 903 return NULL;
904 } else {
905 return parent;
906 }
907 }
845 } 908 }
846 */
847 909
848 struct sway_container *wrap_candidate = NULL; 910 struct sway_container *wrap_candidate = NULL;
849 while (true) { 911 while (true) {
@@ -874,6 +936,14 @@ struct sway_container *container_get_in_direction(
874 if (next == NULL) { 936 if (next == NULL) {
875 return NULL; 937 return NULL;
876 } 938 }
939 struct sway_container *next_workspace = next;
940 if (next_workspace->type != C_WORKSPACE) {
941 next_workspace = container_parent(next_workspace, C_WORKSPACE);
942 }
943 sway_assert(next_workspace, "Next container has no workspace");
944 if (next_workspace->sway_workspace->fullscreen) {
945 return next_workspace->sway_workspace->fullscreen->swayc;
946 }
877 if (next->children && next->children->length) { 947 if (next->children && next->children->length) {
878 // TODO consider floating children as well 948 // TODO consider floating children as well
879 return seat_get_focus_inactive_view(seat, next); 949 return seat_get_focus_inactive_view(seat, next);