diff options
Diffstat (limited to 'sway/commands/focus.c')
-rw-r--r-- | sway/commands/focus.c | 98 |
1 files changed, 52 insertions, 46 deletions
diff --git a/sway/commands/focus.c b/sway/commands/focus.c index 2204f722..521b2427 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c | |||
@@ -1,4 +1,5 @@ | |||
1 | #include <strings.h> | 1 | #include <strings.h> |
2 | #include <wlr/types/wlr_output_layout.h> | ||
2 | #include <wlr/util/log.h> | 3 | #include <wlr/util/log.h> |
3 | #include "log.h" | 4 | #include "log.h" |
4 | #include "sway/commands.h" | 5 | #include "sway/commands.h" |
@@ -13,20 +14,16 @@ | |||
13 | #include "stringop.h" | 14 | #include "stringop.h" |
14 | #include "util.h" | 15 | #include "util.h" |
15 | 16 | ||
16 | static bool parse_movement_direction(const char *name, | 17 | static bool parse_direction(const char *name, |
17 | enum movement_direction *out) { | 18 | enum wlr_direction *out) { |
18 | if (strcasecmp(name, "left") == 0) { | 19 | if (strcasecmp(name, "left") == 0) { |
19 | *out = MOVE_LEFT; | 20 | *out = WLR_DIRECTION_LEFT; |
20 | } else if (strcasecmp(name, "right") == 0) { | 21 | } else if (strcasecmp(name, "right") == 0) { |
21 | *out = MOVE_RIGHT; | 22 | *out = WLR_DIRECTION_RIGHT; |
22 | } else if (strcasecmp(name, "up") == 0) { | 23 | } else if (strcasecmp(name, "up") == 0) { |
23 | *out = MOVE_UP; | 24 | *out = WLR_DIRECTION_UP; |
24 | } else if (strcasecmp(name, "down") == 0) { | 25 | } else if (strcasecmp(name, "down") == 0) { |
25 | *out = MOVE_DOWN; | 26 | *out = WLR_DIRECTION_DOWN; |
26 | } else if (strcasecmp(name, "parent") == 0) { | ||
27 | *out = MOVE_PARENT; | ||
28 | } else if (strcasecmp(name, "child") == 0) { | ||
29 | *out = MOVE_CHILD; | ||
30 | } else { | 27 | } else { |
31 | return false; | 28 | return false; |
32 | } | 29 | } |
@@ -38,7 +35,7 @@ static bool parse_movement_direction(const char *name, | |||
38 | * Get node in the direction of newly entered output. | 35 | * Get node in the direction of newly entered output. |
39 | */ | 36 | */ |
40 | static struct sway_node *get_node_in_output_direction( | 37 | static struct sway_node *get_node_in_output_direction( |
41 | struct sway_output *output, enum movement_direction dir) { | 38 | struct sway_output *output, enum wlr_direction dir) { |
42 | struct sway_seat *seat = config->handler_context.seat; | 39 | struct sway_seat *seat = config->handler_context.seat; |
43 | struct sway_workspace *ws = output_get_active_workspace(output); | 40 | struct sway_workspace *ws = output_get_active_workspace(output); |
44 | if (ws->fullscreen) { | 41 | if (ws->fullscreen) { |
@@ -48,7 +45,7 @@ static struct sway_node *get_node_in_output_direction( | |||
48 | 45 | ||
49 | if (ws->tiling->length > 0) { | 46 | if (ws->tiling->length > 0) { |
50 | switch (dir) { | 47 | switch (dir) { |
51 | case MOVE_LEFT: | 48 | case WLR_DIRECTION_LEFT: |
52 | if (ws->layout == L_HORIZ || ws->layout == L_TABBED) { | 49 | if (ws->layout == L_HORIZ || ws->layout == L_TABBED) { |
53 | // get most right child of new output | 50 | // get most right child of new output |
54 | container = ws->tiling->items[ws->tiling->length-1]; | 51 | container = ws->tiling->items[ws->tiling->length-1]; |
@@ -56,7 +53,7 @@ static struct sway_node *get_node_in_output_direction( | |||
56 | container = seat_get_focus_inactive_tiling(seat, ws); | 53 | container = seat_get_focus_inactive_tiling(seat, ws); |
57 | } | 54 | } |
58 | break; | 55 | break; |
59 | case MOVE_RIGHT: | 56 | case WLR_DIRECTION_RIGHT: |
60 | if (ws->layout == L_HORIZ || ws->layout == L_TABBED) { | 57 | if (ws->layout == L_HORIZ || ws->layout == L_TABBED) { |
61 | // get most left child of new output | 58 | // get most left child of new output |
62 | container = ws->tiling->items[0]; | 59 | container = ws->tiling->items[0]; |
@@ -64,7 +61,7 @@ static struct sway_node *get_node_in_output_direction( | |||
64 | container = seat_get_focus_inactive_tiling(seat, ws); | 61 | container = seat_get_focus_inactive_tiling(seat, ws); |
65 | } | 62 | } |
66 | break; | 63 | break; |
67 | case MOVE_UP: | 64 | case WLR_DIRECTION_UP: |
68 | if (ws->layout == L_VERT || ws->layout == L_STACKED) { | 65 | if (ws->layout == L_VERT || ws->layout == L_STACKED) { |
69 | // get most bottom child of new output | 66 | // get most bottom child of new output |
70 | container = ws->tiling->items[ws->tiling->length-1]; | 67 | container = ws->tiling->items[ws->tiling->length-1]; |
@@ -72,7 +69,7 @@ static struct sway_node *get_node_in_output_direction( | |||
72 | container = seat_get_focus_inactive_tiling(seat, ws); | 69 | container = seat_get_focus_inactive_tiling(seat, ws); |
73 | } | 70 | } |
74 | break; | 71 | break; |
75 | case MOVE_DOWN: { | 72 | case WLR_DIRECTION_DOWN: |
76 | if (ws->layout == L_VERT || ws->layout == L_STACKED) { | 73 | if (ws->layout == L_VERT || ws->layout == L_STACKED) { |
77 | // get most top child of new output | 74 | // get most top child of new output |
78 | container = ws->tiling->items[0]; | 75 | container = ws->tiling->items[0]; |
@@ -81,9 +78,6 @@ static struct sway_node *get_node_in_output_direction( | |||
81 | } | 78 | } |
82 | break; | 79 | break; |
83 | } | 80 | } |
84 | default: | ||
85 | break; | ||
86 | } | ||
87 | } | 81 | } |
88 | 82 | ||
89 | if (container) { | 83 | if (container) { |
@@ -95,11 +89,8 @@ static struct sway_node *get_node_in_output_direction( | |||
95 | } | 89 | } |
96 | 90 | ||
97 | static struct sway_node *node_get_in_direction(struct sway_container *container, | 91 | static struct sway_node *node_get_in_direction(struct sway_container *container, |
98 | struct sway_seat *seat, enum movement_direction dir) { | 92 | struct sway_seat *seat, enum wlr_direction dir) { |
99 | if (container->is_fullscreen) { | 93 | if (container->is_fullscreen) { |
100 | if (dir == MOVE_PARENT) { | ||
101 | return NULL; | ||
102 | } | ||
103 | // Fullscreen container with a direction - go straight to outputs | 94 | // Fullscreen container with a direction - go straight to outputs |
104 | struct sway_output *output = container->workspace->output; | 95 | struct sway_output *output = container->workspace->output; |
105 | struct sway_output *new_output = output_get_in_direction(output, dir); | 96 | struct sway_output *new_output = output_get_in_direction(output, dir); |
@@ -108,9 +99,6 @@ static struct sway_node *node_get_in_direction(struct sway_container *container, | |||
108 | } | 99 | } |
109 | return get_node_in_output_direction(new_output, dir); | 100 | return get_node_in_output_direction(new_output, dir); |
110 | } | 101 | } |
111 | if (dir == MOVE_PARENT) { | ||
112 | return node_get_parent(&container->node); | ||
113 | } | ||
114 | 102 | ||
115 | struct sway_container *wrap_candidate = NULL; | 103 | struct sway_container *wrap_candidate = NULL; |
116 | struct sway_container *current = container; | 104 | struct sway_container *current = container; |
@@ -122,15 +110,15 @@ static struct sway_node *node_get_in_direction(struct sway_container *container, | |||
122 | container_parent_layout(current); | 110 | container_parent_layout(current); |
123 | list_t *siblings = container_get_siblings(current); | 111 | list_t *siblings = container_get_siblings(current); |
124 | 112 | ||
125 | if (dir == MOVE_LEFT || dir == MOVE_RIGHT) { | 113 | if (dir == WLR_DIRECTION_LEFT || dir == WLR_DIRECTION_RIGHT) { |
126 | if (parent_layout == L_HORIZ || parent_layout == L_TABBED) { | 114 | if (parent_layout == L_HORIZ || parent_layout == L_TABBED) { |
127 | can_move = true; | 115 | can_move = true; |
128 | desired = idx + (dir == MOVE_LEFT ? -1 : 1); | 116 | desired = idx + (dir == WLR_DIRECTION_LEFT ? -1 : 1); |
129 | } | 117 | } |
130 | } else { | 118 | } else { |
131 | if (parent_layout == L_VERT || parent_layout == L_STACKED) { | 119 | if (parent_layout == L_VERT || parent_layout == L_STACKED) { |
132 | can_move = true; | 120 | can_move = true; |
133 | desired = idx + (dir == MOVE_UP ? -1 : 1); | 121 | desired = idx + (dir == WLR_DIRECTION_UP ? -1 : 1); |
134 | } | 122 | } |
135 | } | 123 | } |
136 | 124 | ||
@@ -200,9 +188,8 @@ static struct cmd_results *focus_output(struct sway_seat *seat, | |||
200 | struct sway_output *output = output_by_name(identifier); | 188 | struct sway_output *output = output_by_name(identifier); |
201 | 189 | ||
202 | if (!output) { | 190 | if (!output) { |
203 | enum movement_direction direction; | 191 | enum wlr_direction direction; |
204 | if (!parse_movement_direction(identifier, &direction) || | 192 | if (!parse_direction(identifier, &direction)) { |
205 | direction == MOVE_PARENT || direction == MOVE_CHILD) { | ||
206 | free(identifier); | 193 | free(identifier); |
207 | return cmd_results_new(CMD_INVALID, "focus", | 194 | return cmd_results_new(CMD_INVALID, "focus", |
208 | "There is no output with that name"); | 195 | "There is no output with that name"); |
@@ -220,6 +207,31 @@ static struct cmd_results *focus_output(struct sway_seat *seat, | |||
220 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 207 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
221 | } | 208 | } |
222 | 209 | ||
210 | static struct cmd_results *focus_parent(void) { | ||
211 | struct sway_seat *seat = config->handler_context.seat; | ||
212 | struct sway_container *con = config->handler_context.container; | ||
213 | if (!con || con->is_fullscreen) { | ||
214 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
215 | } | ||
216 | struct sway_node *parent = node_get_parent(&con->node); | ||
217 | if (parent) { | ||
218 | seat_set_focus(seat, parent); | ||
219 | seat_consider_warp_to_focus(seat); | ||
220 | } | ||
221 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
222 | } | ||
223 | |||
224 | static struct cmd_results *focus_child(void) { | ||
225 | struct sway_seat *seat = config->handler_context.seat; | ||
226 | struct sway_node *node = config->handler_context.node; | ||
227 | struct sway_node *focus = seat_get_active_tiling_child(seat, node); | ||
228 | if (focus) { | ||
229 | seat_set_focus(seat, focus); | ||
230 | seat_consider_warp_to_focus(seat); | ||
231 | } | ||
232 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
233 | } | ||
234 | |||
223 | struct cmd_results *cmd_focus(int argc, char **argv) { | 235 | struct cmd_results *cmd_focus(int argc, char **argv) { |
224 | if (config->reading || !config->active) { | 236 | if (config->reading || !config->active) { |
225 | return cmd_results_new(CMD_DEFER, NULL, NULL); | 237 | return cmd_results_new(CMD_DEFER, NULL, NULL); |
@@ -257,27 +269,21 @@ struct cmd_results *cmd_focus(int argc, char **argv) { | |||
257 | return focus_output(seat, argc, argv); | 269 | return focus_output(seat, argc, argv); |
258 | } | 270 | } |
259 | 271 | ||
260 | enum movement_direction direction = 0; | 272 | if (strcasecmp(argv[0], "parent") == 0) { |
261 | if (!parse_movement_direction(argv[0], &direction)) { | 273 | return focus_parent(); |
274 | } | ||
275 | if (strcasecmp(argv[0], "child") == 0) { | ||
276 | return focus_child(); | ||
277 | } | ||
278 | |||
279 | enum wlr_direction direction = 0; | ||
280 | if (!parse_direction(argv[0], &direction)) { | ||
262 | return cmd_results_new(CMD_INVALID, "focus", | 281 | return cmd_results_new(CMD_INVALID, "focus", |
263 | "Expected 'focus <direction|parent|child|mode_toggle|floating|tiling>' " | 282 | "Expected 'focus <direction|parent|child|mode_toggle|floating|tiling>' " |
264 | "or 'focus output <direction|name>'"); | 283 | "or 'focus output <direction|name>'"); |
265 | } | 284 | } |
266 | 285 | ||
267 | if (direction == MOVE_CHILD) { | ||
268 | struct sway_node *focus = seat_get_active_tiling_child(seat, node); | ||
269 | if (focus) { | ||
270 | seat_set_focus(seat, focus); | ||
271 | seat_consider_warp_to_focus(seat); | ||
272 | } | ||
273 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
274 | } | ||
275 | |||
276 | if (node->type == N_WORKSPACE) { | 286 | if (node->type == N_WORKSPACE) { |
277 | if (direction == MOVE_PARENT) { | ||
278 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
279 | } | ||
280 | |||
281 | // Jump to the next output | 287 | // Jump to the next output |
282 | struct sway_output *new_output = | 288 | struct sway_output *new_output = |
283 | output_get_in_direction(workspace->output, direction); | 289 | output_get_in_direction(workspace->output, direction); |