diff options
author | Ronan Pigott <rpigott@berkeley.edu> | 2019-10-24 11:41:04 -0700 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2019-10-27 11:02:57 -0400 |
commit | f5f12a69f6280dba4f8b05290bd81385d6e6c268 (patch) | |
tree | fc6bdf29a71499edf9210bd70c0a549dedd75933 /sway/commands/focus.c | |
parent | Fix segfault in wlr_output_manager_v1_set_configuration (diff) | |
download | sway-f5f12a69f6280dba4f8b05290bd81385d6e6c268.tar.gz sway-f5f12a69f6280dba4f8b05290bd81385d6e6c268.tar.zst sway-f5f12a69f6280dba4f8b05290bd81385d6e6c268.zip |
focus: support focus prev|next [sibling]
Diffstat (limited to 'sway/commands/focus.c')
-rw-r--r-- | sway/commands/focus.c | 61 |
1 files changed, 53 insertions, 8 deletions
diff --git a/sway/commands/focus.c b/sway/commands/focus.c index 93d1effe..99c7e61e 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c | |||
@@ -14,6 +14,42 @@ | |||
14 | #include "stringop.h" | 14 | #include "stringop.h" |
15 | #include "util.h" | 15 | #include "util.h" |
16 | 16 | ||
17 | static bool get_direction_from_next_prev(struct sway_container *container, | ||
18 | struct sway_seat *seat, const char *name, enum wlr_direction *out) { | ||
19 | enum sway_container_layout parent_layout = container_parent_layout(container); | ||
20 | if (strcasecmp(name, "prev") == 0) { | ||
21 | switch (parent_layout) { | ||
22 | case L_HORIZ: | ||
23 | case L_TABBED: | ||
24 | *out = WLR_DIRECTION_LEFT; | ||
25 | break; | ||
26 | case L_VERT: | ||
27 | case L_STACKED: | ||
28 | *out = WLR_DIRECTION_UP; | ||
29 | break; | ||
30 | default: | ||
31 | return false; | ||
32 | } | ||
33 | } else if (strcasecmp(name, "next") == 0) { | ||
34 | switch (parent_layout) { | ||
35 | case L_HORIZ: | ||
36 | case L_TABBED: | ||
37 | *out = WLR_DIRECTION_RIGHT; | ||
38 | break; | ||
39 | case L_VERT: | ||
40 | case L_STACKED: | ||
41 | *out = WLR_DIRECTION_DOWN; | ||
42 | break; | ||
43 | default: | ||
44 | return false; | ||
45 | } | ||
46 | } else { | ||
47 | return false; | ||
48 | } | ||
49 | |||
50 | return true; | ||
51 | } | ||
52 | |||
17 | static bool parse_direction(const char *name, | 53 | static bool parse_direction(const char *name, |
18 | enum wlr_direction *out) { | 54 | enum wlr_direction *out) { |
19 | if (strcasecmp(name, "left") == 0) { | 55 | if (strcasecmp(name, "left") == 0) { |
@@ -93,7 +129,7 @@ static struct sway_node *get_node_in_output_direction( | |||
93 | 129 | ||
94 | static struct sway_node *node_get_in_direction_tiling( | 130 | static struct sway_node *node_get_in_direction_tiling( |
95 | struct sway_container *container, struct sway_seat *seat, | 131 | struct sway_container *container, struct sway_seat *seat, |
96 | enum wlr_direction dir) { | 132 | enum wlr_direction dir, bool descend) { |
97 | struct sway_container *wrap_candidate = NULL; | 133 | struct sway_container *wrap_candidate = NULL; |
98 | struct sway_container *current = container; | 134 | struct sway_container *current = container; |
99 | while (current) { | 135 | while (current) { |
@@ -148,9 +184,13 @@ static struct sway_node *node_get_in_direction_tiling( | |||
148 | } | 184 | } |
149 | } else { | 185 | } else { |
150 | struct sway_container *desired_con = siblings->items[desired]; | 186 | struct sway_container *desired_con = siblings->items[desired]; |
151 | struct sway_container *c = seat_get_focus_inactive_view( | 187 | if (!descend) { |
152 | seat, &desired_con->node); | 188 | return &desired_con->node; |
153 | return &c->node; | 189 | } else { |
190 | struct sway_container *c = seat_get_focus_inactive_view( | ||
191 | seat, &desired_con->node); | ||
192 | return &c->node; | ||
193 | } | ||
154 | } | 194 | } |
155 | } | 195 | } |
156 | 196 | ||
@@ -348,10 +388,15 @@ struct cmd_results *cmd_focus(int argc, char **argv) { | |||
348 | } | 388 | } |
349 | 389 | ||
350 | enum wlr_direction direction = 0; | 390 | enum wlr_direction direction = 0; |
391 | bool descend = true; | ||
351 | if (!parse_direction(argv[0], &direction)) { | 392 | if (!parse_direction(argv[0], &direction)) { |
352 | return cmd_results_new(CMD_INVALID, | 393 | if (!get_direction_from_next_prev(container, seat, argv[0], &direction)) { |
353 | "Expected 'focus <direction|parent|child|mode_toggle|floating|tiling>' " | 394 | return cmd_results_new(CMD_INVALID, |
354 | "or 'focus output <direction|name>'"); | 395 | "Expected 'focus <direction|next|prev|parent|child|mode_toggle|floating|tiling>' " |
396 | "or 'focus output <direction|name>'"); | ||
397 | } else if (argc == 2 && strcasecmp(argv[1], "sibling") == 0) { | ||
398 | descend = false; | ||
399 | } | ||
355 | } | 400 | } |
356 | 401 | ||
357 | if (node->type == N_WORKSPACE) { | 402 | if (node->type == N_WORKSPACE) { |
@@ -373,7 +418,7 @@ struct cmd_results *cmd_focus(int argc, char **argv) { | |||
373 | if (container_is_floating(container)) { | 418 | if (container_is_floating(container)) { |
374 | next_focus = node_get_in_direction_floating(container, seat, direction); | 419 | next_focus = node_get_in_direction_floating(container, seat, direction); |
375 | } else { | 420 | } else { |
376 | next_focus = node_get_in_direction_tiling(container, seat, direction); | 421 | next_focus = node_get_in_direction_tiling(container, seat, direction, descend); |
377 | } | 422 | } |
378 | if (next_focus) { | 423 | if (next_focus) { |
379 | seat_set_focus(seat, next_focus); | 424 | seat_set_focus(seat, next_focus); |