aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/gaps.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-11 11:03:43 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-06-11 11:03:43 +1000
commit9e96cfd310c4e5dc60f07d772e60b139ff7dc448 (patch)
tree9961c8705208b2f127133f0533bd305a6f75015e /sway/commands/gaps.c
parentRefactor everything that needs to arrange windows (diff)
parentMerge pull request #2124 from emersion/drag-icons (diff)
downloadsway-9e96cfd310c4e5dc60f07d772e60b139ff7dc448.tar.gz
sway-9e96cfd310c4e5dc60f07d772e60b139ff7dc448.tar.zst
sway-9e96cfd310c4e5dc60f07d772e60b139ff7dc448.zip
Merge remote-tracking branch 'upstream/master' into atomic
Diffstat (limited to 'sway/commands/gaps.c')
-rw-r--r--sway/commands/gaps.c177
1 files changed, 177 insertions, 0 deletions
diff --git a/sway/commands/gaps.c b/sway/commands/gaps.c
new file mode 100644
index 00000000..801fb179
--- /dev/null
+++ b/sway/commands/gaps.c
@@ -0,0 +1,177 @@
1#include <string.h>
2#include "sway/commands.h"
3#include "sway/config.h"
4#include "sway/tree/arrange.h"
5#include "log.h"
6#include "stringop.h"
7#include <math.h>
8
9enum gaps_op {
10 GAPS_OP_SET,
11 GAPS_OP_ADD,
12 GAPS_OP_SUBTRACT
13};
14
15enum gaps_scope {
16 GAPS_SCOPE_ALL,
17 GAPS_SCOPE_WORKSPACE,
18 GAPS_SCOPE_CURRENT
19};
20
21struct cmd_results *cmd_gaps(int argc, char **argv) {
22 struct cmd_results *error = checkarg(argc, "gaps", EXPECTED_AT_LEAST, 1);
23 if (error) {
24 return error;
25 }
26
27 if (strcmp(argv[0], "edge_gaps") == 0) {
28 if ((error = checkarg(argc, "gaps", EXPECTED_AT_LEAST, 2))) {
29 return error;
30 }
31
32 if (strcmp(argv[1], "on") == 0) {
33 config->edge_gaps = true;
34 } else if (strcmp(argv[1], "off") == 0) {
35 config->edge_gaps = false;
36 } else if (strcmp(argv[1], "toggle") == 0) {
37 if (!config->active) {
38 return cmd_results_new(CMD_INVALID, "gaps",
39 "Cannot toggle gaps while not running.");
40 }
41 config->edge_gaps = !config->edge_gaps;
42 } else {
43 return cmd_results_new(CMD_INVALID, "gaps",
44 "gaps edge_gaps on|off|toggle");
45 }
46 arrange_and_commit(&root_container);
47 } else {
48 int amount_idx = 0; // the current index in argv
49 enum gaps_op op = GAPS_OP_SET;
50 enum gaps_scope scope = GAPS_SCOPE_ALL;
51 bool inner = true;
52
53 if (strcmp(argv[0], "inner") == 0) {
54 amount_idx++;
55 inner = true;
56 } else if (strcmp(argv[0], "outer") == 0) {
57 amount_idx++;
58 inner = false;
59 }
60
61 // If one of the long variants of the gaps command is used
62 // (which starts with inner|outer) check the number of args
63 if (amount_idx > 0) { // if we've seen inner|outer
64 if (argc > 2) { // check the longest variant
65 error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 4);
66 if (error) {
67 return error;
68 }
69 } else { // check the next longest format
70 error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 2);
71 if (error) {
72 return error;
73 }
74 }
75 } else {
76 error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 1);
77 if (error) {
78 return error;
79 }
80 }
81
82 if (argc == 4) {
83 // Long format: all|workspace|current.
84 if (strcmp(argv[amount_idx], "all") == 0) {
85 amount_idx++;
86 scope = GAPS_SCOPE_ALL;
87 } else if (strcmp(argv[amount_idx], "workspace") == 0) {
88 amount_idx++;
89 scope = GAPS_SCOPE_WORKSPACE;
90 } else if (strcmp(argv[amount_idx], "current") == 0) {
91 amount_idx++;
92 scope = GAPS_SCOPE_CURRENT;
93 }
94
95 // Long format: set|plus|minus
96 if (strcmp(argv[amount_idx], "set") == 0) {
97 amount_idx++;
98 op = GAPS_OP_SET;
99 } else if (strcmp(argv[amount_idx], "plus") == 0) {
100 amount_idx++;
101 op = GAPS_OP_ADD;
102 } else if (strcmp(argv[amount_idx], "minus") == 0) {
103 amount_idx++;
104 op = GAPS_OP_SUBTRACT;
105 }
106 }
107
108 char *end;
109 double val = strtod(argv[amount_idx], &end);
110
111 if (strlen(end) && val == 0.0) { // invalid <amount>
112 // guess which variant of the command was attempted
113 if (argc == 1) {
114 return cmd_results_new(CMD_INVALID, "gaps", "gaps <amount>");
115 }
116 if (argc == 2) {
117 return cmd_results_new(CMD_INVALID, "gaps",
118 "gaps inner|outer <amount>");
119 }
120 return cmd_results_new(CMD_INVALID, "gaps",
121 "gaps inner|outer all|workspace|current set|plus|minus <amount>");
122 }
123
124 if (amount_idx == 0) { // gaps <amount>
125 config->gaps_inner = val;
126 config->gaps_outer = val;
127 arrange_and_commit(&root_container);
128 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
129 }
130 // Other variants. The middle-length variant (gaps inner|outer <amount>)
131 // just defaults the scope to "all" and defaults the op to "set".
132
133 double total;
134 switch (op) {
135 case GAPS_OP_SUBTRACT: {
136 total = (inner ? config->gaps_inner : config->gaps_outer) - val;
137 if (total < 0) {
138 total = 0;
139 }
140 break;
141 }
142 case GAPS_OP_ADD: {
143 total = (inner ? config->gaps_inner : config->gaps_outer) + val;
144 break;
145 }
146 case GAPS_OP_SET: {
147 total = val;
148 break;
149 }
150 }
151
152 if (scope == GAPS_SCOPE_ALL) {
153 if (inner) {
154 config->gaps_inner = total;
155 } else {
156 config->gaps_outer = total;
157 }
158 arrange_and_commit(&root_container);
159 } else {
160 struct sway_container *c =
161 config->handler_context.current_container;
162 if (scope == GAPS_SCOPE_WORKSPACE && c->type != C_WORKSPACE) {
163 c = container_parent(c, C_WORKSPACE);
164 }
165 c->has_gaps = true;
166 if (inner) {
167 c->gaps_inner = total;
168 } else {
169 c->gaps_outer = total;
170 }
171
172 arrange_and_commit(c->parent ? c->parent : &root_container);
173 }
174 }
175
176 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
177}