Don't restart swaybg if the command hasn't changed

When outputs have changed but none of that has resulted in a change in
how swaybg should be run don't restart it. This avoids flickering the
background to grey as a result of bug #3693, and is generally good to
not churn through process termination and startup for a no-op.
This commit is contained in:
Pedro Côrte-Real 2020-09-02 20:25:04 +01:00
parent 139c4c5f74
commit df9265b29a
3 changed files with 58 additions and 21 deletions

View file

@ -476,6 +476,7 @@ struct sway_config {
// swaybg // swaybg
char *swaybg_command; char *swaybg_command;
char **swaybg_full_command;
struct wl_client *swaybg_client; struct wl_client *swaybg_client;
struct wl_listener swaybg_client_destroy; struct wl_listener swaybg_client_destroy;
@ -586,6 +587,7 @@ void config_add_swaynag_warning(char *fmt, ...);
/** /**
* Free config struct * Free config struct
*/ */
void free_swaybg_full_command(char** cmd);
void free_config(struct sway_config *config); void free_config(struct sway_config *config);
void free_sway_variable(struct sway_variable *var); void free_sway_variable(struct sway_variable *var);

View file

@ -85,6 +85,19 @@ static void free_mode(struct sway_mode *mode) {
free(mode); free(mode);
} }
void free_swaybg_full_command(char **cmd) {
if (!cmd) {
return;
}
char **pos = cmd;
while (*pos) {
free(*pos);
pos++;
}
free(cmd);
}
void free_config(struct sway_config *config) { void free_config(struct sway_config *config) {
if (!config) { if (!config) {
return; return;
@ -160,6 +173,7 @@ void free_config(struct sway_config *config) {
free(config->floating_scroll_right_cmd); free(config->floating_scroll_right_cmd);
free(config->font); free(config->font);
free(config->swaybg_command); free(config->swaybg_command);
free_swaybg_full_command(config->swaybg_full_command);
free(config->swaynag_command); free(config->swaynag_command);
free((char *)config->current_config_path); free((char *)config->current_config_path);
free((char *)config->current_config); free((char *)config->current_config);

View file

@ -578,7 +578,35 @@ static void handle_swaybg_client_destroy(struct wl_listener *listener,
sway_config->swaybg_client = NULL; sway_config->swaybg_client = NULL;
} }
static int compare_swaybg_cmd(char **cmd1, char **cmd2) {
while (true) {
if (*cmd1 == NULL && *cmd2 == NULL) {
return 0;
} else if (*cmd1 == NULL || *cmd2 == NULL) {
return 1;
} else if (strcmp(*cmd1, *cmd2) != 0) {
return 1;
} else {
cmd1++;
cmd2++;
}
}
}
static bool _spawn_swaybg(char **command) { static bool _spawn_swaybg(char **command) {
if (config->swaybg_full_command != NULL &&
compare_swaybg_cmd(command, config->swaybg_full_command) == 0) {
// We got the same command as before, ignore it
free_swaybg_full_command(command);
return true;
}
// Save the command for later comparisons
if (config->swaybg_full_command != NULL) {
free_swaybg_full_command(config->swaybg_full_command);
}
config->swaybg_full_command = command;
if (config->swaybg_client != NULL) { if (config->swaybg_client != NULL) {
wl_client_destroy(config->swaybg_client); wl_client_destroy(config->swaybg_client);
} }
@ -653,35 +681,34 @@ bool spawn_swaybg(void) {
} }
size_t i = 0; size_t i = 0;
cmd[i++] = config->swaybg_command; cmd[i++] = strdup(config->swaybg_command);
// Iterate all the outputs and write the command // Iterate all the outputs and write the command
list_t *output_configs = create_list();
struct sway_output *sway_output, *tmp; struct sway_output *sway_output, *tmp;
wl_list_for_each_safe(sway_output, tmp, &root->all_outputs, link) { wl_list_for_each_safe(sway_output, tmp, &root->all_outputs, link) {
struct output_config *oc = find_output_config(sway_output); struct output_config *oc = find_output_config(sway_output);
list_add(output_configs, oc);
if (!oc->background) { if (!oc->background) {
continue; continue;
} }
if (strcmp(oc->background_option, "solid_color") == 0) { if (strcmp(oc->background_option, "solid_color") == 0) {
cmd[i++] = "-o"; cmd[i++] = strdup("-o");
cmd[i++] = oc->name; cmd[i++] = strdup(oc->name);
cmd[i++] = "-c"; cmd[i++] = strdup("-c");
cmd[i++] = oc->background; cmd[i++] = strdup(oc->background);
} else { } else {
cmd[i++] = "-o"; cmd[i++] = strdup("-o");
cmd[i++] = oc->name; cmd[i++] = strdup(oc->name);
cmd[i++] = "-i"; cmd[i++] = strdup("-i");
cmd[i++] = oc->background; cmd[i++] = strdup(oc->background);
cmd[i++] = "-m"; cmd[i++] = strdup("-m");
cmd[i++] = oc->background_option; cmd[i++] = strdup(oc->background_option);
if (oc->background_fallback) { if (oc->background_fallback) {
cmd[i++] = "-c"; cmd[i++] = strdup("-c");
cmd[i++] = oc->background_fallback; cmd[i++] = strdup(oc->background_fallback);
} }
} }
assert(i < length); assert(i < length);
free_output_config(oc);
} }
for (size_t k = 0; k < i; k++) { for (size_t k = 0; k < i; k++) {
@ -690,11 +717,5 @@ bool spawn_swaybg(void) {
bool result = _spawn_swaybg(cmd); bool result = _spawn_swaybg(cmd);
free(cmd);
for (int k = 0; k < output_configs->length; k++) {
free_output_config(output_configs->items[k]);
}
list_free(output_configs);
return result; return result;
} }