diff options
-rw-r--r-- | sway/commands/move.c | 44 | ||||
-rw-r--r-- | sway/tree/layout.c | 28 |
2 files changed, 49 insertions, 23 deletions
diff --git a/sway/commands/move.c b/sway/commands/move.c index af3dc538..bb4a7124 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include "sway/commands.h" | 9 | #include "sway/commands.h" |
10 | #include "sway/input/cursor.h" | 10 | #include "sway/input/cursor.h" |
11 | #include "sway/input/seat.h" | 11 | #include "sway/input/seat.h" |
12 | #include "sway/ipc-server.h" | ||
12 | #include "sway/output.h" | 13 | #include "sway/output.h" |
13 | #include "sway/tree/arrange.h" | 14 | #include "sway/tree/arrange.h" |
14 | #include "sway/tree/container.h" | 15 | #include "sway/tree/container.h" |
@@ -16,6 +17,7 @@ | |||
16 | #include "sway/tree/workspace.h" | 17 | #include "sway/tree/workspace.h" |
17 | #include "stringop.h" | 18 | #include "stringop.h" |
18 | #include "list.h" | 19 | #include "list.h" |
20 | #include "log.h" | ||
19 | 21 | ||
20 | static const char *expected_syntax = | 22 | static const char *expected_syntax = |
21 | "Expected 'move <left|right|up|down> <[px] px>' or " | 23 | "Expected 'move <left|right|up|down> <[px] px>' or " |
@@ -189,6 +191,46 @@ static struct cmd_results *cmd_move_container(struct sway_container *current, | |||
189 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 191 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
190 | } | 192 | } |
191 | 193 | ||
194 | static void workspace_move_to_output(struct sway_container *workspace, | ||
195 | struct sway_container *output) { | ||
196 | if (!sway_assert(workspace->type == C_WORKSPACE, "Expected a workspace")) { | ||
197 | return; | ||
198 | } | ||
199 | if (!sway_assert(output->type == C_OUTPUT, "Expected an output")) { | ||
200 | return; | ||
201 | } | ||
202 | if (workspace->parent == output) { | ||
203 | return; | ||
204 | } | ||
205 | struct sway_container *old_output = container_remove_child(workspace); | ||
206 | struct sway_seat *seat = input_manager_get_default_seat(input_manager); | ||
207 | struct sway_container *new_output_focus = | ||
208 | seat_get_focus_inactive(seat, output); | ||
209 | |||
210 | container_add_child(output, workspace); | ||
211 | wl_signal_emit(&workspace->events.reparent, old_output); | ||
212 | |||
213 | // If moving the last workspace from the old output, create a new workspace | ||
214 | // on the old output | ||
215 | if (old_output->children->length == 0) { | ||
216 | char *ws_name = workspace_next_name(old_output->name); | ||
217 | struct sway_container *ws = workspace_create(old_output, ws_name); | ||
218 | free(ws_name); | ||
219 | seat_set_focus(seat, ws); | ||
220 | } | ||
221 | |||
222 | // Try to remove an empty workspace from the destination output. | ||
223 | container_reap_empty_recursive(new_output_focus); | ||
224 | |||
225 | container_sort_workspaces(output); | ||
226 | seat_set_focus(seat, output); | ||
227 | workspace_output_raise_priority(workspace, old_output, output); | ||
228 | ipc_event_workspace(NULL, workspace, "move"); | ||
229 | |||
230 | container_notify_subtree_changed(old_output); | ||
231 | container_notify_subtree_changed(output); | ||
232 | } | ||
233 | |||
192 | static struct cmd_results *cmd_move_workspace(struct sway_container *current, | 234 | static struct cmd_results *cmd_move_workspace(struct sway_container *current, |
193 | int argc, char **argv) { | 235 | int argc, char **argv) { |
194 | struct cmd_results *error = NULL; | 236 | struct cmd_results *error = NULL; |
@@ -219,7 +261,7 @@ static struct cmd_results *cmd_move_workspace(struct sway_container *current, | |||
219 | if (current->type != C_WORKSPACE) { | 261 | if (current->type != C_WORKSPACE) { |
220 | current = container_parent(current, C_WORKSPACE); | 262 | current = container_parent(current, C_WORKSPACE); |
221 | } | 263 | } |
222 | container_move_to(current, destination); | 264 | workspace_move_to_output(current, destination); |
223 | 265 | ||
224 | arrange_windows(source); | 266 | arrange_windows(source); |
225 | arrange_windows(destination); | 267 | arrange_windows(destination); |
diff --git a/sway/tree/layout.c b/sway/tree/layout.c index 28cdc71e..20815654 100644 --- a/sway/tree/layout.c +++ b/sway/tree/layout.c | |||
@@ -142,6 +142,10 @@ struct sway_container *container_remove_child(struct sway_container *child) { | |||
142 | 142 | ||
143 | void container_move_to(struct sway_container *container, | 143 | void container_move_to(struct sway_container *container, |
144 | struct sway_container *destination) { | 144 | struct sway_container *destination) { |
145 | if (!sway_assert(container->type == C_CONTAINER || | ||
146 | container->type == C_VIEW, "Expected a container or view")) { | ||
147 | return; | ||
148 | } | ||
145 | if (container == destination | 149 | if (container == destination |
146 | || container_has_ancestor(container, destination)) { | 150 | || container_has_ancestor(container, destination)) { |
147 | return; | 151 | return; |
@@ -154,11 +158,8 @@ void container_move_to(struct sway_container *container, | |||
154 | container->width = container->height = 0; | 158 | container->width = container->height = 0; |
155 | container->saved_width = container->saved_height = 0; | 159 | container->saved_width = container->saved_height = 0; |
156 | 160 | ||
157 | struct sway_container *new_parent, *new_parent_focus; | 161 | struct sway_container *new_parent; |
158 | struct sway_seat *seat = input_manager_get_default_seat(input_manager); | ||
159 | 162 | ||
160 | // Get the focus of the destination before we change it. | ||
161 | new_parent_focus = seat_get_focus_inactive(seat, destination); | ||
162 | if (destination->type == C_VIEW) { | 163 | if (destination->type == C_VIEW) { |
163 | new_parent = container_add_sibling(destination, container); | 164 | new_parent = container_add_sibling(destination, container); |
164 | } else { | 165 | } else { |
@@ -167,24 +168,7 @@ void container_move_to(struct sway_container *container, | |||
167 | } | 168 | } |
168 | wl_signal_emit(&container->events.reparent, old_parent); | 169 | wl_signal_emit(&container->events.reparent, old_parent); |
169 | 170 | ||
170 | if (container->type == C_WORKSPACE) { | 171 | if (container->type == C_VIEW) { |
171 | // If moving a workspace to a new output, maybe create a new workspace | ||
172 | // on the previous output | ||
173 | if (old_parent->children->length == 0) { | ||
174 | char *ws_name = workspace_next_name(old_parent->name); | ||
175 | struct sway_container *ws = workspace_create(old_parent, ws_name); | ||
176 | free(ws_name); | ||
177 | seat_set_focus(seat, ws); | ||
178 | } | ||
179 | |||
180 | // Try to remove an empty workspace from the destination output. | ||
181 | container_reap_empty_recursive(new_parent_focus); | ||
182 | |||
183 | container_sort_workspaces(new_parent); | ||
184 | seat_set_focus(seat, new_parent); | ||
185 | workspace_output_raise_priority(container, old_parent, new_parent); | ||
186 | ipc_event_workspace(NULL, container, "move"); | ||
187 | } else if (container->type == C_VIEW) { | ||
188 | ipc_event_window(container, "move"); | 172 | ipc_event_window(container, "move"); |
189 | } | 173 | } |
190 | container_notify_subtree_changed(old_parent); | 174 | container_notify_subtree_changed(old_parent); |