From 6914a7158f5152829b9013bd28e2d2f9f991b765 Mon Sep 17 00:00:00 2001 From: Manuel Stoeckl Date: Sun, 9 Feb 2025 09:33:45 -0500 Subject: [PATCH] output/background: parse background mode into enum This simplifies the logic in `output_cmd_background` by avoiding strdup() calls (and their error handling paths) for the background mode. It also fixes a mismatch between the "background" subcommand (which accepts mode names case-insensitively) and swaybg (which does not, requiring lowercase). --- include/sway/config.h | 13 ++++++++++- sway/commands/output/background.c | 37 +++++++++++++++---------------- sway/config/output.c | 25 +++++++++------------ 3 files changed, 41 insertions(+), 34 deletions(-) diff --git a/include/sway/config.h b/include/sway/config.h index bb770c6f7f..54510e3a17 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -267,6 +267,17 @@ enum render_bit_depth { RENDER_BIT_DEPTH_10, }; +enum background_mode { + BACKGROUND_MODE_UNSET, // there is no default + BACKGROUND_MODE_SOLID_COLOR, + BACKGROUND_MODE_STRETCH, + BACKGROUND_MODE_CENTER, + BACKGROUND_MODE_FILL, + BACKGROUND_MODE_FIT, + BACKGROUND_MODE_TILE, +}; +extern const char *const background_mode_names[]; + /** * Size and position configuration for a particular output. * @@ -293,7 +304,7 @@ struct output_config { int allow_tearing; char *background; - char *background_option; + enum background_mode background_option; char *background_fallback; }; diff --git a/sway/commands/output/background.c b/sway/commands/output/background.c index fe16216261..502fe4565e 100644 --- a/sway/commands/output/background.c +++ b/sway/commands/output/background.c @@ -8,12 +8,14 @@ #include "log.h" #include "stringop.h" -static const char *bg_options[] = { - "stretch", - "center", - "fill", - "fit", - "tile", +const char *const background_mode_names[] = { + [BACKGROUND_MODE_UNSET] = "unset", + [BACKGROUND_MODE_SOLID_COLOR] = "solid_color", + [BACKGROUND_MODE_STRETCH] = "stretch", + [BACKGROUND_MODE_CENTER] = "center", + [BACKGROUND_MODE_FILL] = "fill", + [BACKGROUND_MODE_FIT] = "fit", + [BACKGROUND_MODE_TILE] = "tile", }; static bool validate_color(const char *color) { @@ -47,27 +49,25 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { "Colors should be of the form #RRGGBB"); } if (!(output->background = strdup(argv[0]))) goto cleanup; - if (!(output->background_option = strdup("solid_color"))) goto cleanup; + output->background_option = BACKGROUND_MODE_SOLID_COLOR; output->background_fallback = NULL; argc -= 2; argv += 2; } else { - bool valid = false; - char *mode; + enum background_mode mode = BACKGROUND_MODE_UNSET; size_t j; for (j = 0; j < (size_t)argc; ++j) { - mode = argv[j]; - size_t n = sizeof(bg_options) / sizeof(char *); + size_t n = sizeof(background_mode_names) / sizeof(char *); for (size_t k = 0; k < n; ++k) { - if (strcasecmp(mode, bg_options[k]) == 0) { - valid = true; + if (strcasecmp(argv[j], background_mode_names[k]) == 0) { + mode = k; break; } } - if (valid) { + if (mode != BACKGROUND_MODE_UNSET) { break; } } - if (!valid) { + if (mode == BACKGROUND_MODE_UNSET) { return cmd_results_new(CMD_INVALID, "Missing background scaling mode."); } @@ -104,10 +104,9 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { bool can_access = access(src, F_OK) != -1; argc -= j + 1; argv += j + 1; - free(output->background_option); free(output->background_fallback); free(output->background); - output->background = output->background_option = output->background_fallback = NULL; + output->background = output->background_fallback = NULL; char *fallback = NULL; if (argc && *argv[0] == '#') { @@ -132,11 +131,11 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { } sway_log(SWAY_DEBUG, "Cannot access file '%s', using fallback '%s'", src, fallback); output->background = fallback; - if (!(output->background_option = strdup("solid_color"))) goto cleanup; + output->background_option = BACKGROUND_MODE_SOLID_COLOR; output->background_fallback = NULL; } else { output->background = src; - if (!(output->background_option = strdup(mode))) goto cleanup; + output->background_option = mode; } } config->handler_context.leftovers.argc = argc; diff --git a/sway/config/output.c b/sway/config/output.c index 9fb3a12ac2..d93fb03f8c 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -133,9 +133,8 @@ static void supersede_output_config(struct output_config *dst, struct output_con free(dst->background); dst->background = NULL; } - if (src->background_option) { - free(dst->background_option); - dst->background_option = NULL; + if (src->background_option != BACKGROUND_MODE_UNSET) { + dst->background_option = BACKGROUND_MODE_UNSET; } if (src->background_fallback) { free(dst->background_fallback); @@ -205,9 +204,8 @@ static void merge_output_config(struct output_config *dst, struct output_config free(dst->background); dst->background = strdup(src->background); } - if (src->background_option) { - free(dst->background_option); - dst->background_option = strdup(src->background_option); + if (src->background_option != BACKGROUND_MODE_UNSET) { + dst->background_option = src->background_option; } if (src->background_fallback) { free(dst->background_fallback); @@ -264,7 +262,7 @@ void store_output_config(struct output_config *oc) { "(max render time: %d) (allow tearing: %d)", oc->name, oc->enabled, oc->width, oc->height, oc->refresh_rate, oc->x, oc->y, oc->scale, sway_wl_output_subpixel_to_string(oc->subpixel), - oc->transform, oc->background, oc->background_option, oc->power, + oc->transform, oc->background, background_mode_names[oc->background_option], oc->power, oc->max_render_time, oc->allow_tearing); // If the configuration was not merged into an existing configuration, add @@ -1017,7 +1015,6 @@ void free_output_config(struct output_config *oc) { } free(oc->name); free(oc->background); - free(oc->background_option); free(oc->background_fallback); wlr_color_transform_unref(oc->color_transform); free(oc); @@ -1032,7 +1029,7 @@ static void handle_swaybg_client_destroy(struct wl_listener *listener, sway_config->swaybg_client = NULL; } -static bool _spawn_swaybg(char **command) { +static bool _spawn_swaybg(const char **command) { if (config->swaybg_client != NULL) { wl_client_destroy(config->swaybg_client); } @@ -1076,7 +1073,7 @@ static bool _spawn_swaybg(char **command) { "%d", sockets[1]); setenv("WAYLAND_SOCKET", wayland_socket_str, true); - execvp(command[0], command); + execvp(command[0], (char *const *)command); sway_log_errno(SWAY_ERROR, "failed to execute '%s' " "(background configuration probably not applied)", command[0]); @@ -1109,7 +1106,7 @@ bool spawn_swaybg(void) { if (!oc->background) { continue; } - if (strcmp(oc->background_option, "solid_color") == 0) { + if (oc->background_option == BACKGROUND_MODE_SOLID_COLOR) { length += 4; } else if (oc->background_fallback) { length += 8; @@ -1118,7 +1115,7 @@ bool spawn_swaybg(void) { } } - char **cmd = calloc(length, sizeof(char *)); + const char **cmd = calloc(length, sizeof(const char *)); if (!cmd) { sway_log(SWAY_ERROR, "Failed to allocate spawn_swaybg command"); return false; @@ -1131,7 +1128,7 @@ bool spawn_swaybg(void) { if (!oc->background) { continue; } - if (strcmp(oc->background_option, "solid_color") == 0) { + if (oc->background_option == BACKGROUND_MODE_SOLID_COLOR) { cmd[i++] = "-o"; cmd[i++] = oc->name; cmd[i++] = "-c"; @@ -1142,7 +1139,7 @@ bool spawn_swaybg(void) { cmd[i++] = "-i"; cmd[i++] = oc->background; cmd[i++] = "-m"; - cmd[i++] = oc->background_option; + cmd[i++] = background_mode_names[oc->background_option]; if (oc->background_fallback) { cmd[i++] = "-c"; cmd[i++] = oc->background_fallback;