aboutsummaryrefslogtreecommitdiffstats
path: root/sway/tree/layout.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-04-18 00:10:32 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-04-18 00:10:32 +1000
commit72beae209b03815e39d0aaa11348fa17c8a7bca9 (patch)
treefefa256f93c8fa7a3e80f9fb54accd0e6108e77a /sway/tree/layout.c
parentFix views unmapping their own fullscreen windows. (diff)
downloadsway-72beae209b03815e39d0aaa11348fa17c8a7bca9.tar.gz
sway-72beae209b03815e39d0aaa11348fa17c8a7bca9.tar.zst
sway-72beae209b03815e39d0aaa11348fa17c8a7bca9.zip
Fullscreen fixes.
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 62219bb1..d931c4dc 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) {
@@ -137,21 +177,6 @@ void container_move_to(struct sway_container *container,
137 || container_has_anscestor(container, destination)) { 177 || container_has_anscestor(container, destination)) {
138 return; 178 return;
139 } 179 }
140
141 if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
142 struct sway_container *old_workspace = container;
143 if (old_workspace->type != C_WORKSPACE) {
144 old_workspace = container_parent(old_workspace, C_WORKSPACE);
145 }
146 struct sway_container *new_workspace = destination;
147 if (new_workspace->type != C_WORKSPACE) {
148 new_workspace = container_parent(new_workspace, C_WORKSPACE);
149 }
150 if (old_workspace != new_workspace) {
151 view_set_fullscreen(container->sway_view, false);
152 }
153 }
154
155 struct sway_container *old_parent = container_remove_child(container); 180 struct sway_container *old_parent = container_remove_child(container);
156 container->width = container->height = 0; 181 container->width = container->height = 0;
157 struct sway_container *new_parent; 182 struct sway_container *new_parent;
@@ -179,6 +204,26 @@ void container_move_to(struct sway_container *container,
179 arrange_windows(old_parent, -1, -1); 204 arrange_windows(old_parent, -1, -1);
180 } 205 }
181 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 }
182} 227}
183 228
184static bool sway_dir_to_wlr(enum movement_direction dir, 229static bool sway_dir_to_wlr(enum movement_direction dir,
@@ -283,6 +328,11 @@ void container_move(struct sway_container *container,
283 struct sway_container *current = container; 328 struct sway_container *current = container;
284 struct sway_container *parent = current->parent; 329 struct sway_container *parent = current->parent;
285 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
286 if (parent != container_flatten(parent)) { 336 if (parent != container_flatten(parent)) {
287 // 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
288 // and leave 338 // and leave
@@ -546,6 +596,14 @@ void arrange_windows(struct sway_container *container,
546 container->name, container->width, container->height, container->x, 596 container->name, container->width, container->height, container->x,
547 container->y); 597 container->y);
548 598
599 if (container->type == C_WORKSPACE
600 && container->sway_workspace->fullscreen) {
601 struct wlr_output *wlr_output
602 = container->parent->sway_output->wlr_output;
603 view_configure(container->sway_workspace->fullscreen, 0, 0,
604 wlr_output->width, wlr_output->height);
605 }
606
549 double x = 0, y = 0; 607 double x = 0, y = 0;
550 switch (container->type) { 608 switch (container->type) {
551 case C_ROOT: 609 case C_ROOT:
@@ -831,19 +889,27 @@ static struct sway_container *sway_output_from_wlr(struct wlr_output *output) {
831 return NULL; 889 return NULL;
832} 890}
833 891
834struct sway_container *container_get_in_direction( 892static struct sway_container *container_get_in_direction_naive(
835 struct sway_container *container, struct sway_seat *seat, 893 struct sway_container *container, struct sway_seat *seat,
836 enum movement_direction dir) { 894 enum movement_direction dir) {
837 if (dir == MOVE_CHILD) {
838 return seat_get_focus_inactive(seat, container);
839 }
840
841 struct sway_container *parent = container->parent; 895 struct sway_container *parent = container->parent;
842 if (dir == MOVE_PARENT) { 896
843 if (parent->type == C_OUTPUT) { 897 if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
898 if (dir == MOVE_PARENT || dir == MOVE_CHILD) {
844 return NULL; 899 return NULL;
845 } else { 900 }
846 return parent; 901 container = container_parent(container, C_OUTPUT);
902 parent = container->parent;
903 } else {
904 if (dir == MOVE_CHILD) {
905 return seat_get_focus_inactive(seat, container);
906 }
907 if (dir == MOVE_PARENT) {
908 if (parent->type == C_OUTPUT) {
909 return NULL;
910 } else {
911 return parent;
912 }
847 } 913 }
848 } 914 }
849 915
@@ -932,6 +998,28 @@ struct sway_container *container_get_in_direction(
932 } 998 }
933} 999}
934 1000
1001struct sway_container *container_get_in_direction(
1002 struct sway_container *container, struct sway_seat *seat,
1003 enum movement_direction dir) {
1004 struct sway_container *result = container_get_in_direction_naive(container,
1005 seat, dir);
1006 if (!result) {
1007 return NULL;
1008 }
1009 struct sway_container *old_workspace = container;
1010 if (old_workspace->type != C_WORKSPACE) {
1011 old_workspace = container_parent(old_workspace, C_WORKSPACE);
1012 }
1013 struct sway_container *new_workspace = result;
1014 if (new_workspace->type != C_WORKSPACE) {
1015 new_workspace = container_parent(new_workspace, C_WORKSPACE);
1016 }
1017 if (old_workspace != new_workspace && new_workspace->sway_workspace->fullscreen) {
1018 result = new_workspace->sway_workspace->fullscreen->swayc;
1019 }
1020 return result;
1021}
1022
935struct sway_container *container_replace_child(struct sway_container *child, 1023struct sway_container *container_replace_child(struct sway_container *child,
936 struct sway_container *new_child) { 1024 struct sway_container *new_child) {
937 struct sway_container *parent = child->parent; 1025 struct sway_container *parent = child->parent;