summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Ian Fan <ianfan0@gmail.com>2018-08-05 00:16:21 +0100
committerLibravatar Ian Fan <ianfan0@gmail.com>2018-08-06 14:17:58 +0100
commitdd48c8a579918f34c6a3441068e6f4b7e753e09c (patch)
tree2c347d2d8dd0ace5213dfcc3b3cc1a34ab6fca28
parentcommands: complete workspace implementation (diff)
downloadsway-dd48c8a579918f34c6a3441068e6f4b7e753e09c.tar.gz
sway-dd48c8a579918f34c6a3441068e6f4b7e753e09c.tar.zst
sway-dd48c8a579918f34c6a3441068e6f4b7e753e09c.zip
commands: add optional flags to move
-rw-r--r--sway/commands/move.c97
-rw-r--r--sway/sway.5.scd19
2 files changed, 81 insertions, 35 deletions
diff --git a/sway/commands/move.c b/sway/commands/move.c
index b80ce936..d49d6862 100644
--- a/sway/commands/move.c
+++ b/sway/commands/move.c
@@ -1,4 +1,5 @@
1#define _XOPEN_SOURCE 500 1#define _XOPEN_SOURCE 500
2#include <stdbool.h>
2#include <string.h> 3#include <string.h>
3#include <strings.h> 4#include <strings.h>
4#include <wlr/types/wlr_cursor.h> 5#include <wlr/types/wlr_cursor.h>
@@ -16,12 +17,11 @@
16#include "stringop.h" 17#include "stringop.h"
17#include "list.h" 18#include "list.h"
18 19
19static const char* expected_syntax = 20static const char *expected_syntax =
20 "Expected 'move <left|right|up|down> <[px] px>' or " 21 "Expected 'move <left|right|up|down> <[px] px>' or "
21 "'move <container|window> to workspace <name>' or " 22 "'move [--no-auto-back-and-forth] <container|window> [to] workspace <name>' or "
22 "'move <container|window|workspace> to output <name|direction>' or " 23 "'move [--no-auto-back-and-forth] <container|window|workspace> [to] output <name|direction>' or "
23 "'move <container|window> to mark <mark>' or " 24 "'move <container|window> [to] mark <mark>'";
24 "'move position mouse'";
25 25
26static struct sway_container *output_in_direction(const char *direction, 26static struct sway_container *output_in_direction(const char *direction,
27 struct wlr_output *reference, int ref_lx, int ref_ly) { 27 struct wlr_output *reference, int ref_lx, int ref_ly) {
@@ -53,7 +53,7 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
53 int argc, char **argv) { 53 int argc, char **argv) {
54 struct cmd_results *error = NULL; 54 struct cmd_results *error = NULL;
55 if ((error = checkarg(argc, "move container/window", 55 if ((error = checkarg(argc, "move container/window",
56 EXPECTED_AT_LEAST, 4))) { 56 EXPECTED_AT_LEAST, 3))) {
57 return error; 57 return error;
58 } 58 }
59 59
@@ -68,26 +68,52 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
68 "Can only move containers and views."); 68 "Can only move containers and views.");
69 } 69 }
70 70
71 bool no_auto_back_and_forth = false;
72 while (strcasecmp(argv[0], "--no-auto-back-and-forth") == 0) {
73 no_auto_back_and_forth = true;
74 if (--argc < 3) {
75 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
76 }
77 ++argv;
78 }
79 while (strcasecmp(argv[1], "--no-auto-back-and-forth") == 0) {
80 no_auto_back_and_forth = true;
81 if (--argc < 3) {
82 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
83 }
84 argv++;
85 }
86
87 while (strcasecmp(argv[1], "to") == 0) {
88 if (--argc < 3) {
89 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
90 }
91 argv++;
92 }
93
71 struct sway_container *old_parent = current->parent; 94 struct sway_container *old_parent = current->parent;
72 struct sway_container *old_ws = container_parent(current, C_WORKSPACE); 95 struct sway_container *old_ws = container_parent(current, C_WORKSPACE);
73 struct sway_container *destination = NULL; 96 struct sway_container *destination = NULL;
74 97
75 // determine destination 98 // determine destination
76 if (strcasecmp(argv[1], "to") == 0 99 if (strcasecmp(argv[1], "workspace") == 0) {
77 && strcasecmp(argv[2], "workspace") == 0) {
78 // move container to workspace x 100 // move container to workspace x
79 struct sway_container *ws; 101 struct sway_container *ws;
80 char *ws_name = NULL; 102 char *ws_name = NULL;
81 if (argc == 5 && strcasecmp(argv[3], "number") == 0) { 103 if (strcasecmp(argv[2], "number") == 0) {
82 // move "container to workspace number x" 104 // move "container to workspace number x"
83 ws_name = strdup(argv[4]); 105 if (argc < 4) {
106 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
107 }
108 ws_name = strdup(argv[3]);
84 ws = workspace_by_number(ws_name); 109 ws = workspace_by_number(ws_name);
85 } else { 110 } else {
86 ws_name = join_args(argv + 3, argc - 3); 111 ws_name = join_args(argv + 2, argc - 2);
87 ws = workspace_by_name(ws_name); 112 ws = workspace_by_name(ws_name);
88 } 113 }
89 114
90 if (config->auto_back_and_forth && prev_workspace_name) { 115 if (!no_auto_back_and_forth && config->auto_back_and_forth &&
116 prev_workspace_name) {
91 // auto back and forth move 117 // auto back and forth move
92 if (old_ws->name && strcmp(old_ws->name, ws_name) == 0) { 118 if (old_ws->name && strcmp(old_ws->name, ws_name) == 0) {
93 // if target workspace is the current one 119 // if target workspace is the current one
@@ -98,19 +124,23 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
98 } 124 }
99 125
100 if (!ws) { 126 if (!ws) {
127 if (strcasecmp(argv[2], "back_and_forth") == 0) {
128 if (prev_workspace_name) {
129 ws = workspace_create(NULL, prev_workspace_name);
130 }
131 }
101 ws = workspace_create(NULL, ws_name); 132 ws = workspace_create(NULL, ws_name);
102 } 133 }
103 free(ws_name); 134 free(ws_name);
104 135
105 destination = seat_get_focus_inactive(config->handler_context.seat, ws); 136 destination = seat_get_focus_inactive(config->handler_context.seat, ws);
106 } else if (strcasecmp(argv[1], "to") == 0 137 } else if (strcasecmp(argv[1], "output") == 0) {
107 && strcasecmp(argv[2], "output") == 0) {
108 struct sway_container *source = container_parent(current, C_OUTPUT); 138 struct sway_container *source = container_parent(current, C_OUTPUT);
109 struct sway_container *dest_output = output_in_direction(argv[3], 139 struct sway_container *dest_output = output_in_direction(argv[2],
110 source->sway_output->wlr_output, current->x, current->y); 140 source->sway_output->wlr_output, current->x, current->y);
111 if (!dest_output) { 141 if (!dest_output) {
112 return cmd_results_new(CMD_FAILURE, "move workspace", 142 return cmd_results_new(CMD_FAILURE, "move workspace",
113 "Can't find output with name/direction '%s'", argv[3]); 143 "Can't find output with name/direction '%s'", argv[2]);
114 } 144 }
115 destination = seat_get_focus_inactive( 145 destination = seat_get_focus_inactive(
116 config->handler_context.seat, dest_output); 146 config->handler_context.seat, dest_output);
@@ -118,12 +148,11 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
118 // We've never been to this output before 148 // We've never been to this output before
119 destination = dest_output->children->items[0]; 149 destination = dest_output->children->items[0];
120 } 150 }
121 } else if (strcasecmp(argv[1], "to") == 0 151 } else if (strcasecmp(argv[1], "mark") == 0) {
122 && strcasecmp(argv[2], "mark") == 0) { 152 struct sway_view *dest_view = view_find_mark(argv[2]);
123 struct sway_view *dest_view = view_find_mark(argv[3]);
124 if (dest_view == NULL) { 153 if (dest_view == NULL) {
125 return cmd_results_new(CMD_FAILURE, "move", 154 return cmd_results_new(CMD_FAILURE, "move",
126 "Mark '%s' not found", argv[3]); 155 "Mark '%s' not found", argv[2]);
127 } 156 }
128 destination = dest_view->swayc; 157 destination = dest_view->swayc;
129 } else { 158 } else {
@@ -150,20 +179,29 @@ static struct cmd_results *cmd_move_container(struct sway_container *current,
150static struct cmd_results *cmd_move_workspace(struct sway_container *current, 179static struct cmd_results *cmd_move_workspace(struct sway_container *current,
151 int argc, char **argv) { 180 int argc, char **argv) {
152 struct cmd_results *error = NULL; 181 struct cmd_results *error = NULL;
153 if ((error = checkarg(argc, "move workspace", EXPECTED_EQUAL_TO, 4))) { 182 if ((error = checkarg(argc, "move workspace", EXPECTED_AT_LEAST, 2))) {
154 return error; 183 return error;
155 } else if (strcasecmp(argv[1], "to") != 0 184 }
156 || strcasecmp(argv[2], "output") != 0) { 185
186 while (strcasecmp(argv[1], "to") == 0) {
187 if (--argc < 3) {
188 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
189 }
190 ++argv;
191 }
192
193 if (strcasecmp(argv[1], "output") != 0) {
157 return cmd_results_new(CMD_INVALID, "move", expected_syntax); 194 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
158 } 195 }
196
159 struct sway_container *source = container_parent(current, C_OUTPUT); 197 struct sway_container *source = container_parent(current, C_OUTPUT);
160 int center_x = current->width / 2 + current->x, 198 int center_x = current->width / 2 + current->x,
161 center_y = current->height / 2 + current->y; 199 center_y = current->height / 2 + current->y;
162 struct sway_container *destination = output_in_direction(argv[3], 200 struct sway_container *destination = output_in_direction(argv[2],
163 source->sway_output->wlr_output, center_x, center_y); 201 source->sway_output->wlr_output, center_x, center_y);
164 if (!destination) { 202 if (!destination) {
165 return cmd_results_new(CMD_FAILURE, "move workspace", 203 return cmd_results_new(CMD_FAILURE, "move workspace",
166 "Can't find output with name/direction '%s'", argv[3]); 204 "Can't find output with name/direction '%s'", argv[2]);
167 } 205 }
168 if (current->type != C_WORKSPACE) { 206 if (current->type != C_WORKSPACE) {
169 current = container_parent(current, C_WORKSPACE); 207 current = container_parent(current, C_WORKSPACE);
@@ -237,7 +275,7 @@ static struct cmd_results *move_in_direction(struct sway_container *container,
237 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 275 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
238} 276}
239 277
240static const char* expected_position_syntax = 278static const char *expected_position_syntax =
241 "Expected 'move [absolute] position <x> [px] <y> [px]' or " 279 "Expected 'move [absolute] position <x> [px] <y> [px]' or "
242 "'move [absolute] position center|mouse'"; 280 "'move [absolute] position center|mouse'";
243 281
@@ -356,8 +394,11 @@ struct cmd_results *cmd_move(int argc, char **argv) {
356 return move_in_direction(current, MOVE_UP, argc, argv); 394 return move_in_direction(current, MOVE_UP, argc, argv);
357 } else if (strcasecmp(argv[0], "down") == 0) { 395 } else if (strcasecmp(argv[0], "down") == 0) {
358 return move_in_direction(current, MOVE_DOWN, argc, argv); 396 return move_in_direction(current, MOVE_DOWN, argc, argv);
359 } else if (strcasecmp(argv[0], "container") == 0 397 } else if ((strcasecmp(argv[0], "container") == 0
360 || strcasecmp(argv[0], "window") == 0) { 398 || strcasecmp(argv[0], "window") == 0) ||
399 (strcasecmp(argv[0], "--no-auto-back-and-forth") &&
400 (strcasecmp(argv[0], "container") == 0
401 || strcasecmp(argv[0], "window") == 0))) {
361 return cmd_move_container(current, argc, argv); 402 return cmd_move_container(current, argc, argv);
362 } else if (strcasecmp(argv[0], "workspace") == 0) { 403 } else if (strcasecmp(argv[0], "workspace") == 0) {
363 return cmd_move_workspace(current, argc, argv); 404 return cmd_move_workspace(current, argc, argv);
diff --git a/sway/sway.5.scd b/sway/sway.5.scd
index 36ce13df..b43cbe8d 100644
--- a/sway/sway.5.scd
+++ b/sway/sway.5.scd
@@ -135,24 +135,29 @@ They are expected to be used with *bindsym* or at runtime through *swaymsg*(1).
135*move* [absolute] position center|mouse 135*move* [absolute] position center|mouse
136 Moves the focused container to be centered on the workspace or mouse. 136 Moves the focused container to be centered on the workspace or mouse.
137 137
138*move* container|window to mark <mark> 138*move* container|window [to] mark <mark>
139 Moves the focused container to the specified mark. 139 Moves the focused container to the specified mark.
140 140
141*move* container|window to workspace <name> 141*move* [--no-auto-back-and-forth] container|window [to] workspace [number] <name>
142 Moves the focused container to the specified workspace. 142 Moves the focused container to the specified workspace. The string "number"
143 is optional and is used to match a workspace with the same number, even if
144 it has a different name.
143 145
144*move* container|window to workspace prev|next|current 146*move* container|window [to] workspace prev|next|current
145 Moves the focused container to the previous, next or current workspace on 147 Moves the focused container to the previous, next or current workspace on
146 this output, or if no workspaces remain, the previous or next output. 148 this output, or if no workspaces remain, the previous or next output.
147 149
148*move* container|window to workspace prev\_on\_output|next\_on\_output 150*move* container|window [to] workspace prev\_on\_output|next\_on\_output
149 Moves the focused container to the previous or next workspace on this 151 Moves the focused container to the previous or next workspace on this
150 output, wrapping around if already at the first or last workspace. 152 output, wrapping around if already at the first or last workspace.
151 153
152*move* container|window|workspace to output <name> 154*move* container|window [to] workspace back_and_forth
155 Moves the focused container to previously focused workspace.
156
157*move* container|window|workspace [to] output <name>
153 Moves the focused container or workspace to the specified output. 158 Moves the focused container or workspace to the specified output.
154 159
155*move* container|window|workspace to output up|right|down|left 160*move* container|window|workspace [to] output up|right|down|left
156 Moves the focused container or workspace to next output in the specified 161 Moves the focused container or workspace to next output in the specified
157 direction. 162 direction.
158 163