Allow a fallback color to be specified for swaybg

This allows for a color to be set when the wallpaper does not fill the
entire output. If specified, the fallback color is also used when the
image path is inaccessible.
This commit is contained in:
Brian Ashworth 2018-08-08 13:46:36 -04:00
parent fc039f0759
commit 43d1ffc9dd
5 changed files with 57 additions and 14 deletions

View file

@ -151,6 +151,7 @@ struct output_config {
char *background; char *background;
char *background_option; char *background_option;
char *background_fallback;
enum config_dpms dpms_state; enum config_dpms dpms_state;
}; };

View file

@ -6,6 +6,7 @@
#include <errno.h> #include <errno.h>
#include "sway/commands.h" #include "sway/commands.h"
#include "sway/config.h" #include "sway/config.h"
#include "sway/swaynag.h"
#include "log.h" #include "log.h"
#include "stringop.h" #include "stringop.h"
@ -36,6 +37,7 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
output->background = calloc(1, strlen(argv[0]) + 3); output->background = calloc(1, strlen(argv[0]) + 3);
snprintf(output->background, strlen(argv[0]) + 3, "\"%s\"", argv[0]); snprintf(output->background, strlen(argv[0]) + 3, "\"%s\"", argv[0]);
output->background_option = strdup("solid_color"); output->background_option = strdup("solid_color");
output->background_fallback = NULL;
argc -= 2; argv += 2; argc -= 2; argv += 2;
} else { } else {
bool valid = false; bool valid = false;
@ -104,16 +106,35 @@ struct cmd_results *output_cmd_background(int argc, char **argv) {
free(conf); free(conf);
} }
if (access(src, F_OK) == -1) { bool can_access = access(src, F_OK) != -1;
struct cmd_results *cmd_res = cmd_results_new(CMD_FAILURE, "output", if (!can_access) {
"Unable to access background file '%s': %s", src, strerror(errno)); wlr_log(WLR_ERROR, "Unable to access background file '%s': %s",
free(src); src, strerror(errno));
return cmd_res; if (!config->validating) {
swaynag_log(config->swaynag_command,
&config->swaynag_config_errors,
"Unable to access background file '%s'", src);
} }
free(src);
} else {
output->background = src; output->background = src;
output->background_option = strdup(mode); output->background_option = strdup(mode);
}
argc -= j + 1; argv += j + 1; 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.argc = argc;

View file

