+#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)
{
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 {
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),
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)
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)) {
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);
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;
}
}
{
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();
}
if (optind < argc)
usage();
+ wlr_log_init(WLR_ERROR, NULL);
rcxml_read(config_file);
/* Wayland requires XDG_RUNTIME_DIR to be set */
#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>
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)
{
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();
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
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);
}