mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Reload swaybar/swaybg on config reload.
This works by tracking the pids of the child processes in the related output container and terminating the processes and spawning new ones on a config reload. Should solve: #347
This commit is contained in:
		
							parent
							
								
									de219f6bec
								
							
						
					
					
						commit
						ede27eabc5
					
				
					 5 changed files with 125 additions and 44 deletions
				
			
		| 
						 | 
				
			
			@ -184,6 +184,8 @@ int sway_mouse_binding_cmp(const void *a, const void *b);
 | 
			
		|||
int sway_mouse_binding_cmp_buttons(const void *a, const void *b);
 | 
			
		||||
void free_sway_mouse_binding(struct sway_mouse_binding *smb);
 | 
			
		||||
 | 
			
		||||
void load_swaybars(swayc_t *output, int output_idx);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Allocate and initialize default bar configuration.
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
#ifndef _SWAY_CONTAINER_H
 | 
			
		||||
#define _SWAY_CONTAINER_H
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <wlc/wlc.h>
 | 
			
		||||
typedef struct sway_container swayc_t;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -81,6 +82,11 @@ struct sway_container {
 | 
			
		|||
	char *class;
 | 
			
		||||
	char *app_id;
 | 
			
		||||
 | 
			
		||||
	// Used by output containers to keep track of swaybar/swaybg child
 | 
			
		||||
	// processes.
 | 
			
		||||
	list_t *bar_pids;
 | 
			
		||||
	pid_t bg_pid;
 | 
			
		||||
 | 
			
		||||
	int gaps;
 | 
			
		||||
 | 
			
		||||
	list_t *children;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1094,6 +1094,15 @@ static struct cmd_results *cmd_reload(int argc, char **argv) {
 | 
			
		|||
	}
 | 
			
		||||
	if (!load_config(NULL)) return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config.");
 | 
			
		||||
 | 
			
		||||
	int i;
 | 
			
		||||
	swayc_t *cont = NULL;
 | 
			
		||||
	for (i = 0; i < root_container.children->length; ++i) {
 | 
			
		||||
		cont = root_container.children->items[i];
 | 
			
		||||
		if (cont->type == C_OUTPUT) {
 | 
			
		||||
			load_swaybars(cont, i);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	arrange_windows(&root_container, -1, -1);
 | 
			
		||||
	return cmd_results_new(CMD_SUCCESS, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										147
									
								
								sway/config.c
									
										
									
									
									
								
							
							
						
						
									
										147
									
								
								sway/config.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -3,6 +3,9 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <wordexp.h>
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
#include <sys/wait.h>
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include "wayland-desktop-shell-server-protocol.h"
 | 
			
		||||
#include "readline.h"
 | 
			
		||||
#include "stringop.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -360,6 +363,91 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
 | 
			
		|||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void invoke_swaybar(swayc_t *output, struct bar_config *bar, int output_i) {
 | 
			
		||||
	sway_log(L_DEBUG, "Invoking swaybar for output %s[%d] and bar %s", output->name, output_i, bar->id);
 | 
			
		||||
 | 
			
		||||
	size_t bufsize = 4;
 | 
			
		||||
	char output_id[bufsize];
 | 
			
		||||
	snprintf(output_id, bufsize, "%d", output_i);
 | 
			
		||||
	output_id[bufsize-1] = 0;
 | 
			
		||||
 | 
			
		||||
	char *const cmd[] = {
 | 
			
		||||
		"swaybar",
 | 
			
		||||
		"-b",
 | 
			
		||||
		bar->id,
 | 
			
		||||
		output_id,
 | 
			
		||||
		NULL,
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	pid_t *pid = malloc(sizeof(pid_t));
 | 
			
		||||
	*pid = fork();
 | 
			
		||||
	if (*pid == 0) {
 | 
			
		||||
		execvp(cmd[0], cmd);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// add swaybar pid to output
 | 
			
		||||
	list_add(output->bar_pids, pid);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void terminate_swaybars(list_t *pids) {
 | 
			
		||||
	int i, ret;
 | 
			
		||||
	pid_t *pid;
 | 
			
		||||
	for (i = 0; i < pids->length; ++i) {
 | 
			
		||||
		pid = pids->items[i];
 | 
			
		||||
		ret = kill(*pid, SIGTERM);
 | 
			
		||||
		if (ret != 0) {
 | 
			
		||||
			sway_log(L_ERROR, "Unable to terminate swaybar [pid: %d]", *pid);
 | 
			
		||||
		} else {
 | 
			
		||||
			int status;
 | 
			
		||||
			waitpid(*pid, &status, 0);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// empty pids list
 | 
			
		||||
	for (i = 0; i < pids->length; ++i) {
 | 
			
		||||
		pid = pids->items[i];
 | 
			
		||||
		list_del(pids, i);
 | 
			
		||||
		free(pid);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void load_swaybars(swayc_t *output, int output_idx) {
 | 
			
		||||
	// Check for bars
 | 
			
		||||
	list_t *bars = create_list();
 | 
			
		||||
	struct bar_config *bar = NULL;
 | 
			
		||||
	int i;
 | 
			
		||||
	for (i = 0; i < config->bars->length; ++i) {
 | 
			
		||||
		bar = config->bars->items[i];
 | 
			
		||||
		bool apply = false;
 | 
			
		||||
		if (bar->outputs) {
 | 
			
		||||
			int j;
 | 
			
		||||
			for (j = 0; j < bar->outputs->length; ++j) {
 | 
			
		||||
				char *o = bar->outputs->items[j];
 | 
			
		||||
				if (strcmp(o, "*") || strcasecmp(o, output->name)) {
 | 
			
		||||
					apply = true;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			apply = true;
 | 
			
		||||
		}
 | 
			
		||||
		if (apply) {
 | 
			
		||||
			list_add(bars, bar);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// terminate swaybar processes previously spawned for this
 | 
			
		||||
	// output.
 | 
			
		||||
	terminate_swaybars(output->bar_pids);
 | 
			
		||||
 | 
			
		||||
	for (i = 0; i < bars->length; ++i) {
 | 
			
		||||
		bar = bars->items[i];
 | 
			
		||||
		invoke_swaybar(output, bar, output_idx);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	list_free(bars);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void apply_output_config(struct output_config *oc, swayc_t *output) {
 | 
			
		||||
	if (oc && oc->width > 0 && oc->height > 0) {
 | 
			
		||||
		output->width = oc->width;
 | 
			
		||||
| 
						 | 
				
			
			@ -407,6 +495,16 @@ void apply_output_config(struct output_config *oc, swayc_t *output) {
 | 
			
		|||
 | 
			
		||||
	if (oc && oc->background) {
 | 
			
		||||
 | 
			
		||||
		if (output->bg_pid != 0) {
 | 
			
		||||
			int ret = kill(output->bg_pid, SIGTERM);
 | 
			
		||||
			if (ret != 0) {
 | 
			
		||||
				sway_log(L_ERROR, "Unable to terminate swaybg [pid: %d]", output->bg_pid);
 | 
			
		||||
			} else {
 | 
			
		||||
				int status;
 | 
			
		||||
				waitpid(output->bg_pid, &status, 0);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		sway_log(L_DEBUG, "Setting background for output %d to %s", output_i, oc->background);
 | 
			
		||||
 | 
			
		||||
		size_t bufsize = 4;
 | 
			
		||||
| 
						 | 
				
			
			@ -421,54 +519,15 @@ void apply_output_config(struct output_config *oc, swayc_t *output) {
 | 
			
		|||
			oc->background_option,
 | 
			
		||||
			NULL,
 | 
			
		||||
		};
 | 
			
		||||
		if (fork() == 0) {
 | 
			
		||||
 | 
			
		||||
		output->bg_pid = fork();
 | 
			
		||||
		if (output->bg_pid == 0) {
 | 
			
		||||
			execvp(cmd[0], cmd);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check for a bar
 | 
			
		||||
	struct bar_config *bar = NULL;
 | 
			
		||||
	int i;
 | 
			
		||||
	for (i = 0; i < config->bars->length; ++i) {
 | 
			
		||||
		bar = config->bars->items[i];
 | 
			
		||||
		bool apply = false;
 | 
			
		||||
		if (bar->outputs) {
 | 
			
		||||
			int j;
 | 
			
		||||
			for (j = 0; j < bar->outputs->length; ++j) {
 | 
			
		||||
				char *o = bar->outputs->items[j];
 | 
			
		||||
				if (strcmp(o, "*") || strcasecmp(o, output->name)) {
 | 
			
		||||
					apply = true;
 | 
			
		||||
					break;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			apply = true;
 | 
			
		||||
		}
 | 
			
		||||
		if (apply) {
 | 
			
		||||
			break;
 | 
			
		||||
		} else {
 | 
			
		||||
			bar = NULL;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if (bar) {
 | 
			
		||||
		sway_log(L_DEBUG, "Invoking swaybar for output %s[%d] and bar %s", output->name, i, bar->id);
 | 
			
		||||
 | 
			
		||||
		size_t bufsize = 4;
 | 
			
		||||
		char output_id[bufsize];
 | 
			
		||||
		snprintf(output_id, bufsize, "%d", output_i);
 | 
			
		||||
		output_id[bufsize-1] = 0;
 | 
			
		||||
 | 
			
		||||
		char *const cmd[] = {
 | 
			
		||||
			"swaybar",
 | 
			
		||||
			"-b",
 | 
			
		||||
			bar->id,
 | 
			
		||||
			output_id,
 | 
			
		||||
			NULL,
 | 
			
		||||
		};
 | 
			
		||||
		if (fork() == 0) {
 | 
			
		||||
			execvp(cmd[0], cmd);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	// load swaybars for output
 | 
			
		||||
	load_swaybars(output, output_i);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *do_var_replacement(char *str) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -60,6 +60,9 @@ static void free_swayc(swayc_t *cont) {
 | 
			
		|||
	if (cont->app_id) {
 | 
			
		||||
		free(cont->app_id);
 | 
			
		||||
	}
 | 
			
		||||
	if (cont->bar_pids) {
 | 
			
		||||
		free_flat_list(cont->bar_pids);
 | 
			
		||||
	}
 | 
			
		||||
	free(cont);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -109,6 +112,8 @@ swayc_t *new_output(wlc_handle handle) {
 | 
			
		|||
	output->width = size->w;
 | 
			
		||||
	output->height = size->h;
 | 
			
		||||
	output->unmanaged = create_list();
 | 
			
		||||
	output->bar_pids = create_list();
 | 
			
		||||
	output->bg_pid = 0;
 | 
			
		||||
 | 
			
		||||
	apply_output_config(oc, output);
 | 
			
		||||
	add_child(&root_container, output);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue