mirror of
https://github.com/gwenhael-le-moine/sway-patched-tray-menu.git
synced 2024-12-28 22:23:42 +01:00
af45ee2d8b
This changes it back so the path given to swaybg is enclosed in quotes. Additionally, the only character that is escaped in the path stored is double quotes now. This makes it so we don't need to keep an exhaustive list of characters that need to be escaped. The end user will still need to escape these characters in their config or when passed to swaybg.
160 lines
4.2 KiB
C
160 lines
4.2 KiB
C
#define _POSIX_C_SOURCE 200809
|
|
#include <libgen.h>
|
|
#include <strings.h>
|
|
#include <unistd.h>
|
|
#include <wordexp.h>
|
|
#include <errno.h>
|
|
#include "sway/commands.h"
|
|
#include "sway/config.h"
|
|
#include "sway/swaynag.h"
|
|
#include "log.h"
|
|
#include "stringop.h"
|
|
|
|
static const char *bg_options[] = {
|
|
"stretch",
|
|
"center",
|
|
"fill",
|
|
"fit",
|
|
"tile",
|
|
};
|
|
|
|
struct cmd_results *output_cmd_background(int argc, char **argv) {
|
|
if (!config->handler_context.output_config) {
|
|
return cmd_results_new(CMD_FAILURE, "output", "Missing output config");
|
|
}
|
|
if (!argc) {
|
|
return cmd_results_new(CMD_INVALID, "output",
|
|
"Missing background file or color specification.");
|
|
}
|
|
if (argc < 2) {
|
|
return cmd_results_new(CMD_INVALID, "output",
|
|
"Missing background scaling mode or `solid_color`.");
|
|
}
|
|
|
|
struct output_config *output = config->handler_context.output_config;
|
|
|
|
if (strcasecmp(argv[1], "solid_color") == 0) {
|
|
output->background = calloc(1, strlen(argv[0]) + 3);
|
|
snprintf(output->background, strlen(argv[0]) + 3, "\"%s\"", argv[0]);
|
|
output->background_option = strdup("solid_color");
|
|
output->background_fallback = NULL;
|
|
argc -= 2; argv += 2;
|
|
} else {
|
|
bool valid = false;
|
|
char *mode;
|
|
size_t j;
|
|
for (j = 0; j < (size_t)argc; ++j) {
|
|
mode = argv[j];
|
|
size_t n = sizeof(bg_options) / sizeof(char *);
|
|
for (size_t k = 0; k < n; ++k) {
|
|
if (strcasecmp(mode, bg_options[k]) == 0) {
|
|
valid = true;
|
|
break;
|
|
}
|
|
}
|
|
if (valid) {
|
|
break;
|
|
}
|
|
}
|
|
if (!valid) {
|
|
return cmd_results_new(CMD_INVALID, "output",
|
|
"Missing background scaling mode.");
|
|
}
|
|
|
|
wordexp_t p = {0};
|
|
char *src = join_args(argv, j);
|
|
while (strstr(src, " ")) {
|
|
src = realloc(src, strlen(src) + 2);
|
|
char *ptr = strstr(src, " ") + 1;
|
|
memmove(ptr + 1, ptr, strlen(ptr) + 1);
|
|
*ptr = '\\';
|
|
}
|
|
if (wordexp(src, &p, 0) != 0 || p.we_wordv[0] == NULL) {
|
|
struct cmd_results *cmd_res = cmd_results_new(CMD_INVALID, "output",
|
|
"Invalid syntax (%s)", src);
|
|
free(src);
|
|
wordfree(&p);
|
|
return cmd_res;
|
|
}
|
|
free(src);
|
|
src = join_args(p.we_wordv, p.we_wordc);
|
|
wordfree(&p);
|
|
if (!src) {
|
|
wlr_log(WLR_ERROR, "Failed to duplicate string");
|
|
return cmd_results_new(CMD_FAILURE, "output",
|
|
"Unable to allocate resource");
|
|
}
|
|
|
|
if (config->reading && *src != '/') {
|
|
// src file is inside configuration dir
|
|
|
|
char *conf = strdup(config->current_config_path);
|
|
if (!conf) {
|
|
wlr_log(WLR_ERROR, "Failed to duplicate string");
|
|
free(src);
|
|
return cmd_results_new(CMD_FAILURE, "output",
|
|
"Unable to allocate resources");
|
|
}
|
|
|
|
char *conf_path = dirname(conf);
|
|
char *rel_path = src;
|
|
src = malloc(strlen(conf_path) + strlen(src) + 2);
|
|
if (!src) {
|
|
free(rel_path);
|
|
free(conf);
|
|
wlr_log(WLR_ERROR, "Unable to allocate memory");
|
|
return cmd_results_new(CMD_FAILURE, "output",
|
|
"Unable to allocate resources");
|
|
}
|
|
|
|
sprintf(src, "%s/%s", conf_path, rel_path);
|
|
free(rel_path);
|
|
free(conf);
|
|
}
|
|
|
|
bool can_access = access(src, F_OK) != -1;
|
|
if (!can_access) {
|
|
wlr_log(WLR_ERROR, "Unable to access background file '%s': %s",
|
|
src, strerror(errno));
|
|
if (config->reading && !config->validating) {
|
|
swaynag_log(config->swaynag_command,
|
|
&config->swaynag_config_errors,
|
|
"Unable to access background file '%s'", src);
|
|
}
|
|
free(src);
|
|
} else {
|
|
// Escape double quotes in the final path for swaybg
|
|
for (size_t i = 0; i < strlen(src); i++) {
|
|
if (src[i] == '"') {
|
|
src = realloc(src, strlen(src) + 2);
|
|
memmove(src + i + 1, src + i, strlen(src + i) + 1);
|
|
*(src + i) = '\\';
|
|
i++;
|
|
}
|
|
}
|
|
|
|
output->background = src;
|
|
output->background_option = strdup(mode);
|
|
}
|
|
argc -= j + 1; argv += j + 1;
|
|
|
|
output->background_fallback = NULL;
|
|
if (argc && *argv[0] == '#') {
|
|
output->background_fallback = calloc(1, strlen(argv[0]) + 3);
|
|
snprintf(output->background_fallback, strlen(argv[0]) + 3,
|
|
"\"%s\"", argv[0]);
|
|
argc--; argv++;
|
|
|
|
if (!can_access) {
|
|
output->background = output->background_fallback;
|
|
output->background_option = strdup("solid_color");
|
|
output->background_fallback = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
config->handler_context.leftovers.argc = argc;
|
|
config->handler_context.leftovers.argv = argv;
|
|
return NULL;
|
|
}
|
|
|