Skip to content

Commit d9fc381

Browse files
authored
Merge pull request #2047 from natesymer/master
Implement Gaps
2 parents 21d98d5 + 6a910b9 commit d9fc381

File tree

9 files changed

+320
-9
lines changed

9 files changed

+320
-9
lines changed

include/sway/tree/arrange.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33

44
struct sway_container;
55

6+
// Remove gaps around container
7+
void remove_gaps(struct sway_container *c);
8+
9+
// Add gaps around container
10+
void add_gaps(struct sway_container *c);
11+
612
// Determine the root container's geometry, then iterate to everything below
713
void arrange_root(void);
814

include/sway/tree/container.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ struct sway_container {
8686
double saved_x, saved_y;
8787
double saved_width, saved_height;
8888

89+
// The gaps currently applied to the container.
90+
double current_gaps;
91+
92+
bool has_gaps;
93+
double gaps_inner;
94+
double gaps_outer;
95+
8996
list_t *children;
9097

9198
struct sway_container *parent;

sway/commands.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ static struct cmd_handler handlers[] = {
105105
{ "font", cmd_font },
106106
{ "for_window", cmd_for_window },
107107
{ "force_focus_wrapping", cmd_force_focus_wrapping },
108+
{ "fullscreen", cmd_fullscreen },
109+
{ "gaps", cmd_gaps },
108110
{ "hide_edge_borders", cmd_hide_edge_borders },
109111
{ "include", cmd_include },
110112
{ "input", cmd_input },
@@ -114,6 +116,7 @@ static struct cmd_handler handlers[] = {
114116
{ "seat", cmd_seat },
115117
{ "set", cmd_set },
116118
{ "show_marks", cmd_show_marks },
119+
{ "smart_gaps", cmd_smart_gaps },
117120
{ "workspace", cmd_workspace },
118121
{ "workspace_auto_back_and_forth", cmd_ws_auto_back_and_forth },
119122
};

sway/commands/gaps.c

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
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+
9+
enum gaps_op {
10+
GAPS_OP_SET,
11+
GAPS_OP_ADD,
12+
GAPS_OP_SUBTRACT
13+
};
14+
15+
enum gaps_scope {
16+
GAPS_SCOPE_ALL,
17+
GAPS_SCOPE_WORKSPACE,
18+
GAPS_SCOPE_CURRENT
19+
};
20+
21+
struct 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+
arrange_root();
35+
} else if (strcmp(argv[1], "off") == 0) {
36+
config->edge_gaps = false;
37+
arrange_root();
38+
} else if (strcmp(argv[1], "toggle") == 0) {
39+
if (!config->active) {
40+
return cmd_results_new(CMD_INVALID, "gaps",
41+
"Cannot toggle gaps while not running.");
42+
}
43+
config->edge_gaps = !config->edge_gaps;
44+
arrange_root();
45+
} else {
46+
return cmd_results_new(CMD_INVALID, "gaps",
47+
"gaps edge_gaps on|off|toggle");
48+
}
49+
} else {
50+
int amount_idx = 0; // the current index in argv
51+
enum gaps_op op = GAPS_OP_SET;
52+
enum gaps_scope scope = GAPS_SCOPE_ALL;
53+
bool inner = true;
54+
55+
if (strcmp(argv[0], "inner") == 0) {
56+
amount_idx++;
57+
inner = true;
58+
} else if (strcmp(argv[0], "outer") == 0) {
59+
amount_idx++;
60+
inner = false;
61+
}
62+
63+
// If one of the long variants of the gaps command is used
64+
// (which starts with inner|outer) check the number of args
65+
if (amount_idx > 0) { // if we've seen inner|outer
66+
if (argc > 2) { // check the longest variant
67+
error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 4);
68+
if (error) {
69+
return error;
70+
}
71+
} else { // check the next longest format
72+
error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 2);
73+
if (error) {
74+
return error;
75+
}
76+
}
77+
} else {
78+
error = checkarg(argc, "gaps", EXPECTED_EQUAL_TO, 1);
79+
if (error) {
80+
return error;
81+
}
82+
}
83+
84+
if (argc == 4) {
85+
// Long format: all|workspace|current.
86+
if (strcmp(argv[amount_idx], "all") == 0) {
87+
amount_idx++;
88+
scope = GAPS_SCOPE_ALL;
89+
} else if (strcmp(argv[amount_idx], "workspace") == 0) {
90+
amount_idx++;
91+
scope = GAPS_SCOPE_WORKSPACE;
92+
} else if (strcmp(argv[amount_idx], "current") == 0) {
93+
amount_idx++;
94+
scope = GAPS_SCOPE_CURRENT;
95+
}
96+
97+
// Long format: set|plus|minus
98+
if (strcmp(argv[amount_idx], "set") == 0) {
99+
amount_idx++;
100+
op = GAPS_OP_SET;
101+
} else if (strcmp(argv[amount_idx], "plus") == 0) {
102+
amount_idx++;
103+
op = GAPS_OP_ADD;
104+
} else if (strcmp(argv[amount_idx], "minus") == 0) {
105+
amount_idx++;
106+
op = GAPS_OP_SUBTRACT;
107+
}
108+
}
109+
110+
char *end;
111+
double val = strtod(argv[amount_idx], &end);
112+
113+
if (strlen(end) && val == 0.0) { // invalid <amount>
114+
// guess which variant of the command was attempted
115+
if (argc == 1) {
116+
return cmd_results_new(CMD_INVALID, "gaps", "gaps <amount>");
117+
}
118+
if (argc == 2) {
119+
return cmd_results_new(CMD_INVALID, "gaps",
120+
"gaps inner|outer <amount>");
121+
}
122+
return cmd_results_new(CMD_INVALID, "gaps",
123+
"gaps inner|outer all|workspace|current set|plus|minus <amount>");
124+
}
125+
126+
if (amount_idx == 0) { // gaps <amount>
127+
config->gaps_inner = val;
128+
config->gaps_outer = val;
129+
arrange_root();
130+
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
131+
}
132+
// Other variants. The middle-length variant (gaps inner|outer <amount>)
133+
// just defaults the scope to "all" and defaults the op to "set".
134+
135+
double total;
136+
switch (op) {
137+
case GAPS_OP_SUBTRACT: {
138+
total = (inner ? config->gaps_inner : config->gaps_outer) - val;
139+
if (total < 0) {
140+
total = 0;
141+
}
142+
break;
143+
}
144+
case GAPS_OP_ADD: {
145+
total = (inner ? config->gaps_inner : config->gaps_outer) + val;
146+
break;
147+
}
148+
case GAPS_OP_SET: {
149+
total = val;
150+
break;
151+
}
152+
}
153+
154+
if (scope == GAPS_SCOPE_ALL) {
155+
if (inner) {
156+
config->gaps_inner = total;
157+
} else {
158+
config->gaps_outer = total;
159+
}
160+
arrange_root();
161+
} else {
162+
struct sway_container *c =
163+
config->handler_context.current_container;
164+
if (scope == GAPS_SCOPE_WORKSPACE && c->type != C_WORKSPACE) {
165+
c = container_parent(c, C_WORKSPACE);
166+
}
167+
c->has_gaps = true;
168+
if (inner) {
169+
c->gaps_inner = total;
170+
} else {
171+
c->gaps_outer = total;
172+
}
173+
174+
if (c->parent) {
175+
arrange_children_of(c->parent);
176+
} else {
177+
arrange_root();
178+
}
179+
}
180+
}
181+
182+
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
183+
}

