diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-04-18 00:10:32 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-04-18 00:10:32 +1000 |
commit | 72beae209b03815e39d0aaa11348fa17c8a7bca9 (patch) | |
tree | fefa256f93c8fa7a3e80f9fb54accd0e6108e77a /sway/tree/layout.c | |
parent | Fix views unmapping their own fullscreen windows. (diff) | |
download | sway-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.c | 136 |
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 | ||
85 | static 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 | |||
85 | void container_insert_child(struct sway_container *parent, | 116 | void 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 | ||
122 | struct sway_container *container_remove_child(struct sway_container *child) { | 157 | struct 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 | ||
184 | static bool sway_dir_to_wlr(enum movement_direction dir, | 229 | static 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 | ||
834 | struct sway_container *container_get_in_direction( | 892 | static 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 | ||
1001 | struct 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 | |||
935 | struct sway_container *container_replace_child(struct sway_container *child, | 1023 | struct 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; |