diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-08-07 09:30:27 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-08-08 08:48:20 +1000 |
commit | a0649190deaaf093112e99881c25ff550f07e96b (patch) | |
tree | 922fc56dad707ceeebaf6ea3364751e51d764407 | |
parent | Implement move to workspace on a floating container (diff) | |
download | sway-a0649190deaaf093112e99881c25ff550f07e96b.tar.gz sway-a0649190deaaf093112e99881c25ff550f07e96b.tar.zst sway-a0649190deaaf093112e99881c25ff550f07e96b.zip |
Fix edge cases when moving floating container to new workspace
* Removes container_floating_move_to_container, instead opting to put
that logic in container_move_to
* In the seat code, focusing a floating view now updates the pending
state only and lets the next transaction carry it over to the current
state. This is required, otherwise it would crash.
* When unfullscreening a floating container, an output check is now done
to see if it should center it.
-rw-r--r-- | include/sway/tree/container.h | 9 | ||||
-rw-r--r-- | sway/input/seat.c | 4 | ||||
-rw-r--r-- | sway/tree/container.c | 40 | ||||
-rw-r--r-- | sway/tree/layout.c | 48 |
4 files changed, 47 insertions, 54 deletions
diff --git a/include/sway/tree/container.h b/include/sway/tree/container.h index d82db89c..4d0e6003 100644 --- a/include/sway/tree/container.h +++ b/include/sway/tree/container.h | |||
@@ -323,6 +323,12 @@ void container_floating_translate(struct sway_container *con, | |||
323 | double x_amount, double y_amount); | 323 | double x_amount, double y_amount); |
324 | 324 | ||
325 | /** | 325 | /** |
326 | * Choose an output for the floating container's new position. | ||
327 | */ | ||
328 | struct sway_container *container_floating_find_output( | ||
329 | struct sway_container *con); | ||
330 | |||
331 | /** | ||
326 | * Move a floating container to a new layout-local position. | 332 | * Move a floating container to a new layout-local position. |
327 | */ | 333 | */ |
328 | void container_floating_move_to(struct sway_container *con, | 334 | void container_floating_move_to(struct sway_container *con, |
@@ -333,9 +339,6 @@ void container_floating_move_to(struct sway_container *con, | |||
333 | */ | 339 | */ |
334 | void container_floating_move_to_center(struct sway_container *con); | 340 | void container_floating_move_to_center(struct sway_container *con); |
335 | 341 | ||
336 | void container_floating_move_to_container(struct sway_container *container, | ||
337 | struct sway_container *destination); | ||
338 | |||
339 | /** | 342 | /** |
340 | * Mark a container as dirty if it isn't already. Dirty containers will be | 343 | * Mark a container as dirty if it isn't already. Dirty containers will be |
341 | * included in the next transaction then unmarked as dirty. | 344 | * included in the next transaction then unmarked as dirty. |
diff --git a/sway/input/seat.c b/sway/input/seat.c index dd4d5c3b..6dd7cf7d 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c | |||
@@ -717,12 +717,8 @@ void seat_set_focus_warp(struct sway_seat *seat, | |||
717 | 717 | ||
718 | // If we've focused a floating container, bring it to the front. | 718 | // If we've focused a floating container, bring it to the front. |
719 | // We do this by putting it at the end of the floating list. | 719 | // We do this by putting it at the end of the floating list. |
720 | // This must happen for both the pending and current children lists. | ||
721 | if (container && container_is_floating(container)) { | 720 | if (container && container_is_floating(container)) { |
722 | list_move_to_end(container->parent->children, container); | 721 | list_move_to_end(container->parent->children, container); |
723 | if (container_has_ancestor(container, container->current.parent)) { | ||
724 | list_move_to_end(container->parent->current.children, container); | ||
725 | } | ||
726 | } | 722 | } |
727 | 723 | ||
728 | // clean up unfocused empty workspace on new output | 724 | // clean up unfocused empty workspace on new output |
diff --git a/sway/tree/container.c b/sway/tree/container.c index f31c152f..4507655e 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -1182,7 +1182,7 @@ void container_floating_translate(struct sway_container *con, | |||
1182 | * one, otherwise we'll choose whichever output is closest to the container's | 1182 | * one, otherwise we'll choose whichever output is closest to the container's |
1183 | * center. | 1183 | * center. |
1184 | */ | 1184 | */ |
1185 | static struct sway_container *container_floating_find_output( | 1185 | struct sway_container *container_floating_find_output( |
1186 | struct sway_container *con) { | 1186 | struct sway_container *con) { |
1187 | double center_x = con->x + con->width / 2; | 1187 | double center_x = con->x + con->width / 2; |
1188 | double center_y = con->y + con->height / 2; | 1188 | double center_y = con->y + con->height / 2; |
@@ -1245,39 +1245,6 @@ void container_floating_move_to_center(struct sway_container *con) { | |||
1245 | container_floating_translate(con, new_lx - con->x, new_ly - con->y); | 1245 | container_floating_translate(con, new_lx - con->x, new_ly - con->y); |
1246 | } | 1246 | } |
1247 | 1247 | ||
1248 | void container_floating_move_to_container(struct sway_container *container, | ||
1249 | struct sway_container *destination) { | ||
1250 | // Resolve destination into a workspace | ||
1251 | struct sway_container *new_ws = NULL; | ||
1252 | if (destination->type == C_OUTPUT) { | ||
1253 | new_ws = output_get_active_workspace(destination->sway_output); | ||
1254 | } else if (destination->type == C_WORKSPACE) { | ||
1255 | new_ws = destination; | ||
1256 | } else { | ||
1257 | new_ws = container_parent(destination, C_WORKSPACE); | ||
1258 | } | ||
1259 | if (!new_ws) { | ||
1260 | // This can happen if the user has run "move container to mark foo", | ||
1261 | // where mark foo is on a hidden scratchpad container. | ||
1262 | return; | ||
1263 | } | ||
1264 | struct sway_container *old_ws = container_parent(container, C_WORKSPACE); | ||
1265 | if (old_ws != new_ws) { | ||
1266 | container_remove_child(container); | ||
1267 | container_add_child(new_ws->sway_workspace->floating, container); | ||
1268 | arrange_windows(old_ws); | ||
1269 | arrange_windows(new_ws); | ||
1270 | workspace_detect_urgent(old_ws); | ||
1271 | workspace_detect_urgent(new_ws); | ||
1272 | } | ||
1273 | // If the container's center doesn't overlap the new workspace, center it | ||
1274 | // within the workspace. | ||
1275 | struct sway_container *output = container_floating_find_output(container); | ||
1276 | if (new_ws->parent != output) { | ||
1277 | container_floating_move_to_center(container); | ||
1278 | } | ||
1279 | } | ||
1280 | |||
1281 | void container_set_dirty(struct sway_container *container) { | 1248 | void container_set_dirty(struct sway_container *container) { |
1282 | if (container->dirty) { | 1249 | if (container->dirty) { |
1283 | return; | 1250 | return; |
@@ -1357,6 +1324,11 @@ void container_set_fullscreen(struct sway_container *container, bool enable) { | |||
1357 | container->y = container->saved_y; | 1324 | container->y = container->saved_y; |
1358 | container->width = container->saved_width; | 1325 | container->width = container->saved_width; |
1359 | container->height = container->saved_height; | 1326 | container->height = container->saved_height; |
1327 | struct sway_container *output = | ||
1328 | container_floating_find_output(container); | ||
1329 | if (!container_has_ancestor(container, output)) { | ||
1330 | container_floating_move_to_center(container); | ||
1331 | } | ||
1360 | } else { | 1332 | } else { |
1361 | container->width = container->saved_width; | 1333 | container->width = container->saved_width; |
1362 | container->height = container->saved_height; | 1334 | container->height = container->saved_height; |
diff --git a/sway/tree/layout.c b/sway/tree/layout.c index bdcd1a9b..38e14d00 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c | |||
@@ -150,22 +150,44 @@ void container_move_to(struct sway_container *container, | |||
150 | || container_has_ancestor(container, destination)) { | 150 | || container_has_ancestor(container, destination)) { |
151 | return; | 151 | return; |
152 | } | 152 | } |
153 | struct sway_container *old_parent = NULL; | ||
154 | struct sway_container *new_parent = NULL; | ||
153 | if (container_is_floating(container)) { | 155 | if (container_is_floating(container)) { |
154 | container_floating_move_to_container(container, destination); | 156 | // Resolve destination into a workspace |
155 | return; | 157 | struct sway_container *new_ws = NULL; |
156 | } | 158 | if (destination->type == C_OUTPUT) { |
157 | struct sway_container *old_parent = container_remove_child(container); | 159 | new_ws = output_get_active_workspace(destination->sway_output); |
158 | container->width = container->height = 0; | 160 | } else if (destination->type == C_WORKSPACE) { |
159 | container->saved_width = container->saved_height = 0; | 161 | new_ws = destination; |
160 | 162 | } else { | |
161 | struct sway_container *new_parent; | 163 | new_ws = container_parent(destination, C_WORKSPACE); |
162 | 164 | } | |
163 | if (destination->type == C_VIEW) { | 165 | if (!new_ws) { |
164 | new_parent = container_add_sibling(destination, container); | 166 | // This can happen if the user has run "move container to mark foo", |
167 | // where mark foo is on a hidden scratchpad container. | ||
168 | return; | ||
169 | } | ||
170 | struct sway_container *old_output = | ||
171 | container_parent(container, C_OUTPUT); | ||
172 | old_parent = container_remove_child(container); | ||
173 | container_add_child(new_ws->sway_workspace->floating, container); | ||
174 | // If changing output, center it within the workspace | ||
175 | if (old_output != new_ws->parent && !container->is_fullscreen) { | ||
176 | container_floating_move_to_center(container); | ||
177 | } | ||
165 | } else { | 178 | } else { |
166 | new_parent = destination; | 179 | old_parent = container_remove_child(container); |
167 | container_add_child(destination, container); | 180 | container->width = container->height = 0; |
181 | container->saved_width = container->saved_height = 0; | ||
182 | |||
183 | if (destination->type == C_VIEW) { | ||
184 | new_parent = container_add_sibling(destination, container); | ||
185 | } else { | ||
186 | new_parent = destination; | ||
187 | container_add_child(destination, container); | ||
188 | } | ||
168 | } | 189 | } |
190 | |||
169 | wl_signal_emit(&container->events.reparent, old_parent); | 191 | wl_signal_emit(&container->events.reparent, old_parent); |
170 | 192 | ||
171 | if (container->type == C_VIEW) { | 193 | if (container->type == C_VIEW) { |