aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/gaps.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/commands/gaps.c')
-rw-r--r--sway/commands/gaps.c151
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
17struct gaps_data { 17struct 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.
30static 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>
46static const char *expected_defaults =
47 "'gaps inner|outer|horizontal|vertical|top|right|bottom|left <px>'";
24static struct cmd_results *gaps_set_defaults(int argc, char **argv) { 48static 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
60static void configure_gaps(struct sway_workspace *ws, void *_data) { 96static 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
110static 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>
139static const char *expected_runtime = "'gaps inner|outer|horizontal|vertical|"
140 "top|right|bottom|left current|all set|plus|minus <px>'";
86static struct cmd_results *gaps_set_runtime(int argc, char **argv) { 141static 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
146struct cmd_results *cmd_gaps(int argc, char **argv) { 212struct 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}