diff options
author | Tony Crisci <tony@dubstepdish.com> | 2018-04-02 14:06:04 -0400 |
---|---|---|
committer | Tony Crisci <tony@dubstepdish.com> | 2018-04-02 14:06:04 -0400 |
commit | 2187684bd09928748f8b3a82c2e25e5ae82f5ae6 (patch) | |
tree | e70e2862280a410f8f0d617abc3539d6f0ae056e /sway/commands | |
parent | remove default from kill switch (diff) | |
parent | Merge pull request #1697 from RedSoxFan/back-and-forth (diff) | |
download | sway-2187684bd09928748f8b3a82c2e25e5ae82f5ae6.tar.gz sway-2187684bd09928748f8b3a82c2e25e5ae82f5ae6.tar.zst sway-2187684bd09928748f8b3a82c2e25e5ae82f5ae6.zip |
Merge branch 'wlroots' into split-containers
Diffstat (limited to 'sway/commands')
-rw-r--r-- | sway/commands/focus.c | 7 | ||||
-rw-r--r-- | sway/commands/move.c | 184 |
2 files changed, 186 insertions, 5 deletions
diff --git a/sway/commands/focus.c b/sway/commands/focus.c index 64f079f4..0a521b9e 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 | sway_seat_set_focus(seat, next_focus); | 53 | sway_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..ab959b77 --- /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 | |||
15 | static 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 | |||
21 | static 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 | |||
49 | static 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 = sway_seat_get_focus_inactive( | ||
82 | config->handler_context.seat, ws); | ||
83 | container_move_to(current, focus); | ||
84 | sway_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 = sway_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 | sway_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 | |||
117 | static 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 | |||
142 | struct 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 | } | ||