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 "labwc.h"
 | 
				
			||||||
#include "common/spawn.h"
 | 
					#include "common/spawn.h"
 | 
				
			||||||
#include "common/log.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)
 | 
					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;
 | 
							return;
 | 
				
			||||||
	if (!strcasecmp(action, "Exit")) {
 | 
						if (!strcasecmp(action, "Exit")) {
 | 
				
			||||||
		wl_display_terminate(server->wl_display);
 | 
							wl_display_terminate(server->wl_display);
 | 
				
			||||||
 | 
						} else if (!strcasecmp(action, "Execute")) {
 | 
				
			||||||
 | 
							spawn_async_no_shell(command);
 | 
				
			||||||
	} else if (!strcasecmp(action, "NextWindow")) {
 | 
						} else if (!strcasecmp(action, "NextWindow")) {
 | 
				
			||||||
		server->cycle_view =
 | 
							server->cycle_view =
 | 
				
			||||||
			desktop_next_view(server, server->cycle_view);
 | 
								desktop_next_view(server, server->cycle_view);
 | 
				
			||||||
	} else if (!strcasecmp(action, "Execute")) {
 | 
						} else if (!strcasecmp(action, "Reconfigure")) {
 | 
				
			||||||
		spawn_async_no_shell(command);
 | 
							reconfigure();
 | 
				
			||||||
	} else if (!strcasecmp(action, "debug-views")) {
 | 
						} else if (!strcasecmp(action, "debug-views")) {
 | 
				
			||||||
		dbg_show_views(server);
 | 
							dbg_show_views(server);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,8 +122,6 @@ char *config_dir(void)
 | 
				
			||||||
char *theme_dir(const char *theme_name)
 | 
					char *theme_dir(const char *theme_name)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static char buf[4096] = { 0 };
 | 
						static char buf[4096] = { 0 };
 | 
				
			||||||
	if (buf[0] != '\0')
 | 
					 | 
				
			||||||
		return buf;
 | 
					 | 
				
			||||||
	struct ctx ctx = { .build_path_fn = build_theme_path,
 | 
						struct ctx ctx = { .build_path_fn = build_theme_path,
 | 
				
			||||||
			   .buf = buf,
 | 
								   .buf = buf,
 | 
				
			||||||
			   .len = sizeof(buf),
 | 
								   .len = sizeof(buf),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -214,9 +214,22 @@ void rcxml_parse_xml(struct buf *b)
 | 
				
			||||||
	xmlCleanupParser();
 | 
						xmlCleanupParser();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void pre_processing(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						rc.xdg_shell_server_side_deco = true;
 | 
				
			||||||
 | 
						rc.font_size_activewindow = 8;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void rcxml_init()
 | 
					static void rcxml_init()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						static bool has_run;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (has_run)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						has_run = true;
 | 
				
			||||||
	LIBXML_TEST_VERSION
 | 
						LIBXML_TEST_VERSION
 | 
				
			||||||
 | 
						wl_list_init(&rc.keybinds);
 | 
				
			||||||
 | 
						pre_processing();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void bind(const char *binding, const char *action, const char *command)
 | 
					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);
 | 
						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)
 | 
					static void post_processing(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (!wl_list_length(&rc.keybinds)) {
 | 
						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());
 | 
						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)
 | 
					void rcxml_read(const char *filename)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	FILE *stream;
 | 
						FILE *stream;
 | 
				
			||||||
	char *line = NULL;
 | 
						char *line = NULL;
 | 
				
			||||||
	size_t len = 0;
 | 
						size_t len = 0;
 | 
				
			||||||
	struct buf b;
 | 
						struct buf b;
 | 
				
			||||||
	char rcxml[4096] = { 0 };
 | 
						static char rcxml[4096] = { 0 };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rcxml_init();
 | 
						rcxml_init();
 | 
				
			||||||
	wl_list_init(&rc.keybinds);
 | 
					 | 
				
			||||||
	pre_processing();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Reading file into buffer before parsing makes it easier to write
 | 
						 * rcxml_read() can be called multiple times, but we only set rcxml[]
 | 
				
			||||||
	 * unit tests.
 | 
						 * the first time. The specified 'filename' is only respected the first
 | 
				
			||||||
 | 
						 * time.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (filename)
 | 
						if (rcxml[0] == '\0')
 | 
				
			||||||
		snprintf(rcxml, sizeof(rcxml), "%s", filename);
 | 
							find_config_file(rcxml, sizeof(rcxml), filename);
 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		rcxml_path(rcxml, sizeof(rcxml));
 | 
					 | 
				
			||||||
	if (rcxml[0] == '\0') {
 | 
						if (rcxml[0] == '\0') {
 | 
				
			||||||
		warn("cannot find rc.xml config file");
 | 
							warn("cannot find rc.xml config file");
 | 
				
			||||||
		goto no_config;
 | 
							goto no_config;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Reading file into buffer before parsing - better for unit tests */
 | 
				
			||||||
	stream = fopen(rcxml, "r");
 | 
						stream = fopen(rcxml, "r");
 | 
				
			||||||
	if (!stream) {
 | 
						if (!stream) {
 | 
				
			||||||
		warn("cannot read (%s)", rcxml);
 | 
							warn("cannot read (%s)", rcxml);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,8 @@ static bool handle_keybinding(struct server *server, uint32_t modifiers,
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		for (size_t i = 0; i < keybind->keysyms_len; i++) {
 | 
							for (size_t i = 0; i < keybind->keysyms_len; i++) {
 | 
				
			||||||
			if (sym == keybind->keysyms[i]) {
 | 
								if (sym == keybind->keysyms[i]) {
 | 
				
			||||||
				action(server, keybind->action, keybind->command);
 | 
									action(server, keybind->action,
 | 
				
			||||||
 | 
									       keybind->command);
 | 
				
			||||||
				return true;
 | 
									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 *startup_cmd = NULL;
 | 
				
			||||||
	char *config_file = NULL;
 | 
						char *config_file = NULL;
 | 
				
			||||||
	wlr_log_init(WLR_ERROR, NULL);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int c;
 | 
						int c;
 | 
				
			||||||
	while ((c = getopt(argc, argv, "s:c:h")) != -1) {
 | 
						while ((c = getopt(argc, argv, "c:s:h")) != -1) {
 | 
				
			||||||
		switch (c) {
 | 
							switch (c) {
 | 
				
			||||||
		case 's':
 | 
					 | 
				
			||||||
			startup_cmd = optarg;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case 'c':
 | 
							case 'c':
 | 
				
			||||||
			config_file = optarg;
 | 
								config_file = optarg;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case 's':
 | 
				
			||||||
 | 
								startup_cmd = optarg;
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case 'h':
 | 
				
			||||||
 | 
								/* fallthrough */
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			usage();
 | 
								usage();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -41,6 +42,7 @@ int main(int argc, char *argv[])
 | 
				
			||||||
	if (optind < argc)
 | 
						if (optind < argc)
 | 
				
			||||||
		usage();
 | 
							usage();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						wlr_log_init(WLR_ERROR, NULL);
 | 
				
			||||||
	rcxml_read(config_file);
 | 
						rcxml_read(config_file);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Wayland requires XDG_RUNTIME_DIR to be set */
 | 
						/* Wayland requires XDG_RUNTIME_DIR to be set */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										30
									
								
								src/server.c
									
										
									
									
									
								
							
							
						
						
									
										30
									
								
								src/server.c
									
										
									
									
									
								
							| 
						 | 
					@ -1,5 +1,8 @@
 | 
				
			||||||
#include "labwc.h"
 | 
					#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_export_dmabuf_v1.h>
 | 
				
			||||||
#include <wlr/types/wlr_screencopy_v1.h>
 | 
					#include <wlr/types/wlr_screencopy_v1.h>
 | 
				
			||||||
#include <wlr/types/wlr_data_control_v1.h>
 | 
					#include <wlr/types/wlr_data_control_v1.h>
 | 
				
			||||||
| 
						 | 
					@ -9,6 +12,7 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct wlr_backend *backend;
 | 
					static struct wlr_backend *backend;
 | 
				
			||||||
static struct wlr_compositor *compositor;
 | 
					static struct wlr_compositor *compositor;
 | 
				
			||||||
 | 
					static struct wl_event_source *sighup_source;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void server_new_input(struct wl_listener *listener, void *data)
 | 
					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);
 | 
						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)
 | 
					void server_init(struct server *server)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	server->wl_display = wl_display_create();
 | 
						server->wl_display = wl_display_create();
 | 
				
			||||||
| 
						 | 
					@ -80,6 +103,12 @@ void server_init(struct server *server)
 | 
				
			||||||
		exit(EXIT_FAILURE);
 | 
							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
 | 
						 * The backend is a wlroots feature which abstracts the underlying
 | 
				
			||||||
	 * input and output hardware. the autocreate option will choose the
 | 
						 * 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_output_layout_destroy(server->output_layout);
 | 
				
			||||||
	wlr_xwayland_destroy(server->xwayland);
 | 
						wlr_xwayland_destroy(server->xwayland);
 | 
				
			||||||
	wlr_xcursor_manager_destroy(server->cursor_mgr);
 | 
						wlr_xcursor_manager_destroy(server->cursor_mgr);
 | 
				
			||||||
 | 
						wl_event_source_remove(sighup_source);
 | 
				
			||||||
	wl_display_destroy_clients(server->wl_display);
 | 
						wl_display_destroy_clients(server->wl_display);
 | 
				
			||||||
	wl_display_destroy(server->wl_display);
 | 
						wl_display_destroy(server->wl_display);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue