aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/move.c
diff options
context:
space:
mode:
authorLibravatar Ian Fan <ianfan0@gmail.com>2018-07-31 11:38:34 +0100
committerLibravatar Ian Fan <ianfan0@gmail.com>2018-08-06 14:17:58 +0100
commit69e1a421fc2ccecd93f79c9dd0537671138bb0a9 (patch)
tree4102876eb5f08897e03250929af5754410b0ca96 /sway/commands/move.c
parentcommands: complete layout implementation (diff)
downloadsway-69e1a421fc2ccecd93f79c9dd0537671138bb0a9.tar.gz
sway-69e1a421fc2ccecd93f79c9dd0537671138bb0a9.tar.zst
sway-69e1a421fc2ccecd93f79c9dd0537671138bb0a9.zip
commands: complete move implementation
Diffstat (limited to 'sway/commands/move.c')
-rw-r--r--sway/commands/move.c138
1 files changed, 76 insertions, 62 deletions
diff --git a/sway/commands/move.c b/sway/commands/move.c
index 841da4c4..b80ce936 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -20,6 +20,7 @@ static const char* expected_syntax =
20 "Expected 'move <left|right|up|down> <[px] px>' or " 20 "Expected 'move <left|right|up|down> <[px] px>' or "
21 "'move <container|window> to workspace <name>' or " 21 "'move <container|window> to workspace <name>' or "
22 "'move <container|window|workspace> to output <name|direction>' or " 22 "'move <container|window|workspace> to output <name|direction>' or "
23 "'move <container|window> to mark <mark>' or "
23 "'move position mouse'"; 24 "'move position mouse'";
24 25
25static struct sway_container *output_in_direction(const char *direction, 26static struct sway_container *output_in_direction(const char *direction,
@@ -54,19 +55,27 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
54 if ((error = checkarg(argc, "move container/window", 55 if ((error = checkarg(argc, "move container/window",
55 EXPECTED_AT_LEAST, 4))) { 56 EXPECTED_AT_LEAST, 4))) {
56 return error; 57 return error;
57 } else if (strcasecmp(argv[1], "to") == 0 58 }
58 && strcasecmp(argv[2], "workspace") == 0) { 59
59 // move container to workspace x 60 if (current->type == C_WORKSPACE) {
60 if (current->type == C_WORKSPACE) { 61 if (current->children->length == 0) {
61 if (current->children->length == 0) {
62 return cmd_results_new(CMD_FAILURE, "move",
63 "Can't move an empty workspace");
64 }
65 current = container_wrap_children(current);
66 } else if (current->type != C_CONTAINER && current->type != C_VIEW) {
67 return cmd_results_new(CMD_FAILURE, "move", 62 return cmd_results_new(CMD_FAILURE, "move",
68 "Can only move containers and views."); 63 "Can't move an empty workspace");
69 } 64 }
65 current = container_wrap_children(current);
66 } else if (current->type != C_CONTAINER && current->type != C_VIEW) {
67 return cmd_results_new(CMD_FAILURE, "move",
68 "Can only move containers and views.");
69 }
70
71 struct sway_container *old_parent = current->parent;
72 struct sway_container *old_ws = container_parent(current, C_WORKSPACE);
73 struct sway_container *destination = NULL;
74
75 // determine destination
76 if (strcasecmp(argv[1], "to") == 0
77 && strcasecmp(argv[2], "workspace") == 0) {
78 // move container to workspace x
70 struct sway_container *ws; 79 struct sway_container *ws;
71 char *ws_name = NULL; 80 char *ws_name = NULL;
72 if (argc == 5 && strcasecmp(argv[3], "number") == 0) { 81 if (argc == 5 && strcasecmp(argv[3], "number") == 0) {
@@ -80,8 +89,7 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
80 89
81 if (config->auto_back_and_forth && prev_workspace_name) { 90 if (config->auto_back_and_forth && prev_workspace_name) {
82 // auto back and forth move 91 // auto back and forth move
83 struct sway_container *curr_ws = container_parent(current, C_WORKSPACE); 92 if (old_ws->name && strcmp(old_ws->name, ws_name) == 0) {
84 if (curr_ws->name && strcmp(curr_ws->name, ws_name) == 0) {
85 // if target workspace is the current one 93 // if target workspace is the current one
86 free(ws_name); 94 free(ws_name);
87 ws_name = strdup(prev_workspace_name); 95 ws_name = strdup(prev_workspace_name);
@@ -93,63 +101,50 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
93 ws = workspace_create(NULL, ws_name); 101 ws = workspace_create(NULL, ws_name);
94 } 102 }
95 free(ws_name); 103 free(ws_name);
96 struct sway_container *old_parent = current->parent;
97 struct sway_container *old_ws = container_parent(current, C_WORKSPACE);
98 struct sway_container *destination = seat_get_focus_inactive(
99 config->handler_context.seat, ws);
100 container_move_to(current, destination);
101 struct sway_container *focus = seat_get_focus_inactive(
102 config->handler_context.seat, old_parent);
103 seat_set_focus_warp(config->handler_context.seat, focus, true, false);
104 container_reap_empty(old_parent);
105 container_reap_empty(destination->parent);
106
107 // TODO: Ideally we would arrange the surviving parent after reaping,
108 // but container_reap_empty does not return it, so we arrange the
109 // workspace instead.
110 arrange_windows(old_ws);
111 arrange_windows(destination->parent);
112 104
113 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 105 destination = seat_get_focus_inactive(config->handler_context.seat, ws);
114 } else if (strcasecmp(argv[1], "to") == 0 106 } else if (strcasecmp(argv[1], "to") == 0
115 && strcasecmp(argv[2], "output") == 0) { 107 && strcasecmp(argv[2], "output") == 0) {
116 if (current->type == C_WORKSPACE) {
117 // TODO: Wrap children in a container and move that
118 return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
119 } else if (current->type != C_CONTAINER
120 && current->type != C_VIEW) {
121 return cmd_results_new(CMD_FAILURE, "move",
122 "Can only move containers and views.");
123 }
124 struct sway_container *source = container_parent(current, C_OUTPUT); 108 struct sway_container *source = container_parent(current, C_OUTPUT);
125 struct sway_container *destination = output_in_direction(argv[3], 109 struct sway_container *dest_output = output_in_direction(argv[3],
126 source->sway_output->wlr_output, current->x, current->y); 110 source->sway_output->wlr_output, current->x, current->y);
127 if (!destination) { 111 if (!dest_output) {
128 return cmd_results_new(CMD_FAILURE, "move workspace", 112 return cmd_results_new(CMD_FAILURE, "move workspace",
129 "Can't find output with name/direction '%s'", argv[3]); 113 "Can't find output with name/direction '%s'", argv[3]);
130 } 114 }
131 struct sway_container *focus = seat_get_focus_inactive( 115 destination = seat_get_focus_inactive(
132 config->handler_context.seat, destination); 116 config->handler_context.seat, dest_output);
133 if (!focus) { 117 if (!destination) {
134 // We've never been to this output before 118 // We've never been to this output before
135 focus = destination->children->items[0]; 119 destination = dest_output->children->items[0];
136 } 120 }
137 struct sway_container *old_parent = current->parent; 121 } else if (strcasecmp(argv[1], "to") == 0
138 struct sway_container *old_ws = container_parent(current, C_WORKSPACE); 122 && strcasecmp(argv[2], "mark") == 0) {
139 container_move_to(current, focus); 123 struct sway_view *dest_view = view_find_mark(argv[3]);
140 seat_set_focus_warp(config->handler_context.seat, old_parent, true, false); 124 if (dest_view == NULL) {
141 container_reap_empty(old_parent); 125 return cmd_results_new(CMD_FAILURE, "move",
142 container_reap_empty(focus->parent); 126 "Mark '%s' not found", argv[3]);
127 }
128 destination = dest_view->swayc;
129 } else {
130 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
131 }
143 132
144 // TODO: Ideally we would arrange the surviving parent after reaping, 133 // move container, arrange windows and return focus
145 // but container_reap_empty does not return it, so we arrange the 134 container_move_to(current, destination);
146 // workspace instead. 135 struct sway_container *focus =
147 arrange_windows(old_ws); 136 seat_get_focus_inactive(config->handler_context.seat, old_parent);
148 arrange_windows(focus->parent); 137 seat_set_focus_warp(config->handler_context.seat, focus, true, false);
138 container_reap_empty(old_parent);
139 container_reap_empty(destination->parent);
149 140
150 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 141 // TODO: Ideally we would arrange the surviving parent after reaping,
151 } 142 // but container_reap_empty does not return it, so we arrange the
152 return cmd_results_new(CMD_INVALID, "move", expected_syntax); 143 // workspace instead.
144 arrange_windows(old_ws);
145 arrange_windows(destination->parent);
146
147 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
153} 148}
154 149
155static struct cmd_results *cmd_move_workspace(struct sway_container *current, 150static struct cmd_results *cmd_move_workspace(struct sway_container *current,
@@ -243,8 +238,8 @@ static struct cmd_results *move_in_direction(struct sway_container *container,
243} 238}
244 239
245static const char* expected_position_syntax = 240static const char* expected_position_syntax =
246 "Expected 'move [absolute] position <x> <y>' or " 241 "Expected 'move [absolute] position <x> [px] <y> [px]' or "
247 "'move [absolute] position mouse'"; 242 "'move [absolute] position center|mouse'";
248 243
249static struct cmd_results *move_to_position(struct sway_container *container, 244static struct cmd_results *move_to_position(struct sway_container *container,
250 int argc, char **argv) { 245 int argc, char **argv) {
@@ -279,10 +274,18 @@ static struct cmd_results *move_to_position(struct sway_container *container,
279 double ly = seat->cursor->cursor->y - container->height / 2; 274 double ly = seat->cursor->cursor->y - container->height / 2;
280 container_floating_move_to(container, lx, ly); 275 container_floating_move_to(container, lx, ly);
281 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 276 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
277 } else if (strcmp(argv[0], "center") == 0) {
278 struct sway_container *ws = container_parent(container, C_WORKSPACE);
279 double lx = ws->x + (ws->width - container->width) / 2;
280 double ly = ws->y + (ws->height - container->height) / 2;
281 container_floating_move_to(container, lx, ly);
282 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
282 } 283 }
283 if (argc != 2) { 284
285 if (argc < 2) {
284 return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax); 286 return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax);
285 } 287 }
288
286 double lx, ly; 289 double lx, ly;
287 char *inv; 290 char *inv;
288 lx = (double)strtol(argv[0], &inv, 10); 291 lx = (double)strtol(argv[0], &inv, 10);
@@ -290,11 +293,22 @@ static struct cmd_results *move_to_position(struct sway_container *container,
290 return cmd_results_new(CMD_FAILURE, "move", 293 return cmd_results_new(CMD_FAILURE, "move",
291 "Invalid position specified"); 294 "Invalid position specified");
292 } 295 }
296 if (strcmp(argv[1], "px") == 0) {
297 --argc;
298 ++argv;
299 }
300
301 if (argc > 3) {
302 return cmd_results_new(CMD_FAILURE, "move", expected_position_syntax);
303 }
304
293 ly = (double)strtol(argv[1], &inv, 10); 305 ly = (double)strtol(argv[1], &inv, 10);
294 if (*inv != '\0' && strcasecmp(inv, "px") != 0) { 306 if ((*inv != '\0' && strcasecmp(inv, "px") != 0) ||
307 (argc == 3 && strcmp(argv[2], "px") != 0)) {
295 return cmd_results_new(CMD_FAILURE, "move", 308 return cmd_results_new(CMD_FAILURE, "move",
296 "Invalid position specified"); 309 "Invalid position specified");
297 } 310 }
311
298 container_floating_move_to(container, lx, ly); 312 container_floating_move_to(container, lx, ly);
299 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 313 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
300} 314}