mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	Reload config+theme on SIGHUP
This commit is contained in:
		
							parent
							
								
									745915c0ba
								
							
						
					
					
						commit
						1721b339da
					
				
					 6 changed files with 80 additions and 26 deletions
				
			
		
							
								
								
									
										14
									
								
								src/action.c
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								src/action.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,8 +1,14 @@
 | 
			
		|||
#include <strings.h>
 | 
			
		||||
 | 
			
		||||
#include "labwc.h"
 | 
			
		||||
#include "common/spawn.h"
 | 
			
		||||
#include "common/log.h"
 | 
			
		||||
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
static void reconfigure(void)
 | 
			
		||||
{
 | 
			
		||||
	char *const args[] = { "killall", "-SIGHUP", "labwc", NULL };
 | 
			
		||||
	execvp(args[0], args);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void action(struct server *server, const char *action, const char *command)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -10,11 +16,13 @@ void action(struct server *server, const char *action, const char *command)
 | 
			
		|||
		return;
 | 
			
		||||
	if (!strcasecmp(action, "Exit")) {
 | 
			
		||||
		wl_display_terminate(server->wl_display);
 | 
			
		||||
	} else if (!strcasecmp(action, "Execute")) {
 | 
			
		||||
		spawn_async_no_shell(command);
 | 
			
		||||
	} else if (!strcasecmp(action, "NextWindow")) {
 | 
			
		||||
		server->cycle_view =
 | 
			
		||||
			desktop_next_view(server, server->cycle_view);
 | 
			
		||||
	} else if (!strcasecmp(action, "Execute")) {
 | 
			
		||||
		spawn_async_no_shell(command);
 | 
			
		||||
	} else if (!strcasecmp(action, "Reconfigure")) {
 | 
			
		||||
		reconfigure();
 | 
			
		||||
	} else if (!strcasecmp(action, "debug-views")) {
 | 
			
		||||
		dbg_show_views(server);
 | 
			
		||||
	} else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -122,8 +122,6 @@ char *config_dir(void)
 | 
			
		|||
char *theme_dir(const char *theme_name)
 | 
			
		||||
{
 | 
			
		||||
	static char buf[4096] = { 0 };
 | 
			
		||||
	if (buf[0] != '\0')
 | 
			
		||||
		return buf;
 | 
			
		||||
	struct ctx ctx = { .build_path_fn = build_theme_path,
 | 
			
		||||
			   .buf = buf,
 | 
			
		||||
			   .len = sizeof(buf),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -214,9 +214,22 @@ void rcxml_parse_xml(struct buf *b)
 | 
			
		|||
	xmlCleanupParser();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pre_processing(void)
 | 
			
		||||
{
 | 
			
		||||
	rc.xdg_shell_server_side_deco = true;
 | 
			
		||||
	rc.font_size_activewindow = 8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void rcxml_init()
 | 
			
		||||
{
 | 
			
		||||
	static bool has_run;
 | 
			
		||||
 | 
			
		||||
	if (has_run)
 | 
			
		||||
		return;
 | 
			
		||||
	has_run = true;
 | 
			
		||||
	LIBXML_TEST_VERSION
 | 
			
		||||
	wl_list_init(&rc.keybinds);
 | 
			
		||||
	pre_processing();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void bind(const char *binding, const char *action, const char *command)
 | 
			
		||||
| 
						 | 
				
			
			@ -240,12 +253,6 @@ static void set_title_height(void)
 | 
			
		|||
	rc.title_height = font_height(buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void pre_processing(void)
 | 
			
		||||
{
 | 
			
		||||
	rc.xdg_shell_server_side_deco = true;
 | 
			
		||||
	rc.font_size_activewindow = 8;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void post_processing(void)
 | 
			
		||||
{
 | 
			
		||||
	if (!wl_list_length(&rc.keybinds)) {
 | 
			
		||||
| 
						 | 
				
			
			@ -271,30 +278,38 @@ static void rcxml_path(char *buf, size_t len)
 | 
			
		|||
	snprintf(buf, len, "%s/rc.xml", config_dir());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void find_config_file(char *buffer, size_t len, const char *filename)
 | 
			
		||||
{
 | 
			
		||||
	if (filename) {
 | 
			
		||||
		snprintf(buffer, len, "%s", filename);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	rcxml_path(buffer, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void rcxml_read(const char *filename)
 | 
			
		||||
{
 | 
			
		||||
	FILE *stream;
 | 
			
		||||
	char *line = NULL;
 | 
			
		||||
	size_t len = 0;
 | 
			
		||||
	struct buf b;
 | 
			
		||||
	char rcxml[4096] = { 0 };
 | 
			
		||||
	static char rcxml[4096] = { 0 };
 | 
			
		||||
 | 
			
		||||
	rcxml_init();
 | 
			
		||||
	wl_list_init(&rc.keybinds);
 | 
			
		||||
	pre_processing();
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Reading file into buffer before parsing makes it easier to write
 | 
			
		||||
	 * unit tests.
 | 
			
		||||
	 * rcxml_read() can be called multiple times, but we only set rcxml[]
 | 
			
		||||
	 * the first time. The specified 'filename' is only respected the first
 | 
			
		||||
	 * time.
 | 
			
		||||
	 */
 | 
			
		||||
	if (filename)
 | 
			
		||||
		snprintf(rcxml, sizeof(rcxml), "%s", filename);
 | 
			
		||||
	else
 | 
			
		||||
		rcxml_path(rcxml, sizeof(rcxml));
 | 
			
		||||
	if (rcxml[0] == '\0')
 | 
			
		||||
		find_config_file(rcxml, sizeof(rcxml), filename);
 | 
			
		||||
	if (rcxml[0] == '\0') {
 | 
			
		||||
		warn("cannot find rc.xml config file");
 | 
			
		||||
		goto no_config;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Reading file into buffer before parsing - better for unit tests */
 | 
			
		||||
	stream = fopen(rcxml, "r");
 | 
			
		||||
	if (!stream) {
 | 
			
		||||
		warn("cannot read (%s)", rcxml);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,8 @@ static bool handle_keybinding(struct server *server, uint32_t modifiers,
 | 
			
		|||
			continue;
 | 
			
		||||
		for (size_t i = 0; i < keybind->keysyms_len; i++) {
 | 
			
		||||
			if (sym == keybind->keysyms[i]) {
 | 
			
		||||
				action(server, keybind->action, keybind->command);
 | 
			
		||||
				action(server, keybind->action,
 | 
			
		||||
				       keybind->command);
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										12
									
								
								src/main.c
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								src/main.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -23,17 +23,18 @@ int main(int argc, char *argv[])
 | 
			
		|||
{
 | 
			
		||||
	char *startup_cmd = NULL;
 | 
			
		||||
	char *config_file = NULL;
 | 
			
		||||
	wlr_log_init(WLR_ERROR, NULL);
 | 
			
		||||
 | 
			
		||||
	int c;
 | 
			
		||||
	while ((c = getopt(argc, argv, "s:c:h")) != -1) {
 | 
			
		||||
	while ((c = getopt(argc, argv, "c:s:h")) != -1) {
 | 
			
		||||
		switch (c) {
 | 
			
		||||
		case 's':
 | 
			
		||||
			startup_cmd = optarg;
 | 
			
		||||
			break;
 | 
			
		||||
		case 'c':
 | 
			
		||||
			config_file = optarg;
 | 
			
		||||
			break;
 | 
			
		||||
		case 's':
 | 
			
		||||
			startup_cmd = optarg;
 | 
			
		||||
			break;
 | 
			
		||||
		case 'h':
 | 
			
		||||
			/* fallthrough */
 | 
			
		||||
		default:
 | 
			
		||||
			usage();
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +42,7 @@ int main(int argc, char *argv[])
 | 
			
		|||
	if (optind < argc)
 | 
			
		||||
		usage();
 | 
			
		||||
 | 
			
		||||
	wlr_log_init(WLR_ERROR, NULL);
 | 
			
		||||
	rcxml_read(config_file);
 | 
			
		||||
 | 
			
		||||
	/* Wayland requires XDG_RUNTIME_DIR to be set */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										30
									
								
								src/server.c
									
										
									
									
									
								
							
							
						
						
									
										30
									
								
								src/server.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -1,5 +1,8 @@
 | 
			
		|||
#include "labwc.h"
 | 
			
		||||
#include "theme/theme.h"
 | 
			
		||||
#include "config/rcxml.h"
 | 
			
		||||
 | 
			
		||||
#include <signal.h>
 | 
			
		||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
 | 
			
		||||
#include <wlr/types/wlr_screencopy_v1.h>
 | 
			
		||||
#include <wlr/types/wlr_data_control_v1.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -9,6 +12,7 @@
 | 
			
		|||
 | 
			
		||||
static struct wlr_backend *backend;
 | 
			
		||||
static struct wlr_compositor *compositor;
 | 
			
		||||
static struct wl_event_source *sighup_source;
 | 
			
		||||
 | 
			
		||||
static void server_new_input(struct wl_listener *listener, void *data)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -72,6 +76,25 @@ static void seat_request_set_selection(struct wl_listener *listener, void *data)
 | 
			
		|||
	wlr_seat_set_selection(server->seat, event->source, event->serial);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void reload_config_and_theme(void)
 | 
			
		||||
{
 | 
			
		||||
	rcxml_finish();
 | 
			
		||||
	/* TODO: use rc.config_path */
 | 
			
		||||
	rcxml_read(NULL);
 | 
			
		||||
	theme_read(rc.theme_name);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int handle_signal(int signal, void *data)
 | 
			
		||||
{
 | 
			
		||||
	switch (signal) {
 | 
			
		||||
	case SIGHUP:
 | 
			
		||||
		reload_config_and_theme();
 | 
			
		||||
		return 0;
 | 
			
		||||
	default:
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void server_init(struct server *server)
 | 
			
		||||
{
 | 
			
		||||
	server->wl_display = wl_display_create();
 | 
			
		||||
| 
						 | 
				
			
			@ -80,6 +103,12 @@ void server_init(struct server *server)
 | 
			
		|||
		exit(EXIT_FAILURE);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Catch SIGHUP */
 | 
			
		||||
	struct wl_event_loop *event_loop = NULL;
 | 
			
		||||
	event_loop = wl_display_get_event_loop(server->wl_display);
 | 
			
		||||
	sighup_source = wl_event_loop_add_signal(
 | 
			
		||||
		event_loop, SIGHUP, handle_signal, &server->wl_display);
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * The backend is a wlroots feature which abstracts the underlying
 | 
			
		||||
	 * input and output hardware. the autocreate option will choose the
 | 
			
		||||
| 
						 | 
				
			
			@ -312,6 +341,7 @@ void server_finish(struct server *server)
 | 
			
		|||
	wlr_output_layout_destroy(server->output_layout);
 | 
			
		||||
	wlr_xwayland_destroy(server->xwayland);
 | 
			
		||||
	wlr_xcursor_manager_destroy(server->cursor_mgr);
 | 
			
		||||
	wl_event_source_remove(sighup_source);
 | 
			
		||||
	wl_display_destroy_clients(server->wl_display);
 | 
			
		||||
	wl_display_destroy(server->wl_display);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue