aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands
diff options
context:
space:
mode:
authorLibravatar Tony Crisci <tony@dubstepdish.com>2018-04-02 13:23:43 -0400
committerLibravatar Tony Crisci <tony@dubstepdish.com>2018-04-02 13:23:43 -0400
commit5e024278a62e6fb00a0521240244c428d2382984 (patch)
treed9010d33d4d576297cc5e40d41bed4bb7bf5631a /sway/commands
parentdont copy input config (diff)
parentMerge pull request #1697 from RedSoxFan/back-and-forth (diff)
downloadsway-5e024278a62e6fb00a0521240244c428d2382984.tar.gz
sway-5e024278a62e6fb00a0521240244c428d2382984.tar.zst
sway-5e024278a62e6fb00a0521240244c428d2382984.zip
Merge branch 'wlroots' into seat-fixes
Diffstat (limited to 'sway/commands')
-rw-r--r--sway/commands/focus.c7
-rw-r--r--sway/commands/move.c184
2 files changed, 186 insertions, 5 deletions
diff --git a/sway/commands/focus.c b/sway/commands/focus.c
index 4fb732dd..74d9d535 100644
--- a/sway/commands/focus.c
+++ b/sway/commands/focus.c
@@ -20,10 +20,6 @@ static bool parse_movement_direction(const char *name,
20 *out = MOVE_PARENT; 20 *out = MOVE_PARENT;
21 } else if (strcasecmp(name, "child") == 0) { 21 } else if (strcasecmp(name, "child") == 0) {
22 *out = MOVE_CHILD; 22 *out = MOVE_CHILD;
23 } else if (strcasecmp(name, "next") == 0) {
24 *out = MOVE_NEXT;
25 } else if (strcasecmp(name, "prev") == 0) {
26 *out = MOVE_PREV;
27 } else { 23 } else {
28 return false; 24 return false;
29 } 25 }
@@ -51,7 +47,8 @@ struct cmd_results *cmd_focus(int argc, char **argv) {
51 "Expected 'focus <direction|parent|child|mode_toggle>' or 'focus output <direction|name>'"); 47 "Expected 'focus <direction|parent|child|mode_toggle>' or 'focus output <direction|name>'");
52 } 48 }
53 49
54 struct sway_container *next_focus = container_get_in_direction(con, seat, direction); 50 struct sway_container *next_focus = container_get_in_direction(
51 con, seat, direction);
55 if (next_focus) { 52 if (next_focus) {
56 seat_set_focus(seat, next_focus); 53 seat_set_focus(seat, next_focus);
57 } 54 }
diff --git a/sway/commands/move.c b/sway/commands/move.c
new file mode 100644
index 00000000..644c622b
--- /dev/null
+++ b/sway/commands/move.c
@@ -0,0 +1,184 @@
1#include <string.h>
2#include <strings.h>
3#include <wlr/types/wlr_output.h>
4#include <wlr/types/wlr_output_layout.h>
5#include <wlr/util/log.h>
6#include "sway/commands.h"
7#include "sway/input/seat.h"
8#include "sway/output.h"
9#include "sway/tree/container.h"
10#include "sway/tree/layout.h"
11#include "sway/tree/workspace.h"
12#include "stringop.h"
13#include "list.h"
14
15static const char* expected_syntax =
16 "Expected 'move <left|right|up|down> <[px] px>' or "
17 "'move <container|window> to workspace <name>' or "
18 "'move <container|window|workspace> to output <name|direction>' or "
19 "'move position mouse'";
20
21static struct sway_container *output_in_direction(const char *direction,
22 struct wlr_output *reference, int ref_ox, int ref_oy) {
23 int ref_lx = ref_ox + reference->lx,
24 ref_ly = ref_oy + reference->ly;
25 struct {
26 char *name;
27 enum wlr_direction direction;
28 } names[] = {
29 { "up", WLR_DIRECTION_UP },
30 { "down", WLR_DIRECTION_DOWN },
31 { "left", WLR_DIRECTION_LEFT },
32 { "right", WLR_DIRECTION_RIGHT },
33 };
34 for (size_t i = 0; i < sizeof(names) / sizeof(names[0]); ++i) {
35 if (strcasecmp(names[i].name, direction) == 0) {
36 struct wlr_output *adjacent = wlr_output_layout_adjacent_output(
37 root_container.sway_root->output_layout,
38 names[i].direction, reference, ref_lx, ref_ly);
39 if (adjacent) {
40 struct sway_output *sway_output = adjacent->data;
41 return sway_output->swayc;
42 }
43 break;
44 }
45 }
46 return output_by_name(direction);
47}
48
49static struct cmd_results *cmd_move_container(struct sway_container *current,
50 int argc, char **argv) {
51 struct cmd_results *error = NULL;
52 if ((error = checkarg(argc, "move container/window",
53 EXPECTED_AT_LEAST, 4))) {
54 return error;
55 } else if (strcasecmp(argv[1], "to") == 0
56 && strcasecmp(argv[2], "workspace") == 0) {
57 // move container to workspace x
58 if (current->type == C_WORKSPACE) {
59 // TODO: Wrap children in a container and move that
60 return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
61 } else if (current->type != C_CONTAINER && current->type != C_VIEW) {
62 return cmd_results_new(CMD_FAILURE, "move",
63 "Can only move containers and views.");
64 }
65 struct sway_container *ws;
66 const char *num_name = NULL;
67 char *ws_name = NULL;
68 if (argc == 5 && strcasecmp(argv[3], "number") == 0) {
69 // move "container to workspace number x"
70 num_name = argv[4];
71 ws = workspace_by_number(num_name);
72 } else {
73 ws_name = join_args(argv + 3, argc - 3);
74 ws = workspace_by_name(ws_name);
75 }
76 if (!ws) {
77 ws = workspace_create(ws_name ? ws_name : num_name);
78 }
79 free(ws_name);
80 struct sway_container *old_parent = current->parent;
81 struct sway_container *focus = seat_get_focus_inactive(
82 config->handler_context.seat, ws);
83 container_move_to(current, focus);
84 seat_set_focus(config->handler_context.seat, old_parent);
85 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
86 } else if (strcasecmp(argv[1], "to") == 0
87 && strcasecmp(argv[2], "output") == 0) {
88 if (current->type == C_WORKSPACE) {
89 // TODO: Wrap children in a container and move that
90 return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
91 } else if (current->type != C_CONTAINER
92 && current->type != C_VIEW) {
93 return cmd_results_new(CMD_FAILURE, "move",
94 "Can only move containers and views.");
95 }
96 struct sway_container *source = container_parent(current, C_OUTPUT);
97 struct sway_container *destination = output_in_direction(argv[3],
98 source->sway_output->wlr_output, current->x, current->y);
99 if (!destination) {
100 return cmd_results_new(CMD_FAILURE, "move workspace",
101 "Can't find output with name/direction '%s'", argv[3]);
102 }
103 struct sway_container *focus = seat_get_focus_inactive(
104 config->handler_context.seat, destination);
105 if (!focus) {
106 // We've never been to this output before
107 focus = destination->children->items[0];
108 }
109 struct sway_container *old_parent = current->parent;
110 container_move_to(current, focus);
111 seat_set_focus(config->handler_context.seat, old_parent);
112 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
113 }
114 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
115}
116
117static struct cmd_results *cmd_move_workspace(struct sway_container *current,
118 int argc, char **argv) {
119 struct cmd_results *error = NULL;
120 if ((error = checkarg(argc, "move workspace", EXPECTED_EQUAL_TO, 4))) {
121 return error;
122 } else if (strcasecmp(argv[1], "to") != 0
123 || strcasecmp(argv[2], "output") != 0) {
124 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
125 }
126 struct sway_container *source = container_parent(current, C_OUTPUT);
127 int center_x = current->width / 2 + current->x,
128 center_y = current->height / 2 + current->y;
129 struct sway_container *destination = output_in_direction(argv[3],
130 source->sway_output->wlr_output, center_x, center_y);
131 if (!destination) {
132 return cmd_results_new(CMD_FAILURE, "move workspace",
133 "Can't find output with name/direction '%s'", argv[3]);
134 }
135 if (current->type != C_WORKSPACE) {
136 current = container_parent(current, C_WORKSPACE);
137 }
138 container_move_to(current, destination);
139 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
140}
141
142struct cmd_results *cmd_move(int argc, char **argv) {
143 struct cmd_results *error = NULL;
144 int move_amt = 10;
145 if ((error = checkarg(argc, "move", EXPECTED_AT_LEAST, 1))) {
146 return error;
147 }
148 struct sway_container *current = config->handler_context.current_container;
149
150 if (argc == 2 || (argc == 3 && strcasecmp(argv[2], "px") == 0)) {
151 char *inv;
152 move_amt = (int)strtol(argv[1], &inv, 10);
153 if (*inv != '\0' && strcasecmp(inv, "px") != 0) {
154 return cmd_results_new(CMD_FAILURE, "move",
155 "Invalid distance specified");
156 }
157 }
158
159 if (strcasecmp(argv[0], "left") == 0) {
160 container_move(current, MOVE_LEFT, move_amt);
161 } else if (strcasecmp(argv[0], "right") == 0) {
162 container_move(current, MOVE_RIGHT, move_amt);
163 } else if (strcasecmp(argv[0], "up") == 0) {
164 container_move(current, MOVE_UP, move_amt);
165 } else if (strcasecmp(argv[0], "down") == 0) {
166 container_move(current, MOVE_DOWN, move_amt);
167 } else if (strcasecmp(argv[0], "container") == 0
168 || strcasecmp(argv[0], "window") == 0) {
169 return cmd_move_container(current, argc, argv);
170 } else if (strcasecmp(argv[0], "workspace") == 0) {
171 return cmd_move_workspace(current, argc, argv);
172 } else if (strcasecmp(argv[0], "scratchpad") == 0
173 || (strcasecmp(argv[0], "to") == 0
174 && strcasecmp(argv[1], "scratchpad") == 0)) {
175 // TODO: scratchpad
176 return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
177 } else if (strcasecmp(argv[0], "position") == 0) {
178 // TODO: floating
179 return cmd_results_new(CMD_FAILURE, "move", "Unimplemented");
180 } else {
181 return cmd_results_new(CMD_INVALID, "move", expected_syntax);
182 }
183 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
184}