diff options
author | Ian Fan <ianfan0@gmail.com> | 2018-08-05 00:16:21 +0100 |
---|---|---|
committer | Ian Fan <ianfan0@gmail.com> | 2018-08-06 14:17:58 +0100 |
commit | dd48c8a579918f34c6a3441068e6f4b7e753e09c (patch) | |
tree | 2c347d2d8dd0ace5213dfcc3b3cc1a34ab6fca28 | |
parent | commands: complete workspace implementation (diff) | |
download | sway-dd48c8a579918f34c6a3441068e6f4b7e753e09c.tar.gz sway-dd48c8a579918f34c6a3441068e6f4b7e753e09c.tar.zst sway-dd48c8a579918f34c6a3441068e6f4b7e753e09c.zip |
commands: add optional flags to move
-rw-r--r-- | sway/commands/move.c | 97 | ||||
-rw-r--r-- | sway/sway.5.scd | 19 |
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 | ||
19 | static const char* expected_syntax = | 20 | static 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 | ||
26 | static struct sway_container *output_in_direction(const char *direction, | 26 | static 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, | |||
150 | static struct cmd_results *cmd_move_workspace(struct sway_container *current, | 179 | static 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 | ||
240 | static const char* expected_position_syntax = | 278 | static 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 | ||