From b2bf05190c5429ce67b2108279f72fc111300e86 Mon Sep 17 00:00:00 2001 From: emersion Date: Wed, 11 Jul 2018 19:56:13 +0100 Subject: [PATCH] Invoke only one swaybg process --- include/sway/config.h | 4 +- include/sway/output.h | 2 - sway/commands/reload.c | 1 + sway/config/bar.c | 2 +- sway/config/bg.c | 92 ++++++++++++++++++++++++++++++++++++++++++ sway/config/output.c | 64 +---------------------------- sway/meson.build | 3 +- sway/server.c | 1 + 8 files changed, 101 insertions(+), 68 deletions(-) create mode 100644 sway/config/bg.c diff --git a/include/sway/config.h b/include/sway/config.h index d5e4116fa..b22d0c48d 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -474,11 +474,11 @@ void free_sway_binding(struct sway_binding *sb); struct sway_binding *sway_binding_dup(struct sway_binding *sb); -void load_swaybars(); +void load_swaybars(void); void invoke_swaybar(struct bar_config *bar); -void terminate_swaybg(pid_t pid); +void load_swaybg(void); struct bar_config *default_bar_config(void); diff --git a/include/sway/output.h b/include/sway/output.h index b6cda83c2..814e0f946 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -31,8 +31,6 @@ struct sway_output { struct wl_list link; - pid_t bg_pid; - struct { struct wl_signal destroy; } events; diff --git a/sway/commands/reload.c b/sway/commands/reload.c index c6715f9ca..20f95a936 100644 --- a/sway/commands/reload.c +++ b/sway/commands/reload.c @@ -11,6 +11,7 @@ struct cmd_results *cmd_reload(int argc, char **argv) { return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config."); } + load_swaybg(); load_swaybars(); arrange_and_commit(&root_container); return cmd_results_new(CMD_SUCCESS, NULL, NULL); diff --git a/sway/config/bar.c b/sway/config/bar.c index 3a74331e4..11abf7af9 100644 --- a/sway/config/bar.c +++ b/sway/config/bar.c @@ -225,7 +225,7 @@ static bool active_output(const char *name) { return false; } -void load_swaybars() { +void load_swaybars(void) { for (int i = 0; i < config->bars->length; ++i) { struct bar_config *bar = config->bars->items[i]; bool apply = false; diff --git a/sway/config/bg.c b/sway/config/bg.c new file mode 100644 index 000000000..a050e44d0 --- /dev/null +++ b/sway/config/bg.c @@ -0,0 +1,92 @@ +#define _POSIX_C_SOURCE 200809L +#define _XOPEN_SOURCE 700 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sway/config.h" +#include "stringop.h" +#include "list.h" +#include "log.h" + +static pid_t swaybg_pid = -1; + +static void terminate_swaybg(void) { + wlr_log(WLR_DEBUG, "Terminating swaybg %d", swaybg_pid); + int ret = kill(-swaybg_pid, SIGTERM); + if (ret != 0) { + wlr_log_errno(WLR_ERROR, "Unable to terminate swaybg %d", swaybg_pid); + } else { + waitpid(swaybg_pid, NULL, 0); + } + swaybg_pid = 0; +} + +void load_swaybg(void) { + if (swaybg_pid >= 0) { + terminate_swaybg(); + } + + swaybg_pid = fork(); + if (swaybg_pid < 0) { + wlr_log(WLR_ERROR, "Failed to fork()"); + return; + } else if (swaybg_pid == 0) { + setsid(); + + const char *cmd = config->swaybg_command ? + config->swaybg_command : "swaybg"; + + size_t argv_cap = 2 + 4 * config->output_configs->length; + size_t argv_len = 0; + char *argv[argv_cap]; + argv[argv_len++] = "swaybg"; + + for (int i = 0; i < config->output_configs->length; ++i) { + struct output_config *oc = config->output_configs->items[i]; + + if (oc->background_option) { + if (strcmp(oc->background_option, "solid_color") == 0) { + argv[argv_len++] = "--color"; + argv[argv_len++] = oc->background; + continue; + } + + argv[argv_len++] = "--scaling"; + argv[argv_len++] = oc->background_option; + } + + if (oc->background) { + char *arg; + if (strcmp(oc->name, "*") == 0) { + arg = oc->background; + } else { + arg = malloc(strlen(oc->name) + 1 + + strlen(oc->background) + 1); + strcpy(arg, oc->name); + strcat(arg, ":"); + strcat(arg, oc->background); + } + + argv[argv_len++] = "--image"; + argv[argv_len++] = arg; + } + } + + argv[argv_len++] = NULL; + assert(argv_len <= argv_cap); + + execvp(cmd, argv); + + wlr_log(WLR_ERROR, "Failed to exec swaybg"); + exit(EXIT_FAILURE); + } + + wlr_log(WLR_ERROR, "Spawned swaybg %d", swaybg_pid); +} diff --git a/sway/config/output.c b/sway/config/output.c index 205e2633c..7c741190a 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -2,8 +2,6 @@ #include #include #include -#include -#include #include #include #include @@ -113,16 +111,6 @@ static void set_mode(struct wlr_output *output, int width, int height, } } -void terminate_swaybg(pid_t pid) { - int ret = kill(pid, SIGTERM); - if (ret != 0) { - wlr_log(WLR_ERROR, "Unable to terminate swaybg [pid: %d]", pid); - } else { - int status; - waitpid(pid, &status, 0); - } -} - void apply_output_config(struct output_config *oc, struct sway_container *output) { assert(output->type == C_OUTPUT); @@ -132,10 +120,6 @@ void apply_output_config(struct output_config *oc, struct sway_container *output if (oc && oc->enabled == 0) { struct sway_output *sway_output = output->sway_output; - if (output->sway_output->bg_pid != 0) { - terminate_swaybg(output->sway_output->bg_pid); - output->sway_output->bg_pid = 0; - } container_destroy(output); sway_output->swayc = NULL; wlr_output_layout_remove(root_container.sway_root->output_layout, @@ -165,58 +149,14 @@ void apply_output_config(struct output_config *oc, struct sway_container *output wlr_output_layout_add_auto(output_layout, wlr_output); } - if (!oc || !oc->background) { - // Look for a * config for background - int i = list_seq_find(config->output_configs, output_name_cmp, "*"); - if (i >= 0) { - oc = config->output_configs->items[i]; - } else { - oc = NULL; - } - } - - int output_i; - for (output_i = 0; output_i < root_container.children->length; ++output_i) { - if (root_container.children->items[output_i] == output) { - break; - } - } - - if (oc && oc->background) { - if (output->sway_output->bg_pid != 0) { - terminate_swaybg(output->sway_output->bg_pid); - } - - wlr_log(WLR_DEBUG, "Setting background for output %d to %s", - output_i, oc->background); - - size_t len = snprintf(NULL, 0, "%s %d %s %s", - config->swaybg_command ? config->swaybg_command : "swaybg", - output_i, oc->background, oc->background_option); - char *command = malloc(len + 1); - if (!command) { - wlr_log(WLR_DEBUG, "Unable to allocate swaybg command"); - return; - } - snprintf(command, len + 1, "%s %d %s %s", - config->swaybg_command ? config->swaybg_command : "swaybg", - output_i, oc->background, oc->background_option); - wlr_log(WLR_DEBUG, "-> %s", command); - - char *const cmd[] = { "sh", "-c", command, NULL }; - output->sway_output->bg_pid = fork(); - if (output->sway_output->bg_pid == 0) { - execvp(cmd[0], cmd); - } - } if (oc && oc->dpms_state != DPMS_IGNORE) { switch (oc->dpms_state) { case DPMS_ON: - wlr_log(WLR_DEBUG, "Turning on screen"); + wlr_log(WLR_DEBUG, "Turning on output %s", oc->name); wlr_output_enable(wlr_output, true); break; case DPMS_OFF: - wlr_log(WLR_DEBUG, "Turning off screen"); + wlr_log(WLR_DEBUG, "Turning off output %s", oc->name); wlr_output_enable(wlr_output, false); break; case DPMS_IGNORE: diff --git a/sway/meson.build b/sway/meson.build index e492aeeed..57ee92b57 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -25,9 +25,10 @@ sway_sources = files( 'input/keyboard.c', 'config/bar.c', + 'config/bg.c', + 'config/input.c', 'config/output.c', 'config/seat.c', - 'config/input.c', 'commands/assign.c', 'commands/bar.c', diff --git a/sway/server.c b/sway/server.c index 1d8eb9640..e9f21035a 100644 --- a/sway/server.c +++ b/sway/server.c @@ -148,5 +148,6 @@ void server_run(struct sway_server *server) { wlr_backend_destroy(server->backend); return; } + load_swaybg(); wl_display_run(server->wl_display); }