summaryrefslogtreecommitdiffstats
path: root/sway/commands/layout.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/commands/layout.c')
-rw-r--r--sway/commands/layout.c105
1 files changed, 80 insertions, 25 deletions
diff --git a/sway/commands/layout.c b/sway/commands/layout.c
index c446f1f9..f4e4dda9 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
9static 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
24static 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
8struct cmd_results *cmd_layout(int argc, char **argv) { 29struct 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))) {
@@ -21,35 +42,69 @@ struct cmd_results *cmd_layout(int argc, char **argv) {
21 parent = parent->parent; 42 parent = parent->parent;
22 } 43 }
23 44
24 if (strcasecmp(argv[0], "default") == 0) { 45 enum sway_container_layout prev = parent->layout;
25 parent->layout = parent->prev_layout; 46 bool assigned_directly = parse_layout_string(argv[0], &parent->layout);
26 if (parent->layout == L_NONE) { 47 if (!assigned_directly) {
27 parent->layout = container_get_default_layout(parent); 48 if (strcasecmp(argv[0], "default") == 0) {
28 } 49 parent->layout = parent->prev_split_layout;
29 } else { 50 } else if (strcasecmp(argv[0], "toggle") == 0) {
30 if (parent->layout != L_TABBED && parent->layout != L_STACKED) { 51 if (argc == 1) {
31 parent->prev_layout = parent->layout; 52 parent->layout =
32 } 53 parent->layout == L_STACKED ? L_TABBED :
33 54 parent->layout == L_TABBED ? parent->prev_split_layout : L_STACKED;
34 if (strcasecmp(argv[0], "splith") == 0) { 55 } else if (argc == 2) {
35 parent->layout = L_HORIZ; 56 if (strcasecmp(argv[1], "all") == 0) {
36 } else if (strcasecmp(argv[0], "splitv") == 0) { 57 parent->layout =
37 parent->layout = L_VERT; 58 parent->layout == L_HORIZ ? L_VERT :
38 } else if (strcasecmp(argv[0], "tabbed") == 0) { 59 parent->layout == L_VERT ? L_STACKED :
39 parent->layout = L_TABBED; 60 parent->layout == L_STACKED ? L_TABBED : L_HORIZ;
40 } else if (strcasecmp(argv[0], "stacking") == 0) { 61 } else if (strcasecmp(argv[1], "split") == 0) {
41 parent->layout = L_STACKED; 62 parent->layout =
42 } else if (strcasecmp(argv[0], "toggle") == 0 && argc == 2 && strcasecmp(argv[1], "split") == 0) { 63 parent->layout == L_HORIZ ? L_VERT :
43 if (parent->layout == L_HORIZ) { 64 parent->layout == L_VERT ? L_HORIZ : parent->prev_split_layout;
44 parent->layout = L_VERT; 65 } else {
66 return cmd_results_new(CMD_INVALID, "layout", expected_syntax);
67 }
45 } else { 68 } else {
46 parent->layout = L_HORIZ; 69 enum sway_container_layout parsed_layout;
70 int curr = 1;
71 for (; curr < argc; curr++) {
72 bool valid = parse_layout_string(argv[curr], &parsed_layout);
73 if ((valid && parsed_layout == parent->layout) ||
74 (strcmp(argv[curr], "split") == 0 &&
75 (parent->layout == L_VERT || parent->layout == L_HORIZ))) {
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 } else if (strcmp(argv[i], "split") == 0) {
87 parent->layout =
88 parent->layout == L_HORIZ ? L_VERT :
89 parent->layout == L_VERT ? L_HORIZ : parent->prev_split_layout;
90 break;
91 } // invalid layout strings are silently ignored
92 }
47 } 93 }
94 } else {
95 return cmd_results_new(CMD_INVALID, "layout", expected_syntax);
48 } 96 }
49 } 97 }
50 98 if (parent->layout == L_NONE) {
51 container_notify_subtree_changed(parent); 99 parent->layout = container_get_default_layout(parent);
52 arrange_windows(parent); 100 }
101 if (prev != parent->layout) {
102 if (prev != L_TABBED && prev != L_STACKED) {
103 parent->prev_split_layout = prev;
104 }
105 container_notify_subtree_changed(parent);
106 arrange_windows(parent);
107 }
53 108
54 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 109 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
55} 110}