@ -77,6 +77,10 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
free(dst->background_option); free(dst->background_option);
dst->background_option = strdup(src->background_option); dst->background_option = strdup(src->background_option);
} }
if (src->background_fallback) {
free(dst->background_fallback);
dst->background_fallback = strdup(src->background_fallback);
}
if (src->dpms_state != 0) { if (src->dpms_state != 0) {
dst->dpms_state = src->dpms_state; dst->dpms_state = src->dpms_state;
} }
@ -226,17 +230,19 @@ void apply_output_config(struct output_config *oc, struct sway_container *output
wlr_log(WLR_DEBUG, "Setting background for output %d to %s", wlr_log(WLR_DEBUG, "Setting background for output %d to %s",
output_i, oc->background); output_i, oc->background);
size_t len = snprintf(NULL, 0, "%s %d %s %s", size_t len = snprintf(NULL, 0, "%s %d %s %s %s",
config->swaybg_command ? config->swaybg_command : "swaybg", config->swaybg_command ? config->swaybg_command : "swaybg",
output_i, oc->background, oc->background_option); output_i, oc->background, oc->background_option,
oc->background_fallback ? oc->background_fallback : "");
char *command = malloc(len + 1); char *command = malloc(len + 1);
if (!command) { if (!command) {
wlr_log(WLR_DEBUG, "Unable to allocate swaybg command"); wlr_log(WLR_DEBUG, "Unable to allocate swaybg command");
return; return;
} }
snprintf(command, len + 1, "%s %d %s %s", snprintf(command, len + 1, "%s %d %s %s %s",
config->swaybg_command ? config->swaybg_command : "swaybg", config->swaybg_command ? config->swaybg_command : "swaybg",
output_i, oc->background, oc->background_option); output_i, oc->background, oc->background_option,
oc->background_fallback ? oc->background_fallback : "");
wlr_log(WLR_DEBUG, "-> %s", command); wlr_log(WLR_DEBUG, "-> %s", command);
char *const cmd[] = { "sh", "-c", command, NULL }; char *const cmd[] = { "sh", "-c", command, NULL };

View file

@ -489,9 +489,13 @@ The default colors are:
setting an integral scale factor and adjusting the font size of your setting an integral scale factor and adjusting the font size of your
applications to taste. applications to taste.
*output* <name> background|bg <file> <mode> *output* <name> background|bg <file> <mode> [<fallback\_color>]
Sets the wallpaper for the given output to the specified file, using the Sets the wallpaper for the given output to the specified file, using the
given scaling mode (one of "stretch", "fill", "fit", "center", "tile"). given scaling mode (one of "stretch", "fill", "fit", "center", "tile"). If
the specified file cannot be accessed or if the image does fill the entire
output, a fallback color may be provided to cover the rest of the output.
__fallback\_color__ should be specified as _#RRGGBB_. Alpha is not
supported.
**output** <name> background|bg <color> solid\_color **output** <name> background|bg <color> solid\_color
Sets the background of the given output to the specified color. _color_ Sets the background of the given output to the specified color. _color_

View file

@ -17,6 +17,7 @@ struct swaybg_args {
int output_idx; int output_idx;
const char *path; const char *path;
enum background_mode mode; enum background_mode mode;
const char *fallback;
}; };
struct swaybg_context { struct swaybg_context {
@ -76,6 +77,10 @@ static void render_frame(struct swaybg_state *state) {
cairo_set_source_u32(cairo, state->context.color); cairo_set_source_u32(cairo, state->context.color);
cairo_paint(cairo); cairo_paint(cairo);
} else { } else {
if (state->args->fallback && state->context.color) {
cairo_set_source_u32(cairo, state->context.color);
cairo_paint(cairo);
}
render_background_image(cairo, state->context.image, render_background_image(cairo, state->context.image,
state->args->mode, buffer_width, buffer_height); state->args->mode, buffer_width, buffer_height);
} }
@ -91,6 +96,9 @@ static bool prepare_context(struct swaybg_state *state) {
state->context.color = parse_color(state->args->path); state->context.color = parse_color(state->args->path);
return is_valid_color(state->args->path); return is_valid_color(state->args->path);
} }
if (state->args->fallback && is_valid_color(state->args->fallback)) {
state->context.color = parse_color(state->args->fallback);
}
if (!(state->context.image = load_background_image(state->args->path))) { if (!(state->context.image = load_background_image(state->args->path))) {
return false; return false;
} }
@ -190,7 +198,7 @@ int main(int argc, const char **argv) {
state.args = &args; state.args = &args;
wlr_log_init(WLR_DEBUG, NULL); wlr_log_init(WLR_DEBUG, NULL);
if (argc != 4) { if (argc < 4 || argc > 5) {
wlr_log(WLR_ERROR, "Do not run this program manually. " wlr_log(WLR_ERROR, "Do not run this program manually. "
"See man 5 sway and look for output options."); "See man 5 sway and look for output options.");
return 1; return 1;
@ -202,6 +210,9 @@ int main(int argc, const char **argv) {
if (args.mode == BACKGROUND_MODE_INVALID) { if (args.mode == BACKGROUND_MODE_INVALID) {
return 1; return 1;
} }
args.fallback = argc == 5 ? argv[4] : NULL;
if (!prepare_context(&state)) { if (!prepare_context(&state)) {
return 1; return 1;
} }