aboutsummaryrefslogtreecommitdiffstats
path: root/sway/commands/workspace.c
diff options
context:
space:
mode:
authorLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-11-07 22:44:11 -0500
committerLibravatar Brian Ashworth <bosrsf04@gmail.com>2018-11-07 22:44:11 -0500
commit9e8aa3953098adb6175c26aebd984a32a2beccb0 (patch)
treeac64adf9f2720ddbb2476810f6ec05ec2a85a4ae /sway/commands/workspace.c
parentAdd focus_follows_mouse always. (#3081) (diff)
downloadsway-9e8aa3953098adb6175c26aebd984a32a2beccb0.tar.gz
sway-9e8aa3953098adb6175c26aebd984a32a2beccb0.tar.zst
sway-9e8aa3953098adb6175c26aebd984a32a2beccb0.zip
Implement per side and per direction outer gaps
This introduces the following command extensions from `i3-gaps`: * `gaps horizontal|vertical|top|right|bottom|left <amount>` * `gaps horizontal|vertical|top|right|bottom|left all|current set|plus|minus <amount>` * `workspace <ws> gaps horizontal|vertical|top|right|bottom|left <amount>` `inner` and `outer` are also still available as options for all three of the above commands. `outer` now acts as a shorthand to set/alter all sides. Additionally, this fixes two bugs with the prevention of invalid gap configurations for workspace configs: 1. If outer gaps were not set and inner gaps were, the outer gaps would be snapped to the negation of the inner gaps due to `INT_MIN` being less than the negation. This took precedence over the default outer gaps. 2. Similarly, if inner gaps were not set and outer gaps were, inner gaps would be set to zero, which would take precedence over the default inner gaps. Fixing both of the above items also requires checking the gaps again when creating a workspace since the default outer gaps can be smaller than the negation of the workspace specific inner gaps.
Diffstat (limited to 'sway/commands/workspace.c')
-rw-r--r--sway/commands/workspace.c124
1 files changed, 88 insertions, 36 deletions
diff --git a/sway/commands/workspace.c b/sway/commands/workspace.c
index 5abbb676..168494d2 100644
--- a/sway/commands/workspace.c
+++ b/sway/commands/workspace.c
@@ -22,7 +22,10 @@ static struct workspace_config *workspace_config_find_or_create(char *ws_name) {
22 } 22 }
23 wsc->workspace = strdup(ws_name); 23 wsc->workspace = strdup(ws_name);
24 wsc->gaps_inner = INT_MIN; 24 wsc->gaps_inner = INT_MIN;
25 wsc->gaps_outer = INT_MIN; 25 wsc->gaps_outer.top = INT_MIN;
26 wsc->gaps_outer.right = INT_MIN;
27 wsc->gaps_outer.bottom = INT_MIN;
28 wsc->gaps_outer.left = INT_MIN;
26 list_add(config->workspace_configs, wsc); 29 list_add(config->workspace_configs, wsc);
27 return wsc; 30 return wsc;
28} 31}
@@ -33,6 +36,89 @@ void free_workspace_config(struct workspace_config *wsc) {
33 free(wsc); 36 free(wsc);
34} 37}
35 38
39static void prevent_invalid_outer_gaps(struct workspace_config *wsc) {
40 if (wsc->gaps_outer.top != INT_MIN &&
41 wsc->gaps_outer.top < -wsc->gaps_inner) {
42 wsc->gaps_outer.top = -wsc->gaps_inner;
43 }
44 if (wsc->gaps_outer.right != INT_MIN &&
45 wsc->gaps_outer.right < -wsc->gaps_inner) {
46 wsc->gaps_outer.right = -wsc->gaps_inner;
47 }
48 if (wsc->gaps_outer.bottom != INT_MIN &&
49 wsc->gaps_outer.bottom < -wsc->gaps_inner) {
50 wsc->gaps_outer.bottom = -wsc->gaps_inner;
51 }
52 if (wsc->gaps_outer.left != INT_MIN &&
53 wsc->gaps_outer.left < -wsc->gaps_inner) {
54 wsc->gaps_outer.left = -wsc->gaps_inner;
55 }
56}
57
58static struct cmd_results *cmd_workspace_gaps(int argc, char **argv,
59 int gaps_location) {
60 const char *expected = "Expected 'workspace <name> gaps "
61 "inner|outer|horizontal|vertical|top|right|bottom|left <px>'";
62 struct cmd_results *error = NULL;
63 if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO,
64 gaps_location + 3))) {
65 return error;
66 }
67 char *ws_name = join_args(argv, argc - 3);
68 struct workspace_config *wsc = workspace_config_find_or_create(ws_name);
69 free(ws_name);
70 if (!wsc) {
71 return cmd_results_new(CMD_FAILURE, "workspace gaps",
72 "Unable to allocate workspace output");
73 }
74
75 char *end;
76 int amount = strtol(argv[gaps_location + 2], &end, 10);
77 if (strlen(end)) {
78 free(end);
79 return cmd_results_new(CMD_FAILURE, "workspace gaps", expected);
80 }
81
82 bool valid = false;
83 char *type = argv[gaps_location + 1];
84 if (!strcasecmp(type, "inner")) {
85 valid = true;
86 wsc->gaps_inner = (amount >= 0) ? amount : 0;
87 } else {
88 if (!strcasecmp(type, "outer") || !strcasecmp(type, "vertical")
89 || !strcasecmp(type, "top")) {
90 valid = true;
91 wsc->gaps_outer.top = amount;
92 }
93 if (!strcasecmp(type, "outer") || !strcasecmp(type, "horizontal")
94 || !strcasecmp(type, "right")) {
95 valid = true;
96 wsc->gaps_outer.right = amount;
97 }
98 if (!strcasecmp(type, "outer") || !strcasecmp(type, "vertical")
99 || !strcasecmp(type, "bottom")) {
100 valid = true;
101 wsc->gaps_outer.bottom = amount;
102 }
103 if (!strcasecmp(type, "outer") || !strcasecmp(type, "horizontal")
104 || !strcasecmp(type, "left")) {
105 valid = true;
106 wsc->gaps_outer.left = amount;
107 }
108 }
109 if (!valid) {
110 return cmd_results_new(CMD_INVALID, "workspace gaps", expected);
111 }
112
113 // Prevent invalid gaps configurations.
114 if (wsc->gaps_inner != INT_MIN && wsc->gaps_inner < 0) {
115 wsc->gaps_inner = 0;
116 }
117 prevent_invalid_outer_gaps(wsc);
118
119 return error;
120}
121
36struct cmd_results *cmd_workspace(int argc, char **argv) { 122struct cmd_results *cmd_workspace(int argc, char **argv) {
37 struct cmd_results *error = NULL; 123 struct cmd_results *error = NULL;
38 if ((error = checkarg(argc, "workspace", EXPECTED_AT_LEAST, 1))) { 124 if ((error = checkarg(argc, "workspace", EXPECTED_AT_LEAST, 1))) {
@@ -68,43 +154,9 @@ struct cmd_results *cmd_workspace(int argc, char **argv) {
68 free(wsc->output); 154 free(wsc->output);
69 wsc->output = strdup(argv[output_location + 1]); 155 wsc->output = strdup(argv[output_location + 1]);
70 } else if (gaps_location >= 0) { 156 } else if (gaps_location >= 0) {
71 if ((error = checkarg(argc, "workspace", EXPECTED_EQUAL_TO, gaps_location + 3))) { 157 if ((error = cmd_workspace_gaps(argc, argv, gaps_location))) {
72 return error; 158 return error;
73 } 159 }
74 char *ws_name = join_args(argv, argc - 3);
75 struct workspace_config *wsc = workspace_config_find_or_create(ws_name);
76 free(ws_name);
77 if (!wsc) {
78 return cmd_results_new(CMD_FAILURE, "workspace gaps",
79 "Unable to allocate workspace output");
80 }
81 int *prop = NULL;
82 if (strcasecmp(argv[gaps_location + 1], "inner") == 0) {
83 prop = &wsc->gaps_inner;
84 } else if (strcasecmp(argv[gaps_location + 1], "outer") == 0) {
85 prop = &wsc->gaps_outer;
86 } else {
87 return cmd_results_new(CMD_FAILURE, "workspace gaps",
88 "Expected 'workspace <ws> gaps inner|outer <px>'");
89 }
90 char *end;
91 int val = strtol(argv[gaps_location + 2], &end, 10);
92
93 if (strlen(end)) {
94 free(end);
95 return cmd_results_new(CMD_FAILURE, "workspace gaps",
96 "Expected 'workspace <ws> gaps inner|outer <px>'");
97 }
98 *prop = val;
99
100 // Prevent invalid gaps configurations.
101 if (wsc->gaps_inner < 0) {
102 wsc->gaps_inner = 0;
103 }
104 if (wsc->gaps_outer < -wsc->gaps_inner) {
105 wsc->gaps_outer = -wsc->gaps_inner;
106 }
107
108 } else { 160 } else {
109 if (config->reading || !config->active) { 161 if (config->reading || !config->active) {
110 return cmd_results_new(CMD_DEFER, "workspace", NULL); 162 return cmd_results_new(CMD_DEFER, "workspace", NULL);