aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/focus.c
diff options
context:
space:
mode:
authorLibravatar Ronan Pigott <rpigott@berkeley.edu>2019-10-24 11:41:04 -0700
committerLibravatar Drew DeVault <sir@cmpwn.com>2019-10-27 11:02:57 -0400
commitf5f12a69f6280dba4f8b05290bd81385d6e6c268 (patch)
treefc6bdf29a71499edf9210bd70c0a549dedd75933 /sway/commands/focus.c
parentFix segfault in wlr_output_manager_v1_set_configuration (diff)
downloadsway-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.c61
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
17static 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
17static bool parse_direction(const char *name, 53static 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
94static struct sway_node *node_get_in_direction_tiling( 130static 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);