aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/move.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-07-07 18:36:20 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-07-09 23:38:29 +1000
commitab8a86369c01c7146991ff4ae2ef04b0a1db06ca (patch)
tree9ec17bf453a32d7fdd7f621896c9b89c00af8755 /sway/commands/move.c
parentMerge pull request #2226 from emersion/swaylock-daemonize-after-lock (diff)
downloadsway-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.c122
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
186static struct cmd_results *move_in_direction(struct sway_container *container, 188static 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
251static const char* expected_position_syntax =
252 "Expected 'move [absolute] position <x> <y>' or "
253 "'move [absolute] position mouse'";
254
255static 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
211struct cmd_results *cmd_move(int argc, char **argv) { 308struct 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 }