diff options
-rw-r--r-- | include/sway/config.h | 1 | ||||
-rw-r--r-- | sway/commands/output/background.c | 35 | ||||
-rw-r--r-- | sway/config/output.c | 14 | ||||
-rw-r--r-- | sway/sway.5.scd | 8 | ||||
-rw-r--r-- | swaybg/main.c | 13 |
5 files changed, 57 insertions, 14 deletions
diff --git a/include/sway/config.h b/include/sway/config.h index 632aca14..c2eaea1b 100644 --- a/include/sway/config.h +++ b/include/sway/config.h | |||
@@ -151,6 +151,7 @@ struct output_config { | |||
151 | 151 | ||
152 | char *background; | 152 | char *background; |
153 | char *background_option; | 153 | char *background_option; |
154 | char *background_fallback; | ||
154 | enum config_dpms dpms_state; | 155 | enum config_dpms dpms_state; |
155 | }; | 156 | }; |
156 | 157 | ||
diff --git a/sway/commands/output/background.c b/sway/commands/output/background.c index 4ed56c2a..e45b571e 100644 --- a/sway/commands/output/background.c +++ b/sway/commands/output/background.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <errno.h> | 6 | #include <errno.h> |
7 | #include "sway/commands.h" | 7 | #include "sway/commands.h" |
8 | #include "sway/config.h" | 8 | #include "sway/config.h" |
9 | #include "sway/swaynag.h" | ||
9 | #include "log.h" | 10 | #include "log.h" |
10 | #include "stringop.h" | 11 | #include "stringop.h" |
11 | 12 | ||
@@ -36,6 +37,7 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { | |||
36 | output->background = calloc(1, strlen(argv[0]) + 3); | 37 | output->background = calloc(1, strlen(argv[0]) + 3); |
37 | snprintf(output->background, strlen(argv[0]) + 3, "\"%s\"", argv[0]); | 38 | snprintf(output->background, strlen(argv[0]) + 3, "\"%s\"", argv[0]); |
38 | output->background_option = strdup("solid_color"); | 39 | output->background_option = strdup("solid_color"); |
40 | output->background_fallback = NULL; | ||
39 | argc -= 2; argv += 2; | 41 | argc -= 2; argv += 2; |
40 | } else { | 42 | } else { |
41 | bool valid = false; | 43 | bool valid = false; |
@@ -104,16 +106,35 @@ struct cmd_results *output_cmd_background(int argc, char **argv) { | |||
104 | free(conf); | 106 | free(conf); |
105 | } | 107 | } |
106 | 108 | ||
107 | if (access(src, F_OK) == -1) { | 109 | bool can_access = access(src, F_OK) != -1; |
108 | struct cmd_results *cmd_res = cmd_results_new(CMD_FAILURE, "output", | 110 | if (!can_access) { |
109 | "Unable to access background file '%s': %s", src, strerror(errno)); | 111 | wlr_log(WLR_ERROR, "Unable to access background file '%s': %s", |
112 | src, strerror(errno)); | ||
113 | if (!config->validating) { | ||
114 | swaynag_log(config->swaynag_command, | ||
115 | &config->swaynag_config_errors, | ||
116 | "Unable to access background file '%s'", src); | ||
117 | } | ||
110 | free(src); | 118 | free(src); |
111 | return cmd_res; | 119 | } else { |
120 | output->background = src; | ||
121 | output->background_option = strdup(mode); | ||
112 | } | 122 | } |
113 | |||
114 | output->background = src; | ||
115 | output->background_option = strdup(mode); | ||
116 | argc -= j + 1; argv += j + 1; | 123 | argc -= j + 1; argv += j + 1; |
124 | |||
125 | output->background_fallback = NULL; | ||
126 | if (argc && *argv[0] == '#') { | ||
127 | output->background_fallback = calloc(1, strlen(argv[0]) + 3); | ||
128 | snprintf(output->background_fallback, strlen(argv[0]) + 3, | ||
129 | "\"%s\"", argv[0]); | ||
130 | argc--; argv++; | ||
131 | |||
132 | if (!can_access) { | ||
133 | output->background = output->background_fallback; | ||
134 | output->background_option = strdup("solid_color"); | ||
135 | output->background_fallback = NULL; | ||
136 | } | ||
137 | } | ||
117 | } | 138 | } |
118 | 139 | ||
119 | config->handler_context.leftovers.argc = argc; | 140 | config->handler_context.leftovers.argc = argc; |
diff --git a/sway/config/output.c b/sway/config/output.c index 504c48c6..1d8cb3ef 100644 --- a/sway/config/output.c +++ b/sway/config/output.c | |||
@@ -77,6 +77,10 @@ void merge_output_config(struct output_config *dst, struct output_config *src) { | |||
77 | free(dst->background_option); | 77 | free(dst->background_option); |
78 | dst->background_option = strdup(src->background_option); | 78 | dst->background_option = strdup(src->background_option); |
79 | } | 79 | } |
80 | if (src->background_fallback) { | ||
81 | free(dst->background_fallback); | ||
82 | dst->background_fallback = strdup(src->background_fallback); | ||
83 | } | ||
80 | if (src->dpms_state != 0) { | 84 | if (src->dpms_state != 0) { |
81 | dst->dpms_state = src->dpms_state; | 85 | dst->dpms_state = src->dpms_state; |
82 | } | 86 | } |
@@ -226,17 +230,19 @@ void apply_output_config(struct output_config *oc, struct sway_container *output | |||
226 | wlr_log(WLR_DEBUG, "Setting background for output %d to %s", | 230 | wlr_log(WLR_DEBUG, "Setting background for output %d to %s", |
227 | output_i, oc->background); | 231 | output_i, oc->background); |
228 | 232 | ||
229 | size_t len = snprintf(NULL, 0, "%s %d %s %s", | 233 | size_t len = snprintf(NULL, 0, "%s %d %s %s %s", |
230 | config->swaybg_command ? config->swaybg_command : "swaybg", | 234 | config->swaybg_command ? config->swaybg_command : "swaybg", |
231 | output_i, oc->background, oc->background_option); | 235 | output_i, oc->background, oc->background_option, |
236 | oc->background_fallback ? oc->background_fallback : ""); | ||
232 | char *command = malloc(len + 1); | 237 | char *command = malloc(len + 1); |
233 | if (!command) { | 238 | if (!command) { |
234 | wlr_log(WLR_DEBUG, "Unable to allocate swaybg command"); | 239 | wlr_log(WLR_DEBUG, "Unable to allocate swaybg command"); |
235 | return; | 240 | return; |
236 | } | 241 | } |
237 | snprintf(command, len + 1, "%s %d %s %s", | 242 | snprintf(command, len + 1, "%s %d %s %s %s", |
238 | config->swaybg_command ? config->swaybg_command : "swaybg", | 243 | config->swaybg_command ? config->swaybg_command : "swaybg", |
239 | output_i, oc->background, oc->background_option); | 244 | output_i, oc->background, oc->background_option, |
245 | oc->background_fallback ? oc->background_fallback : ""); | ||
240 | wlr_log(WLR_DEBUG, "-> %s", command); | 246 | wlr_log(WLR_DEBUG, "-> %s", command); |
241 | 247 | ||
242 | char *const cmd[] = { "sh", "-c", command, NULL }; | 248 | char *const cmd[] = { "sh", "-c", command, NULL }; |
diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 73a01152..31ab281b 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd | |||
@@ -489,9 +489,13 @@ The default colors are: | |||
489 | setting an integral scale factor and adjusting the font size of your | 489 | setting an integral scale factor and adjusting the font size of your |
490 | applications to taste. | 490 | applications to taste. |
491 | 491 | ||
492 | *output* <name> background|bg <file> <mode> | 492 | *output* <name> background|bg <file> <mode> [<fallback\_color>] |
493 | Sets the wallpaper for the given output to the specified file, using the | 493 | Sets the wallpaper for the given output to the specified file, using the |
494 | given scaling mode (one of "stretch", "fill", "fit", "center", "tile"). | 494 | given scaling mode (one of "stretch", "fill", "fit", "center", "tile"). If |
495 | the specified file cannot be accessed or if the image does fill the entire | ||
496 | output, a fallback color may be provided to cover the rest of the output. | ||
497 | __fallback\_color__ should be specified as _#RRGGBB_. Alpha is not | ||
498 | supported. | ||
495 | 499 | ||
496 | **output** <name> background|bg <color> solid\_color | 500 | **output** <name> background|bg <color> solid\_color |
497 | Sets the background of the given output to the specified color. _color_ | 501 | Sets the background of the given output to the specified color. _color_ |
diff --git a/swaybg/main.c b/swaybg/main.c index f8e7e7ef..5b0d0458 100644 --- a/swaybg/main.c +++ b/swaybg/main.c | |||
@@ -17,6 +17,7 @@ struct swaybg_args { | |||
17 | int output_idx; | 17 | int output_idx; |
18 | const char *path; | 18 | const char *path; |
19 | enum background_mode mode; | 19 | enum background_mode mode; |
20 | const char *fallback; | ||
20 | }; | 21 | }; |
21 | 22 | ||
22 | struct swaybg_context { | 23 | struct swaybg_context { |
@@ -76,6 +77,10 @@ static void render_frame(struct swaybg_state *state) { | |||
76 | cairo_set_source_u32(cairo, state->context.color); | 77 | cairo_set_source_u32(cairo, state->context.color); |
77 | cairo_paint(cairo); | 78 | cairo_paint(cairo); |
78 | } else { | 79 | } else { |
80 | if (state->args->fallback && state->context.color) { | ||
81 | cairo_set_source_u32(cairo, state->context.color); | ||
82 | cairo_paint(cairo); | ||
83 | } | ||
79 | render_background_image(cairo, state->context.image, | 84 | render_background_image(cairo, state->context.image, |
80 | state->args->mode, buffer_width, buffer_height); | 85 | state->args->mode, buffer_width, buffer_height); |
81 | } | 86 | } |
@@ -91,6 +96,9 @@ static bool prepare_context(struct swaybg_state *state) { | |||
91 | state->context.color = parse_color(state->args->path); | 96 | state->context.color = parse_color(state->args->path); |
92 | return is_valid_color(state->args->path); | 97 | return is_valid_color(state->args->path); |
93 | } | 98 | } |
99 | if (state->args->fallback && is_valid_color(state->args->fallback)) { | ||
100 | state->context.color = parse_color(state->args->fallback); | ||
101 | } | ||
94 | if (!(state->context.image = load_background_image(state->args->path))) { | 102 | if (!(state->context.image = load_background_image(state->args->path))) { |
95 | return false; | 103 | return false; |
96 | } | 104 | } |
@@ -190,7 +198,7 @@ int main(int argc, const char **argv) { | |||
190 | state.args = &args; | 198 | state.args = &args; |
191 | wlr_log_init(WLR_DEBUG, NULL); | 199 | wlr_log_init(WLR_DEBUG, NULL); |
192 | 200 | ||
193 | if (argc != 4) { | 201 | if (argc < 4 || argc > 5) { |
194 | wlr_log(WLR_ERROR, "Do not run this program manually. " | 202 | wlr_log(WLR_ERROR, "Do not run this program manually. " |
195 | "See man 5 sway and look for output options."); | 203 | "See man 5 sway and look for output options."); |
196 | return 1; | 204 | return 1; |
@@ -202,6 +210,9 @@ int main(int argc, const char **argv) { | |||
202 | if (args.mode == BACKGROUND_MODE_INVALID) { | 210 | if (args.mode == BACKGROUND_MODE_INVALID) { |
203 | return 1; | 211 | return 1; |
204 | } | 212 | } |
213 | |||
214 | args.fallback = argc == 5 ? argv[4] : NULL; | ||
215 | |||
205 | if (!prepare_context(&state)) { | 216 | if (!prepare_context(&state)) { |
206 | return 1; | 217 | return 1; |
207 | } | 218 | } |