diff options
-rw-r--r-- | sway/commands/layout.c | 76 | ||||
-rw-r--r-- | sway/sway.5.scd | 12 |
2 files changed, 70 insertions, 18 deletions
diff --git a/sway/commands/layout.c b/sway/commands/layout.c index c446f1f9..ec170591 100644 --- a/sway/commands/layout.c +++ b/sway/commands/layout.c | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <stdbool.h> | ||
1 | #include <string.h> | 2 | #include <string.h> |
2 | #include <strings.h> | 3 | #include <strings.h> |
3 | #include "sway/commands.h" | 4 | #include "sway/commands.h" |
@@ -5,6 +6,26 @@ | |||
5 | #include "sway/tree/container.h" | 6 | #include "sway/tree/container.h" |
6 | #include "log.h" | 7 | #include "log.h" |
7 | 8 | ||
9 | static bool parse_layout_string(char *s, enum sway_container_layout *ptr) { | ||
10 | if (strcasecmp(s, "splith") == 0) { | ||
11 | *ptr = L_HORIZ; | ||
12 | } else if (strcasecmp(s, "splitv") == 0) { | ||
13 | *ptr = L_VERT; | ||
14 | } else if (strcasecmp(s, "tabbed") == 0) { | ||
15 | *ptr = L_TABBED; | ||
16 | } else if (strcasecmp(s, "stacking") == 0) { | ||
17 | *ptr = L_STACKED; | ||
18 | } else { | ||
19 | return false; | ||
20 | } | ||
21 | return true; | ||
22 | } | ||
23 | |||
24 | static const char* expected_syntax = | ||
25 | "Expected 'layout default|tabbed|stacking|splitv|splith' or " | ||
26 | "'layout toggle [split|all]' or " | ||
27 | "'layout toggle [split|tabbed|stacking|splitv|splith] [split|tabbed|stacking|splitv|splith]...'"; | ||
28 | |||
8 | struct cmd_results *cmd_layout(int argc, char **argv) { | 29 | struct cmd_results *cmd_layout(int argc, char **argv) { |
9 | struct cmd_results *error = NULL; | 30 | struct cmd_results *error = NULL; |
10 | if ((error = checkarg(argc, "layout", EXPECTED_MORE_THAN, 0))) { | 31 | if ((error = checkarg(argc, "layout", EXPECTED_MORE_THAN, 0))) { |
@@ -23,30 +44,55 @@ struct cmd_results *cmd_layout(int argc, char **argv) { | |||
23 | 44 | ||
24 | if (strcasecmp(argv[0], "default") == 0) { | 45 | if (strcasecmp(argv[0], "default") == 0) { |
25 | parent->layout = parent->prev_layout; | 46 | parent->layout = parent->prev_layout; |
26 | if (parent->layout == L_NONE) { | ||
27 | parent->layout = container_get_default_layout(parent); | ||
28 | } | ||
29 | } else { | 47 | } else { |
30 | if (parent->layout != L_TABBED && parent->layout != L_STACKED) { | 48 | if (parent->layout != L_TABBED && parent->layout != L_STACKED) { |
31 | parent->prev_layout = parent->layout; | 49 | parent->prev_layout = parent->layout; |
32 | } | 50 | } |
33 | 51 | ||
34 | if (strcasecmp(argv[0], "splith") == 0) { | 52 | bool assigned_directly = parse_layout_string(argv[0], &parent->layout); |
35 | parent->layout = L_HORIZ; | 53 | if (!assigned_directly && strcasecmp(argv[0], "toggle") == 0) { |
36 | } else if (strcasecmp(argv[0], "splitv") == 0) { | 54 | if (argc == 1) { |
37 | parent->layout = L_VERT; | 55 | parent->layout = |
38 | } else if (strcasecmp(argv[0], "tabbed") == 0) { | 56 | parent->layout == L_STACKED ? L_TABBED : |
39 | parent->layout = L_TABBED; | 57 | parent->layout == L_TABBED ? parent->prev_layout : L_STACKED; |
40 | } else if (strcasecmp(argv[0], "stacking") == 0) { | 58 | } else if (argc == 2) { |
41 | parent->layout = L_STACKED; | 59 | if (strcasecmp(argv[1], "all") == 0) { |
42 | } else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) { | 60 | parent->layout = |
43 | if (parent->layout == L_HORIZ) { | 61 | parent->layout == L_HORIZ ? L_VERT : |
44 | parent->layout = L_VERT; | 62 | parent->layout == L_VERT ? L_STACKED : |
63 | parent->layout == L_STACKED ? L_TABBED : L_HORIZ; | ||
64 | } else if (strcasecmp(argv[1], "split") == 0) { | ||
65 | parent->layout = parent->layout == L_VERT ? L_HORIZ : L_VERT; | ||
66 | } else { | ||
67 | return cmd_results_new(CMD_INVALID, "layout", expected_syntax); | ||
68 | } | ||
45 | } else { | 69 | } else { |
46 | parent->layout = L_HORIZ; | 70 | bool valid; |
71 | enum sway_container_layout parsed_layout; | ||
72 | int curr = 1; | ||
73 | for (; curr < argc; curr++) { | ||
74 | valid = parse_layout_string(argv[curr], &parsed_layout); | ||
75 | if (valid && parsed_layout == parent->layout) { | ||
76 | break; | ||
77 | } | ||
78 | } | ||
79 | for (int i = curr + 1; i != curr; ++i) { | ||
80 | // cycle round to find next valid layout | ||
81 | if (i >= argc) { | ||
82 | i = 1; | ||
83 | } | ||
84 | if (parse_layout_string(argv[i], &parent->layout)) { | ||
85 | break; | ||
86 | } // invalid layout strings are silently ignored | ||
87 | } | ||
47 | } | 88 | } |
89 | } else { | ||
90 | return cmd_results_new(CMD_INVALID, "layout", expected_syntax); | ||
48 | } | 91 | } |
49 | } | 92 | } |
93 | if (parent->layout == L_NONE) { | ||
94 | parent->layout = container_get_default_layout(parent); | ||
95 | } | ||
50 | 96 | ||
51 | container_notify_subtree_changed(parent); | 97 | container_notify_subtree_changed(parent); |
52 | arrange_windows(parent); | 98 | arrange_windows(parent); |
diff --git a/sway/sway.5.scd b/sway/sway.5.scd index b639653a..a580c7d6 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd | |||
@@ -111,11 +111,17 @@ They are expected to be used with *bindsym* or at runtime through *swaymsg*(1). | |||
111 | *fullscreen* | 111 | *fullscreen* |
112 | Toggles fullscreen for the focused view. | 112 | Toggles fullscreen for the focused view. |
113 | 113 | ||
114 | *layout* splith|splitv|stacking|tabbed | 114 | *layout* default|splith|splitv|stacking|tabbed |
115 | Sets the layout mode of the focused container. | 115 | Sets the layout mode of the focused container. |
116 | 116 | ||
117 | *layout* toggle split | 117 | *layout* toggle [split|all] |
118 | Switches the focused container between the splitv and splith layouts. | 118 | Cycles the layout mode of the focused container though a preset list of |
119 | layouts. If no argument is given, then it cycles through stacking, tabbed | ||
120 | and the last split layout. If "split" is given, then it cycles through | ||
121 | splith and splitv. If "all" is given, then it cycles through every layout. | ||
122 | |||
123 | *layout* toggle [split|tabbed|stacking|splitv|splith] [split|tabbed|stacking|splitv|splith]... | ||
124 | Cycles the layout mode of the focused container through a list of layouts. | ||
119 | 125 | ||
120 | *move* left|right|up|down [<px>] | 126 | *move* left|right|up|down [<px>] |
121 | Moves the focused container in the direction specified. If the container, | 127 | Moves the focused container in the direction specified. If the container, |