diff options
Diffstat (limited to 'sway/commands/gaps.c')
-rw-r--r-- | sway/commands/gaps.c | 151 |
1 files changed, 108 insertions, 43 deletions
diff --git a/sway/commands/gaps.c b/sway/commands/gaps.c index 3f0ef155..faaeab37 100644 --- a/sway/commands/gaps.c +++ b/sway/commands/gaps.c | |||
@@ -16,73 +16,128 @@ enum gaps_op { | |||
16 | 16 | ||
17 | struct gaps_data { | 17 | struct gaps_data { |
18 | bool inner; | 18 | bool inner; |
19 | struct { | ||
20 | bool top; | ||
21 | bool right; | ||
22 | bool bottom; | ||
23 | bool left; | ||
24 | } outer; | ||
19 | enum gaps_op operation; | 25 | enum gaps_op operation; |
20 | int amount; | 26 | int amount; |
21 | }; | 27 | }; |
22 | 28 | ||
23 | // gaps inner|outer <px> | 29 | // Prevent negative outer gaps from moving windows out of the workspace. |
30 | static void prevent_invalid_outer_gaps(void) { | ||
31 | if (config->gaps_outer.top < -config->gaps_inner) { | ||
32 | config->gaps_outer.top = -config->gaps_inner; | ||
33 | } | ||
34 | if (config->gaps_outer.right < -config->gaps_inner) { | ||
35 | config->gaps_outer.right = -config->gaps_inner; | ||
36 | } | ||
37 | if (config->gaps_outer.bottom < -config->gaps_inner) { | ||
38 | config->gaps_outer.bottom = -config->gaps_inner; | ||
39 | } | ||
40 | if (config->gaps_outer.left < -config->gaps_inner) { | ||
41 | config->gaps_outer.left = -config->gaps_inner; | ||
42 | } | ||
43 | } | ||
44 | |||
45 | // gaps inner|outer|horizontal|vertical|top|right|bottom|left <px> | ||
46 | static const char *expected_defaults = | ||
47 | "'gaps inner|outer|horizontal|vertical|top|right|bottom|left <px>'"; | ||
24 | static struct cmd_results *gaps_set_defaults(int argc, char **argv) { | 48 | static struct cmd_results *gaps_set_defaults(int argc, char **argv) { |
25 | struct cmd_results *error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 2); | 49 | struct cmd_results *error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 2); |
26 | if (error) { | 50 | if (error) { |
27 | return error; | 51 | return error; |
28 | } | 52 | } |
29 | 53 | ||
30 | bool inner; | ||
31 | if (strcasecmp(argv[0], "inner") == 0) { | ||
32 | inner = true; | ||
33 | } else if (strcasecmp(argv[0], "outer") == 0) { | ||
34 | inner = false; | ||
35 | } else { | ||
36 | return cmd_results_new(CMD_INVALID, "gaps", | ||
37 | "Expected 'gaps inner|outer <px>'"); | ||
38 | } | ||
39 | |||
40 | char *end; | 54 | char *end; |
41 | int amount = strtol(argv[1], &end, 10); | 55 | int amount = strtol(argv[1], &end, 10); |
42 | if (strlen(end) && strcasecmp(end, "px") != 0) { | 56 | if (strlen(end) && strcasecmp(end, "px") != 0) { |
43 | return cmd_results_new(CMD_INVALID, "gaps", | 57 | return cmd_results_new(CMD_INVALID, "gaps", |
44 | "Expected 'gaps inner|outer <px>'"); | 58 | "Expected %s", expected_defaults); |
45 | } | 59 | } |
46 | if (inner) { | 60 | |
61 | bool valid = false; | ||
62 | if (!strcasecmp(argv[0], "inner")) { | ||
63 | valid = true; | ||
47 | config->gaps_inner = (amount >= 0) ? amount : 0; | 64 | config->gaps_inner = (amount >= 0) ? amount : 0; |
48 | } else { | 65 | } else { |
49 | config->gaps_outer = amount; | 66 | if (!strcasecmp(argv[0], "outer") || !strcasecmp(argv[0], "vertical") |
50 | } | 67 | || !strcasecmp(argv[0], "top")) { |
51 | 68 | valid = true; | |
52 | // Prevent negative outer gaps from moving windows out of the workspace. | 69 | config->gaps_outer.top = amount; |
53 | if (config->gaps_outer < -config->gaps_inner) { | 70 | } |
54 | config->gaps_outer = -config->gaps_inner; | 71 | if (!strcasecmp(argv[0], "outer") || !strcasecmp(argv[0], "horizontal") |
72 | || !strcasecmp(argv[0], "right")) { | ||
73 | valid = true; | ||
74 | config->gaps_outer.right = amount; | ||
75 | } | ||
76 | if (!strcasecmp(argv[0], "outer") || !strcasecmp(argv[0], "vertical") | ||
77 | || !strcasecmp(argv[0], "bottom")) { | ||
78 | valid = true; | ||
79 | config->gaps_outer.bottom = amount; | ||
80 | } | ||
81 | if (!strcasecmp(argv[0], "outer") || !strcasecmp(argv[0], "horizontal") | ||
82 | || !strcasecmp(argv[0], "left")) { | ||
83 | valid = true; | ||
84 | config->gaps_outer.left = amount; | ||
85 | } | ||
86 | } | ||
87 | if (!valid) { | ||
88 | return cmd_results_new(CMD_INVALID, "gaps", | ||
89 | "Expected %s", expected_defaults); | ||
55 | } | 90 | } |
56 | 91 | ||
92 | prevent_invalid_outer_gaps(); | ||
57 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 93 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
58 | } | 94 | } |
59 | 95 | ||
60 | static void configure_gaps(struct sway_workspace *ws, void *_data) { | 96 | static void apply_gaps_op(int *prop, enum gaps_op op, int amount) { |
61 | struct gaps_data *data = _data; | 97 | switch (op) { |
62 | int *prop = data->inner ? &ws->gaps_inner : &ws->gaps_outer; | ||
63 | |||
64 | switch (data->operation) { | ||
65 | case GAPS_OP_SET: | 98 | case GAPS_OP_SET: |
66 | *prop = data->amount; | 99 | *prop = amount; |
67 | break; | 100 | break; |
68 | case GAPS_OP_ADD: | 101 | case GAPS_OP_ADD: |
69 | *prop += data->amount; | 102 | *prop += amount; |
70 | break; | 103 | break; |
71 | case GAPS_OP_SUBTRACT: | 104 | case GAPS_OP_SUBTRACT: |
72 | *prop -= data->amount; | 105 | *prop -= amount; |
73 | break; | 106 | break; |
74 | } | 107 | } |
108 | } | ||
109 | |||
110 | static void configure_gaps(struct sway_workspace *ws, void *_data) { | ||
111 | // Apply operation to gaps | ||
112 | struct gaps_data *data = _data; | ||
113 | if (data->inner) { | ||
114 | apply_gaps_op(&ws->gaps_inner, data->operation, data->amount); | ||
115 | } | ||
116 | if (data->outer.top) { | ||
117 | apply_gaps_op(&(ws->gaps_outer.top), data->operation, data->amount); | ||
118 | } | ||
119 | if (data->outer.right) { | ||
120 | apply_gaps_op(&(ws->gaps_outer.right), data->operation, data->amount); | ||
121 | } | ||
122 | if (data->outer.bottom) { | ||
123 | apply_gaps_op(&(ws->gaps_outer.bottom), data->operation, data->amount); | ||
124 | } | ||
125 | if (data->outer.left) { | ||
126 | apply_gaps_op(&(ws->gaps_outer.left), data->operation, data->amount); | ||
127 | } | ||
128 | |||
75 | // Prevent invalid gaps configurations. | 129 | // Prevent invalid gaps configurations. |
76 | if (ws->gaps_inner < 0) { | 130 | if (ws->gaps_inner < 0) { |
77 | ws->gaps_inner = 0; | 131 | ws->gaps_inner = 0; |
78 | } | 132 | } |
79 | if (ws->gaps_outer < -ws->gaps_inner) { | 133 | prevent_invalid_outer_gaps(); |
80 | ws->gaps_outer = -ws->gaps_inner; | ||
81 | } | ||
82 | arrange_workspace(ws); | 134 | arrange_workspace(ws); |
83 | } | 135 | } |
84 | 136 | ||
85 | // gaps inner|outer current|all set|plus|minus <px> | 137 | // gaps inner|outer|horizontal|vertical|top|right|bottom|left current|all |
138 | // set|plus|minus <px> | ||
139 | static const char *expected_runtime = "'gaps inner|outer|horizontal|vertical|" | ||
140 | "top|right|bottom|left current|all set|plus|minus <px>'"; | ||
86 | static struct cmd_results *gaps_set_runtime(int argc, char **argv) { | 141 | static struct cmd_results *gaps_set_runtime(int argc, char **argv) { |
87 | struct cmd_results *error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 4); | 142 | struct cmd_results *error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 4); |
88 | if (error) { | 143 | if (error) { |
@@ -93,15 +148,24 @@ static struct cmd_results *gaps_set_runtime(int argc, char **argv) { | |||
93 | "Can't run this command while there's no outputs connected."); | 148 | "Can't run this command while there's no outputs connected."); |
94 | } | 149 | } |
95 | 150 | ||
96 | struct gaps_data data; | 151 | struct gaps_data data = {0}; |
97 | 152 | ||
98 | if (strcasecmp(argv[0], "inner") == 0) { | 153 | if (strcasecmp(argv[0], "inner") == 0) { |
99 | data.inner = true; | 154 | data.inner = true; |
100 | } else if (strcasecmp(argv[0], "outer") == 0) { | ||
101 | data.inner = false; | ||
102 | } else { | 155 | } else { |
156 | data.outer.top = !strcasecmp(argv[0], "outer") || | ||
157 | !strcasecmp(argv[0], "vertical") || !strcasecmp(argv[0], "top"); | ||
158 | data.outer.right = !strcasecmp(argv[0], "outer") || | ||
159 | !strcasecmp(argv[0], "horizontal") || !strcasecmp(argv[0], "right"); | ||
160 | data.outer.bottom = !strcasecmp(argv[0], "outer") || | ||
161 | !strcasecmp(argv[0], "vertical") || !strcasecmp(argv[0], "bottom"); | ||
162 | data.outer.left = !strcasecmp(argv[0], "outer") || | ||
163 | !strcasecmp(argv[0], "horizontal") || !strcasecmp(argv[0], "left"); | ||
164 | } | ||
165 | if (!data.inner && !data.outer.top && !data.outer.right && | ||
166 | !data.outer.bottom && !data.outer.left) { | ||
103 | return cmd_results_new(CMD_INVALID, "gaps", | 167 | return cmd_results_new(CMD_INVALID, "gaps", |
104 | "Expected 'gaps inner|outer current|all set|plus|minus <px>'"); | 168 | "Expected %s", expected_runtime); |
105 | } | 169 | } |
106 | 170 | ||
107 | bool all; | 171 | bool all; |
@@ -111,7 +175,7 @@ static struct cmd_results *gaps_set_runtime(int argc, char **argv) { | |||
111 | all = true; | 175 | all = true; |
112 | } else { | 176 | } else { |
113 | return cmd_results_new(CMD_INVALID, "gaps", | 177 | return cmd_results_new(CMD_INVALID, "gaps", |
114 | "Expected 'gaps inner|outer current|all set|plus|minus <px>'"); | 178 | "Expected %s", expected_runtime); |
115 | } | 179 | } |
116 | 180 | ||
117 | if (strcasecmp(argv[2], "set") == 0) { | 181 | if (strcasecmp(argv[2], "set") == 0) { |
@@ -122,14 +186,14 @@ static struct cmd_results *gaps_set_runtime(int argc, char **argv) { | |||
122 | data.operation = GAPS_OP_SUBTRACT; | 186 | data.operation = GAPS_OP_SUBTRACT; |
123 | } else { | 187 | } else { |
124 | return cmd_results_new(CMD_INVALID, "gaps", | 188 | return cmd_results_new(CMD_INVALID, "gaps", |
125 | "Expected 'gaps inner|outer current|all set|plus|minus <px>'"); | 189 | "Expected %s", expected_runtime); |
126 | } | 190 | } |
127 | 191 | ||
128 | char *end; | 192 | char *end; |
129 | data.amount = strtol(argv[3], &end, 10); | 193 | data.amount = strtol(argv[3], &end, 10); |
130 | if (strlen(end) && strcasecmp(end, "px") != 0) { | 194 | if (strlen(end) && strcasecmp(end, "px") != 0) { |
131 | return cmd_results_new(CMD_INVALID, "gaps", | 195 | return cmd_results_new(CMD_INVALID, "gaps", |
132 | "Expected 'gaps inner|outer current|all set|plus|minus <px>'"); | 196 | "Expected %s", expected_runtime); |
133 | } | 197 | } |
134 | 198 | ||
135 | if (all) { | 199 | if (all) { |
@@ -141,8 +205,10 @@ static struct cmd_results *gaps_set_runtime(int argc, char **argv) { | |||
141 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 205 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
142 | } | 206 | } |
143 | 207 | ||
144 | // gaps inner|outer <px> - sets defaults for workspaces | 208 | // gaps inner|outer|<dir>|<side> <px> - sets defaults for workspaces |
145 | // gaps inner|outer current|all set|plus|minus <px> - runtime only | 209 | // gaps inner|outer|<dir>|<side> current|all set|plus|minus <px> - runtime only |
210 | // <dir> = horizontal|vertical | ||
211 | // <side> = top|right|bottom|left | ||
146 | struct cmd_results *cmd_gaps(int argc, char **argv) { | 212 | struct cmd_results *cmd_gaps(int argc, char **argv) { |
147 | struct cmd_results *error = checkarg(argc, "gaps", EXPECTED_AT_LEAST, 2); | 213 | struct cmd_results *error = checkarg(argc, "gaps", EXPECTED_AT_LEAST, 2); |
148 | if (error) { | 214 | if (error) { |
@@ -159,9 +225,8 @@ struct cmd_results *cmd_gaps(int argc, char **argv) { | |||
159 | } | 225 | } |
160 | if (config_loading) { | 226 | if (config_loading) { |
161 | return cmd_results_new(CMD_INVALID, "gaps", | 227 | return cmd_results_new(CMD_INVALID, "gaps", |
162 | "Expected 'gaps inner|outer <px>'"); | 228 | "Expected %s", expected_defaults); |
163 | } | 229 | } |
164 | return cmd_results_new(CMD_INVALID, "gaps", | 230 | return cmd_results_new(CMD_INVALID, "gaps", |
165 | "Expected 'gaps inner|outer <px>' or " | 231 | "Expected %s or %s", expected_runtime, expected_defaults); |
166 | "'gaps inner|outer current|all set|plus|minus <px>'"); | ||
167 | } | 232 | } |