diff options
Diffstat (limited to 'sway/commands/move.c')
-rw-r--r-- | sway/commands/move.c | 61 |
1 files changed, 57 insertions, 4 deletions
diff --git a/sway/commands/move.c b/sway/commands/move.c index dc9a6f6f..a4fae388 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c | |||
@@ -5,8 +5,10 @@ | |||
5 | #include <wlr/types/wlr_output_layout.h> | 5 | #include <wlr/types/wlr_output_layout.h> |
6 | #include <wlr/util/log.h> | 6 | #include <wlr/util/log.h> |
7 | #include "sway/commands.h" | 7 | #include "sway/commands.h" |
8 | #include "sway/desktop/transaction.h" | ||
8 | #include "sway/input/seat.h" | 9 | #include "sway/input/seat.h" |
9 | #include "sway/output.h" | 10 | #include "sway/output.h" |
11 | #include "sway/tree/arrange.h" | ||
10 | #include "sway/tree/container.h" | 12 | #include "sway/tree/container.h" |
11 | #include "sway/tree/layout.h" | 13 | #include "sway/tree/layout.h" |
12 | #include "sway/tree/workspace.h" | 14 | #include "sway/tree/workspace.h" |
@@ -88,6 +90,7 @@ static struct cmd_results *cmd_move_container(struct sway_container *current, | |||
88 | } | 90 | } |
89 | free(ws_name); | 91 | free(ws_name); |
90 | struct sway_container *old_parent = current->parent; | 92 | struct sway_container *old_parent = current->parent; |
93 | struct sway_container *old_ws = container_parent(current, C_WORKSPACE); | ||
91 | struct sway_container *destination = seat_get_focus_inactive( | 94 | struct sway_container *destination = seat_get_focus_inactive( |
92 | config->handler_context.seat, ws); | 95 | config->handler_context.seat, ws); |
93 | container_move_to(current, destination); | 96 | container_move_to(current, destination); |
@@ -96,6 +99,15 @@ static struct cmd_results *cmd_move_container(struct sway_container *current, | |||
96 | seat_set_focus(config->handler_context.seat, focus); | 99 | seat_set_focus(config->handler_context.seat, focus); |
97 | container_reap_empty(old_parent); | 100 | container_reap_empty(old_parent); |
98 | container_reap_empty(destination->parent); | 101 | container_reap_empty(destination->parent); |
102 | |||
103 | // TODO: Ideally we would arrange the surviving parent after reaping, | ||
104 | // but container_reap_empty does not return it, so we arrange the | ||
105 | // workspace instead. | ||
106 | struct sway_transaction *txn = transaction_create(); | ||
107 | arrange_windows(old_ws, txn); | ||
108 | arrange_windows(destination->parent, txn); | ||
109 | transaction_commit(txn); | ||
110 | |||
99 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 111 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
100 | } else if (strcasecmp(argv[1], "to") == 0 | 112 | } else if (strcasecmp(argv[1], "to") == 0 |
101 | && strcasecmp(argv[2], "output") == 0) { | 113 | && strcasecmp(argv[2], "output") == 0) { |
@@ -121,10 +133,20 @@ static struct cmd_results *cmd_move_container(struct sway_container *current, | |||
121 | focus = destination->children->items[0]; | 133 | focus = destination->children->items[0]; |
122 | } | 134 | } |
123 | struct sway_container *old_parent = current->parent; | 135 | struct sway_container *old_parent = current->parent; |
136 | struct sway_container *old_ws = container_parent(current, C_WORKSPACE); | ||
124 | container_move_to(current, focus); | 137 | container_move_to(current, focus); |
125 | seat_set_focus(config->handler_context.seat, old_parent); | 138 | seat_set_focus(config->handler_context.seat, old_parent); |
126 | container_reap_empty(old_parent); | 139 | container_reap_empty(old_parent); |
127 | container_reap_empty(focus->parent); | 140 | container_reap_empty(focus->parent); |
141 | |||
142 | // TODO: Ideally we would arrange the surviving parent after reaping, | ||
143 | // but container_reap_empty does not return it, so we arrange the | ||
144 | // workspace instead. | ||
145 | struct sway_transaction *txn = transaction_create(); | ||
146 | arrange_windows(old_ws, txn); | ||
147 | arrange_windows(focus->parent, txn); | ||
148 | transaction_commit(txn); | ||
149 | |||
128 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 150 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
129 | } | 151 | } |
130 | return cmd_results_new(CMD_INVALID, "move", expected_syntax); | 152 | return cmd_results_new(CMD_INVALID, "move", expected_syntax); |
@@ -152,6 +174,37 @@ static struct cmd_results *cmd_move_workspace(struct sway_container *current, | |||
152 | current = container_parent(current, C_WORKSPACE); | 174 | current = container_parent(current, C_WORKSPACE); |
153 | } | 175 | } |
154 | container_move_to(current, destination); | 176 | container_move_to(current, destination); |
177 | |||
178 | struct sway_transaction *txn = transaction_create(); | ||
179 | arrange_windows(source, txn); | ||
180 | arrange_windows(destination, txn); | ||
181 | transaction_commit(txn); | ||
182 | |||
183 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
184 | } | ||
185 | |||
186 | static struct cmd_results *move_in_direction(struct sway_container *container, | ||
187 | enum movement_direction direction, int move_amt) { | ||
188 | if (container->type == C_WORKSPACE) { | ||
189 | return cmd_results_new(CMD_FAILURE, "move", | ||
190 | "Cannot move workspaces in a direction"); | ||
191 | } | ||
192 | // For simplicity, we'll arrange the entire workspace. The reason for this | ||
193 | // is moving the container might reap the old parent, and container_move | ||
194 | // does not return a surviving parent. | ||
195 | // TODO: Make container_move return the surviving parent so we can arrange | ||
196 | // just that. | ||
197 | struct sway_container *old_ws = container_parent(container, C_WORKSPACE); | ||
198 | container_move(container, direction, move_amt); | ||
199 | struct sway_container *new_ws = container_parent(container, C_WORKSPACE); | ||
200 | |||
201 | struct sway_transaction *txn = transaction_create(); | ||
202 | arrange_windows(old_ws, txn); | ||
203 | if (new_ws != old_ws) { | ||
204 | arrange_windows(new_ws, txn); | ||
205 | } | ||
206 | transaction_commit(txn); | ||
207 | |||
155 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 208 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
156 | } | 209 | } |
157 | 210 | ||
@@ -173,13 +226,13 @@ struct cmd_results *cmd_move(int argc, char **argv) { | |||
173 | } | 226 | } |
174 | 227 | ||
175 | if (strcasecmp(argv[0], "left") == 0) { | 228 | if (strcasecmp(argv[0], "left") == 0) { |
176 | container_move(current, MOVE_LEFT, move_amt); | 229 | return move_in_direction(current, MOVE_LEFT, move_amt); |
177 | } else if (strcasecmp(argv[0], "right") == 0) { | 230 | } else if (strcasecmp(argv[0], "right") == 0) { |
178 | container_move(current, MOVE_RIGHT, move_amt); | 231 | return move_in_direction(current, MOVE_RIGHT, move_amt); |
179 | } else if (strcasecmp(argv[0], "up") == 0) { | 232 | } else if (strcasecmp(argv[0], "up") == 0) { |
180 | container_move(current, MOVE_UP, move_amt); | 233 | return move_in_direction(current, MOVE_UP, move_amt); |
181 | } else if (strcasecmp(argv[0], "down") == 0) { | 234 | } else if (strcasecmp(argv[0], "down") == 0) { |
182 | container_move(current, MOVE_DOWN, move_amt); | 235 | return move_in_direction(current, MOVE_DOWN, move_amt); |
183 | } else if (strcasecmp(argv[0], "container") == 0 | 236 | } else if (strcasecmp(argv[0], "container") == 0 |
184 | || strcasecmp(argv[0], "window") == 0) { | 237 | || strcasecmp(argv[0], "window") == 0) { |
185 | return cmd_move_container(current, argc, argv); | 238 | return cmd_move_container(current, argc, argv); |