diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-07-07 18:36:20 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-07-09 23:38:29 +1000 |
commit | ab8a86369c01c7146991ff4ae2ef04b0a1db06ca (patch) | |
tree | 9ec17bf453a32d7fdd7f621896c9b89c00af8755 /sway/commands/move.c | |
parent | Merge pull request #2226 from emersion/swaylock-daemonize-after-lock (diff) | |
download | sway-ab8a86369c01c7146991ff4ae2ef04b0a1db06ca.tar.gz sway-ab8a86369c01c7146991ff4ae2ef04b0a1db06ca.tar.zst sway-ab8a86369c01c7146991ff4ae2ef04b0a1db06ca.zip |
Implement some floating move commands
This implements the following for floating containers:
* move <direction> <amount>
* move [absolute] position <x> <y>
* move [absolute] position mouse
Diffstat (limited to 'sway/commands/move.c')
-rw-r--r-- | sway/commands/move.c | 122 |
1 files changed, 105 insertions, 17 deletions
diff --git a/sway/commands/move.c b/sway/commands/move.c index a4fae388..a1c1e018 100644 --- a/sway/commands/move.c +++ b/sway/commands/move.c | |||
@@ -1,11 +1,13 @@ | |||
1 | #define _XOPEN_SOURCE 500 | 1 | #define _XOPEN_SOURCE 500 |
2 | #include <string.h> | 2 | #include <string.h> |
3 | #include <strings.h> | 3 | #include <strings.h> |
4 | #include <wlr/types/wlr_cursor.h> | ||
4 | #include <wlr/types/wlr_output.h> | 5 | #include <wlr/types/wlr_output.h> |
5 | #include <wlr/types/wlr_output_layout.h> | 6 | #include <wlr/types/wlr_output_layout.h> |
6 | #include <wlr/util/log.h> | 7 | #include <wlr/util/log.h> |
7 | #include "sway/commands.h" | 8 | #include "sway/commands.h" |
8 | #include "sway/desktop/transaction.h" | 9 | #include "sway/desktop/transaction.h" |
10 | #include "sway/input/cursor.h" | ||
9 | #include "sway/input/seat.h" | 11 | #include "sway/input/seat.h" |
10 | #include "sway/output.h" | 12 | #include "sway/output.h" |
11 | #include "sway/tree/arrange.h" | 13 | #include "sway/tree/arrange.h" |
@@ -184,11 +186,49 @@ static struct cmd_results *cmd_move_workspace(struct sway_container *current, | |||
184 | } | 186 | } |
185 | 187 | ||
186 | static struct cmd_results *move_in_direction(struct sway_container *container, | 188 | static struct cmd_results *move_in_direction(struct sway_container *container, |
187 | enum movement_direction direction, int move_amt) { | 189 | enum movement_direction direction, int argc, char **argv) { |
190 | int move_amt = 10; | ||
191 | if (argc > 1) { | ||
192 | char *inv; | ||
193 | move_amt = (int)strtol(argv[1], &inv, 10); | ||
194 | if (*inv != '\0' && strcasecmp(inv, "px") != 0) { | ||
195 | return cmd_results_new(CMD_FAILURE, "move", | ||
196 | "Invalid distance specified"); | ||
197 | } | ||
198 | } | ||
199 | |||
188 | if (container->type == C_WORKSPACE) { | 200 | if (container->type == C_WORKSPACE) { |
189 | return cmd_results_new(CMD_FAILURE, "move", | 201 | return cmd_results_new(CMD_FAILURE, "move", |
190 | "Cannot move workspaces in a direction"); | 202 | "Cannot move workspaces in a direction"); |
191 | } | 203 | } |
204 | if (container_is_floating(container)) { | ||
205 | if (container->type == C_VIEW && container->sway_view->is_fullscreen) { | ||
206 | return cmd_results_new(CMD_FAILURE, "move", | ||
207 | "Cannot move fullscreen floating container"); | ||
208 | } | ||
209 | double lx = container->x; | ||
210 | double ly = container->y; | ||
211 | switch (direction) { | ||
212 | case MOVE_LEFT: | ||
213 | lx -= move_amt; | ||
214 | break; | ||
215 | case MOVE_RIGHT: | ||
216 | lx += move_amt; | ||
217 | break; | ||
218 | case MOVE_UP: | ||
219 | ly -= move_amt; | ||
220 | break; | ||
221 | case MOVE_DOWN: | ||
222 | ly += move_amt; | ||
223 | break; | ||
224 | case MOVE_PARENT: | ||
225 | case MOVE_CHILD: | ||
226 | return cmd_results_new(CMD_FAILURE, "move", | ||
227 | "Cannot move floating container to parent or child"); | ||
228 | } | ||
229 | container_floating_move_to(container, lx, ly); | ||
230 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
231 | } | ||
192 | // For simplicity, we'll arrange the entire workspace. The reason for this | 232 | // 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 | 233 | // is moving the container might reap the old parent, and container_move |
194 | // does not return a surviving parent. | 234 | // does not return a surviving parent. |
@@ -208,31 +248,78 @@ static struct cmd_results *move_in_direction(struct sway_container *container, | |||
208 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 248 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
209 | } | 249 | } |
210 | 250 | ||
251 | static const char* expected_position_syntax = | ||
252 | "Expected 'move [absolute] position <x> <y>' or " | ||
253 | "'move [absolute] position mouse'"; | ||
254 | |||
255 | static struct cmd_results *move_to_position(struct sway_container *container, | ||
256 | int argc, char **argv) { | ||
257 | if (!container_is_floating(container)) { | ||
258 | return cmd_results_new(CMD_FAILURE, "move", | ||
259 | "Only floating containers " | ||
260 | "can be moved to an absolute position"); | ||
261 | } | ||
262 | if (!argc) { | ||
263 | return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); | ||
264 | } | ||
265 | if (strcmp(argv[0], "absolute") == 0) { | ||
266 | --argc; | ||
267 | ++argv; | ||
268 | } | ||
269 | if (!argc) { | ||
270 | return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); | ||
271 | } | ||
272 | if (strcmp(argv[0], "position") == 0) { | ||
273 | --argc; | ||
274 | ++argv; | ||
275 | } | ||
276 | if (!argc) { | ||
277 | return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); | ||
278 | } | ||
279 | if (strcmp(argv[0], "mouse") == 0) { | ||
280 | struct sway_seat *seat = config->handler_context.seat; | ||
281 | if (!seat->cursor) { | ||
282 | return cmd_results_new(CMD_FAILURE, "move", "No cursor device"); | ||
283 | } | ||
284 | double lx = seat->cursor->cursor->x - container->width / 2; | ||
285 | double ly = seat->cursor->cursor->y - container->height / 2; | ||
286 | container_floating_move_to(container, lx, ly); | ||
287 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
288 | } | ||
289 | if (argc != 2) { | ||
290 | return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); | ||
291 | } | ||
292 | double lx, ly; | ||
293 | char *inv; | ||
294 | lx = (double)strtol(argv[0], &inv, 10); | ||
295 | if (*inv != '\0' && strcasecmp(inv, "px") != 0) { | ||
296 | return cmd_results_new(CMD_FAILURE, "move", | ||
297 | "Invalid position specified"); | ||
298 | } | ||
299 | ly = (double)strtol(argv[1], &inv, 10); | ||
300 | if (*inv != '\0' && strcasecmp(inv, "px") != 0) { | ||
301 | return cmd_results_new(CMD_FAILURE, "move", | ||
302 | "Invalid position specified"); | ||
303 | } | ||
304 | container_floating_move_to(container, lx, ly); | ||
305 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
306 | } | ||
307 | |||
211 | struct cmd_results *cmd_move(int argc, char **argv) { | 308 | struct cmd_results *cmd_move(int argc, char **argv) { |
212 | struct cmd_results *error = NULL; | 309 | struct cmd_results *error = NULL; |
213 | int move_amt = 10; | ||
214 | if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) { | 310 | if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) { |
215 | return error; | 311 | return error; |
216 | } | 312 | } |
217 | struct sway_container *current = config->handler_context.current_container; | 313 | struct sway_container *current = config->handler_context.current_container; |
218 | 314 | ||
219 | if (argc == 2 || (argc == 3 && strcasecmp(argv[2], "px") == 0)) { | ||
220 | char *inv; | ||
221 | move_amt = (int)strtol(argv[1], &inv, 10); | ||
222 | if (*inv != '\0' && strcasecmp(inv, "px") != 0) { | ||
223 | return cmd_results_new(CMD_FAILURE, "move", | ||
224 | "Invalid distance specified"); | ||
225 | } | ||
226 | } | ||
227 | |||
228 | if (strcasecmp(argv[0], "left") == 0) { | 315 | if (strcasecmp(argv[0], "left") == 0) { |
229 | return move_in_direction(current, MOVE_LEFT, move_amt); | 316 | return move_in_direction(current, MOVE_LEFT, argc, argv); |
230 | } else if (strcasecmp(argv[0], "right") == 0) { | 317 | } else if (strcasecmp(argv[0], "right") == 0) { |
231 | return move_in_direction(current, MOVE_RIGHT, move_amt); | 318 | return move_in_direction(current, MOVE_RIGHT, argc, argv); |
232 | } else if (strcasecmp(argv[0], "up") == 0) { | 319 | } else if (strcasecmp(argv[0], "up") == 0) { |
233 | return move_in_direction(current, MOVE_UP, move_amt); | 320 | return move_in_direction(current, MOVE_UP, argc, argv); |
234 | } else if (strcasecmp(argv[0], "down") == 0) { | 321 | } else if (strcasecmp(argv[0], "down") == 0) { |
235 | return move_in_direction(current, MOVE_DOWN, move_amt); | 322 | return move_in_direction(current, MOVE_DOWN, argc, argv); |
236 | } else if (strcasecmp(argv[0], "container") == 0 | 323 | } else if (strcasecmp(argv[0], "container") == 0 |
237 | || strcasecmp(argv[0], "window") == 0) { | 324 | || strcasecmp(argv[0], "window") == 0) { |
238 | return cmd_move_container(current, argc, argv); | 325 | return cmd_move_container(current, argc, argv); |
@@ -244,8 +331,9 @@ struct cmd_results *cmd_move(int argc, char **argv) { | |||
244 | // TODO: scratchpad | 331 | // TODO: scratchpad |
245 | return cmd_results_new(CMD_FAILURE, "move", "Unimplemented"); | 332 | return cmd_results_new(CMD_FAILURE, "move", "Unimplemented"); |
246 | } else if (strcasecmp(argv[0], "position") == 0) { | 333 | } else if (strcasecmp(argv[0], "position") == 0) { |
247 | // TODO: floating | 334 | return move_to_position(current, argc, argv); |
248 | return cmd_results_new(CMD_FAILURE, "move", "Unimplemented"); | 335 | } else if (strcasecmp(argv[0], "absolute") == 0) { |
336 | return move_to_position(current, argc, argv); | ||
249 | } else { | 337 | } else { |
250 | return cmd_results_new(CMD_INVALID, "move", expected_syntax); | 338 | return cmd_results_new(CMD_INVALID, "move", expected_syntax); |
251 | } | 339 | } |