diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2019-12-27 23:56:11 -0500 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2019-12-28 10:07:25 +0100 |
commit | 66dc33296ca97b10f60daaff8c5e4b3f95fac8cd (patch) | |
tree | 95cb83ff86cf43d096df4f10a3cfb402d34315f7 | |
parent | parse_color: return success + drop fallback color (diff) | |
download | sway-66dc33296ca97b10f60daaff8c5e4b3f95fac8cd.tar.gz sway-66dc33296ca97b10f60daaff8c5e4b3f95fac8cd.tar.zst sway-66dc33296ca97b10f60daaff8c5e4b3f95fac8cd.zip |
cmd_client_*: refactor duplicated code
This is the second in a series of commits to refactor the color handling
in sway. This removes the duplicated color parsing code in
sway/commands/client.c. Additionally, this combines the parsing of
colors to float arrays with that in sway/config.c and introduces a
color_to_rgba function in commom/util.c.
As an added bonus, this also makes it so non of the colors in a border
color class will be changed unless all of the colors specified are
valid. This ensures that an invalid command does not get partially
applied.
-rw-r--r-- | common/util.c | 7 | ||||
-rw-r--r-- | include/util.h | 2 | ||||
-rw-r--r-- | sway/commands/client.c | 87 | ||||
-rw-r--r-- | sway/config.c | 70 |
4 files changed, 62 insertions, 104 deletions
diff --git a/common/util.c b/common/util.c index 84ebab99..c7ef2ac4 100644 --- a/common/util.c +++ b/common/util.c | |||
@@ -31,6 +31,13 @@ bool parse_color(const char *color, uint32_t *result) { | |||
31 | return true; | 31 | return true; |
32 | } | 32 | } |
33 | 33 | ||
34 | void color_to_rgba(float dest[static 4], uint32_t color) { | ||
35 | dest[0] = ((color >> 24) & 0xff) / 255.0; | ||
36 | dest[1] = ((color >> 16) & 0xff) / 255.0; | ||
37 | dest[2] = ((color >> 8) & 0xff) / 255.0; | ||
38 | dest[3] = (color & 0xff) / 255.0; | ||
39 | } | ||
40 | |||
34 | bool parse_boolean(const char *boolean, bool current) { | 41 | bool parse_boolean(const char *boolean, bool current) { |
35 | if (strcasecmp(boolean, "1") == 0 | 42 | if (strcasecmp(boolean, "1") == 0 |
36 | || strcasecmp(boolean, "yes") == 0 | 43 | || strcasecmp(boolean, "yes") == 0 |
diff --git a/include/util.h b/include/util.h index 931ac691..867eb0a4 100644 --- a/include/util.h +++ b/include/util.h | |||
@@ -17,6 +17,8 @@ int wrap(int i, int max); | |||
17 | */ | 17 | */ |
18 | bool parse_color(const char *color, uint32_t *result); | 18 | bool parse_color(const char *color, uint32_t *result); |
19 | 19 | ||
20 | void color_to_rgba(float dest[static 4], uint32_t color); | ||
21 | |||
20 | /** | 22 | /** |
21 | * Given a string that represents a boolean, return the boolean value. This | 23 | * Given a string that represents a boolean, return the boolean value. This |
22 | * function also takes in the current boolean value to support toggling. If | 24 | * function also takes in the current boolean value to support toggling. If |
diff --git a/sway/commands/client.c b/sway/commands/client.c index f5c7d90f..e4282341 100644 --- a/sway/commands/client.c +++ b/sway/commands/client.c | |||
@@ -3,56 +3,13 @@ | |||
3 | #include "sway/config.h" | 3 | #include "sway/config.h" |
4 | #include "sway/output.h" | 4 | #include "sway/output.h" |
5 | #include "sway/tree/container.h" | 5 | #include "sway/tree/container.h" |
6 | #include "util.h" | ||
6 | 7 | ||
7 | static void rebuild_textures_iterator(struct sway_container *con, void *data) { | 8 | static void rebuild_textures_iterator(struct sway_container *con, void *data) { |
8 | container_update_marks_textures(con); | 9 | container_update_marks_textures(con); |
9 | container_update_title_textures(con); | 10 | container_update_title_textures(con); |
10 | } | 11 | } |
11 | 12 | ||
12 | /** | ||
13 | * Parse the hex string into an integer. | ||
14 | */ | ||
15 | static bool parse_color_int(char *hexstring, uint32_t *dest) { | ||
16 | if (hexstring[0] != '#') { | ||
17 | return false; | ||
18 | } | ||
19 | |||
20 | if (strlen(hexstring) != 7 && strlen(hexstring) != 9) { | ||
21 | return false; | ||
22 | } | ||
23 | |||
24 | ++hexstring; | ||
25 | char *end; | ||
26 | uint32_t decimal = strtol(hexstring, &end, 16); | ||
27 | |||
28 | if (*end != '\0') { | ||
29 | return false; | ||
30 | } | ||
31 | |||
32 | if (strlen(hexstring) == 6) { | ||
33 | // Add alpha | ||
34 | decimal = (decimal << 8) | 0xff; | ||
35 | } | ||
36 | |||
37 | *dest = decimal; | ||
38 | return true; | ||
39 | } | ||
40 | |||
41 | /** | ||
42 | * Parse the hex string into a float value. | ||
43 | */ | ||
44 | static bool parse_color_float(char *hexstring, float dest[static 4]) { | ||
45 | uint32_t decimal; | ||
46 | if (!parse_color_int(hexstring, &decimal)) { | ||
47 | return false; | ||
48 | } | ||
49 | dest[0] = ((decimal >> 24) & 0xff) / 255.0; | ||
50 | dest[1] = ((decimal >> 16) & 0xff) / 255.0; | ||
51 | dest[2] = ((decimal >> 8) & 0xff) / 255.0; | ||
52 | dest[3] = (decimal & 0xff) / 255.0; | ||
53 | return true; | ||
54 | } | ||
55 | |||
56 | static struct cmd_results *handle_command(int argc, char **argv, | 13 | static struct cmd_results *handle_command(int argc, char **argv, |
57 | struct border_colors *class, char *cmd_name) { | 14 | struct border_colors *class, char *cmd_name) { |
58 | struct cmd_results *error = NULL; | 15 | struct cmd_results *error = NULL; |
@@ -60,30 +17,28 @@ static struct cmd_results *handle_command(int argc, char **argv, | |||
60 | return error; | 17 | return error; |
61 | } | 18 | } |
62 | 19 | ||
63 | if (!parse_color_float(argv[0], class->border)) { | 20 | struct border_colors colors = {0}; |
64 | return cmd_results_new(CMD_INVALID, | 21 | |
65 | "Unable to parse border color '%s'", argv[0]); | 22 | struct { |
66 | } | 23 | const char *name; |
67 | 24 | float *rgba[4]; | |
68 | if (!parse_color_float(argv[1], class->background)) { | 25 | } properties[] = { |
69 | return cmd_results_new(CMD_INVALID, | 26 | { "border", colors.border }, |
70 | "Unable to parse background color '%s'", argv[1]); | 27 | { "background", colors.background }, |
71 | } | 28 | { "text", colors.text }, |
72 | 29 | { "indicator", colors.indicator }, | |
73 | if (!parse_color_float(argv[2], class->text)) { | 30 | { "child_border", colors.child_border } |
74 | return cmd_results_new(CMD_INVALID, | 31 | }; |
75 | "Unable to parse text color '%s'", argv[2]); | 32 | for (size_t i = 0; i < sizeof(properties) / sizeof(properties[0]); i++) { |
76 | } | 33 | uint32_t color; |
77 | 34 | if (!parse_color(argv[i], &color)) { | |
78 | if (!parse_color_float(argv[3], class->indicator)) { | 35 | return cmd_results_new(CMD_INVALID, |
79 | return cmd_results_new(CMD_INVALID, | 36 | "Invalid %s color %s", properties[i].name, argv[i]); |
80 | "Unable to parse indicator color '%s'", argv[3]); | 37 | } |
38 | color_to_rgba(*properties[i].rgba, color); | ||
81 | } | 39 | } |
82 | 40 | ||
83 | if (!parse_color_float(argv[4], class->child_border)) { | 41 | memcpy(class, &colors, sizeof(struct border_colors)); |
84 | return cmd_results_new(CMD_INVALID, | ||
85 | "Unable to parse child border color '%s'", argv[4]); | ||
86 | } | ||
87 | 42 | ||
88 | if (config->active) { | 43 | if (config->active) { |
89 | root_for_each_container(rebuild_textures_iterator, NULL); | 44 | root_for_each_container(rebuild_textures_iterator, NULL); |
diff --git a/sway/config.c b/sway/config.c index 34704277..6d730f46 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include "stringop.h" | 31 | #include "stringop.h" |
32 | #include "list.h" | 32 | #include "list.h" |
33 | #include "log.h" | 33 | #include "log.h" |
34 | #include "util.h" | ||
34 | 35 | ||
35 | struct sway_config *config = NULL; | 36 | struct sway_config *config = NULL; |
36 | 37 | ||
@@ -192,13 +193,6 @@ static void destroy_removed_seats(struct sway_config *old_config, | |||
192 | } | 193 | } |
193 | } | 194 | } |
194 | 195 | ||
195 | static void set_color(float dest[static 4], uint32_t color) { | ||
196 | dest[0] = ((color >> 16) & 0xff) / 255.0; | ||
197 | dest[1] = ((color >> 8) & 0xff) / 255.0; | ||
198 | dest[2] = (color & 0xff) / 255.0; | ||
199 | dest[3] = 1.0; | ||
200 | } | ||
201 | |||
202 | static void config_defaults(struct sway_config *config) { | 196 | static void config_defaults(struct sway_config *config) { |
203 | if (!(config->swaynag_command = strdup("swaynag"))) goto cleanup; | 197 | if (!(config->swaynag_command = strdup("swaynag"))) goto cleanup; |
204 | config->swaynag_config_errors = (struct swaynag_instance){0}; | 198 | config->swaynag_config_errors = (struct swaynag_instance){0}; |
@@ -300,37 +294,37 @@ static void config_defaults(struct sway_config *config) { | |||
300 | config->hide_lone_tab = false; | 294 | config->hide_lone_tab = false; |
301 | 295 | ||
302 | // border colors | 296 | // border colors |
303 | set_color(config->border_colors.focused.border, 0x4C7899); | 297 | color_to_rgba(config->border_colors.focused.border, 0x4C7899FF); |
304 | set_color(config->border_colors.focused.background, 0x285577); | 298 | color_to_rgba(config->border_colors.focused.background, 0x285577FF); |
305 | set_color(config->border_colors.focused.text, 0xFFFFFFFF); | 299 | color_to_rgba(config->border_colors.focused.text, 0xFFFFFFFF); |
306 | set_color(config->border_colors.focused.indicator, 0x2E9EF4); | 300 | color_to_rgba(config->border_colors.focused.indicator, 0x2E9EF4FF); |
307 | set_color(config->border_colors.focused.child_border, 0x285577); | 301 | color_to_rgba(config->border_colors.focused.child_border, 0x285577FF); |
308 | 302 | ||
309 | set_color(config->border_colors.focused_inactive.border, 0x333333); | 303 | color_to_rgba(config->border_colors.focused_inactive.border, 0x333333FF); |
310 | set_color(config->border_colors.focused_inactive.background, 0x5F676A); | 304 | color_to_rgba(config->border_colors.focused_inactive.background, 0x5F676AFF); |
311 | set_color(config->border_colors.focused_inactive.text, 0xFFFFFFFF); | 305 | color_to_rgba(config->border_colors.focused_inactive.text, 0xFFFFFFFF); |
312 | set_color(config->border_colors.focused_inactive.indicator, 0x484E50); | 306 | color_to_rgba(config->border_colors.focused_inactive.indicator, 0x484E50FF); |
313 | set_color(config->border_colors.focused_inactive.child_border, 0x5F676A); | 307 | color_to_rgba(config->border_colors.focused_inactive.child_border, 0x5F676AFF); |
314 | 308 | ||
315 | set_color(config->border_colors.unfocused.border, 0x333333); | 309 | color_to_rgba(config->border_colors.unfocused.border, 0x333333FF); |
316 | set_color(config->border_colors.unfocused.background, 0x222222); | 310 | color_to_rgba(config->border_colors.unfocused.background, 0x222222FF); |
317 | set_color(config->border_colors.unfocused.text, 0x88888888); | 311 | color_to_rgba(config->border_colors.unfocused.text, 0x88888888); |
318 | set_color(config->border_colors.unfocused.indicator, 0x292D2E); | 312 | color_to_rgba(config->border_colors.unfocused.indicator, 0x292D2EFF); |
319 | set_color(config->border_colors.unfocused.child_border, 0x222222); | 313 | color_to_rgba(config->border_colors.unfocused.child_border, 0x222222FF); |
320 | 314 | ||
321 | set_color(config->border_colors.urgent.border, 0x2F343A); | 315 | color_to_rgba(config->border_colors.urgent.border, 0x2F343AFF); |
322 | set_color(config->border_colors.urgent.background, 0x900000); | 316 | color_to_rgba(config->border_colors.urgent.background, 0x900000FF); |
323 | set_color(config->border_colors.urgent.text, 0xFFFFFFFF); | 317 | color_to_rgba(config->border_colors.urgent.text, 0xFFFFFFFF); |
324 | set_color(config->border_colors.urgent.indicator, 0x900000); | 318 | color_to_rgba(config->border_colors.urgent.indicator, 0x900000FF); |
325 | set_color(config->border_colors.urgent.child_border, 0x900000); | 319 | color_to_rgba(config->border_colors.urgent.child_border, 0x900000FF); |
326 | 320 | ||
327 | set_color(config->border_colors.placeholder.border, 0x000000); | 321 | color_to_rgba(config->border_colors.placeholder.border, 0x000000FF); |
328 | set_color(config->border_colors.placeholder.background, 0x0C0C0C); | 322 | color_to_rgba(config->border_colors.placeholder.background, 0x0C0C0CFF); |
329 | set_color(config->border_colors.placeholder.text, 0xFFFFFFFF); | 323 | color_to_rgba(config->border_colors.placeholder.text, 0xFFFFFFFF); |
330 | set_color(config->border_colors.placeholder.indicator, 0x000000); | 324 | color_to_rgba(config->border_colors.placeholder.indicator, 0x000000FF); |
331 | set_color(config->border_colors.placeholder.child_border, 0x0C0C0C); | 325 | color_to_rgba(config->border_colors.placeholder.child_border, 0x0C0C0CFF); |
332 | 326 | ||
333 | set_color(config->border_colors.background, 0xFFFFFF); | 327 | color_to_rgba(config->border_colors.background, 0xFFFFFFFF); |
334 | 328 | ||
335 | // Security | 329 | // Security |
336 | if (!(config->command_policies = create_list())) goto cleanup; | 330 | if (!(config->command_policies = create_list())) goto cleanup; |