diff options
Diffstat (limited to 'sway/commands/focus.c')
-rw-r--r-- | sway/commands/focus.c | 71 |
1 files changed, 68 insertions, 3 deletions
diff --git a/sway/commands/focus.c b/sway/commands/focus.c index 74d9d535..9cd8bfae 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c | |||
@@ -1,10 +1,14 @@ | |||
1 | #include <strings.h> | 1 | #include <strings.h> |
2 | #include <wlr/util/log.h> | 2 | #include <wlr/util/log.h> |
3 | #include "log.h" | 3 | #include "log.h" |
4 | #include "sway/commands.h" | ||
4 | #include "sway/input/input-manager.h" | 5 | #include "sway/input/input-manager.h" |
5 | #include "sway/input/seat.h" | 6 | #include "sway/input/seat.h" |
7 | #include "sway/output.h" | ||
8 | #include "sway/tree/arrange.h" | ||
6 | #include "sway/tree/view.h" | 9 | #include "sway/tree/view.h" |
7 | #include "sway/commands.h" | 10 | #include "sway/tree/workspace.h" |
11 | #include "stringop.h" | ||
8 | 12 | ||
9 | static bool parse_movement_direction(const char *name, | 13 | static bool parse_movement_direction(const char *name, |
10 | enum movement_direction *out) { | 14 | enum movement_direction *out) { |
@@ -27,7 +31,55 @@ static bool parse_movement_direction(const char *name, | |||
27 | return true; | 31 | return true; |
28 | } | 32 | } |
29 | 33 | ||
34 | static struct cmd_results *focus_mode(struct sway_container *con, | ||
35 | struct sway_seat *seat, bool floating) { | ||
36 | struct sway_container *ws = con->type == C_WORKSPACE ? | ||
37 | con : container_parent(con, C_WORKSPACE); | ||
38 | struct sway_container *new_focus = ws; | ||
39 | if (floating) { | ||
40 | new_focus = ws->sway_workspace->floating; | ||
41 | if (new_focus->children->length == 0) { | ||
42 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
43 | } | ||
44 | } | ||
45 | seat_set_focus(seat, seat_get_active_child(seat, new_focus)); | ||
46 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
47 | } | ||
48 | |||
49 | static struct cmd_results *focus_output(struct sway_container *con, | ||
50 | struct sway_seat *seat, int argc, char **argv) { | ||
51 | if (!argc) { | ||
52 | return cmd_results_new(CMD_INVALID, "focus", | ||
53 | "Expected 'focus output <direction|name>'"); | ||
54 | } | ||
55 | char *identifier = join_args(argv, argc); | ||
56 | struct sway_container *output = output_by_name(identifier); | ||
57 | |||
58 | if (!output) { | ||
59 | enum movement_direction direction; | ||
60 | if (!parse_movement_direction(identifier, &direction) || | ||
61 | direction == MOVE_PARENT || direction == MOVE_CHILD) { | ||
62 | free(identifier); | ||
63 | return cmd_results_new(CMD_INVALID, "focus", | ||
64 | "There is no output with that name"); | ||
65 | } | ||
66 | struct sway_container *focus = seat_get_focus(seat); | ||
67 | focus = container_parent(focus, C_OUTPUT); | ||
68 | output = container_get_in_direction(focus, seat, direction); | ||
69 | } | ||
70 | |||
71 | free(identifier); | ||
72 | if (output) { | ||
73 | seat_set_focus(seat, seat_get_focus_inactive(seat, output)); | ||
74 | } | ||
75 | |||
76 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | ||
77 | } | ||
78 | |||
30 | struct cmd_results *cmd_focus(int argc, char **argv) { | 79 | struct cmd_results *cmd_focus(int argc, char **argv) { |
80 | if (config->reading || !config->active) { | ||
81 | return cmd_results_new(CMD_DEFER, NULL, NULL); | ||
82 | } | ||
31 | struct sway_container *con = config->handler_context.current_container; | 83 | struct sway_container *con = config->handler_context.current_container; |
32 | struct sway_seat *seat = config->handler_context.seat; | 84 | struct sway_seat *seat = config->handler_context.seat; |
33 | if (con->type < C_WORKSPACE) { | 85 | if (con->type < C_WORKSPACE) { |
@@ -40,11 +92,24 @@ struct cmd_results *cmd_focus(int argc, char **argv) { | |||
40 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 92 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
41 | } | 93 | } |
42 | 94 | ||
43 | // TODO mode_toggle | 95 | if (strcmp(argv[0], "floating") == 0) { |
96 | return focus_mode(con, seat, true); | ||
97 | } else if (strcmp(argv[0], "tiling") == 0) { | ||
98 | return focus_mode(con, seat, false); | ||
99 | } else if (strcmp(argv[0], "mode_toggle") == 0) { | ||
100 | return focus_mode(con, seat, !container_is_floating(con)); | ||
101 | } | ||
102 | |||
103 | if (strcmp(argv[0], "output") == 0) { | ||
104 | argc--; argv++; | ||
105 | return focus_output(con, seat, argc, argv); | ||
106 | } | ||
107 | |||
44 | enum movement_direction direction = 0; | 108 | enum movement_direction direction = 0; |
45 | if (!parse_movement_direction(argv[0], &direction)) { | 109 | if (!parse_movement_direction(argv[0], &direction)) { |
46 | return cmd_results_new(CMD_INVALID, "focus", | 110 | return cmd_results_new(CMD_INVALID, "focus", |
47 | "Expected 'focus <direction|parent|child|mode_toggle>' or 'focus output <direction|name>'"); | 111 | "Expected 'focus <direction|parent|child|mode_toggle|floating|tiling>' " |
112 | "or 'focus output <direction|name>'"); | ||
48 | } | 113 | } |
49 | 114 | ||
50 | struct sway_container *next_focus = container_get_in_direction( | 115 | struct sway_container *next_focus = container_get_in_direction( |