sway/commands/smart_gaps.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include <string.h>
2+
#include "sway/commands.h"
3+
#include "sway/config.h"
4+
#include "sway/tree/arrange.h"
5+
#include "sway/tree/view.h"
6+
#include "sway/tree/container.h"
7+
#include "log.h"
8+
#include "stringop.h"
9+
10+
struct cmd_results *cmd_smart_gaps(int argc, char **argv) {
11+
struct cmd_results *error = checkarg(argc, "smart_gaps", EXPECTED_AT_LEAST, 1);
12+
13+
if (error) {
14+
return error;
15+
}
16+
17+
if (strcmp(argv[0], "on") == 0) {
18+
config->smart_gaps = true;
19+
arrange_root();
20+
} else if (strcmp(argv[0], "off") == 0) {
21+
config->smart_gaps = false;
22+
arrange_root();
23+
} else {
24+
return cmd_results_new(CMD_INVALID, "smart_gaps",
25+
"Expected 'smart_gaps <on|off>' ");
26+
}
27+
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
28+
}

sway/meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ sway_sources = files(
4444
'commands/for_window.c',
4545
'commands/force_focus_wrapping.c',
4646
'commands/fullscreen.c',
47+
'commands/gaps.c',
4748
'commands/hide_edge_borders.c',
4849
'commands/kill.c',
4950
'commands/mark.c',
@@ -64,6 +65,7 @@ sway_sources = files(
6465
'commands/seat/fallback.c',
6566
'commands/set.c',
6667
'commands/show_marks.c',
68+
'commands/smart_gaps.c',
6769
'commands/split.c',
6870
'commands/sticky.c',
6971
'commands/swaybg_command.c',

0 commit comments

Comments
 (0)