]> git.mdlowis.com Git - proto/labwc.git/commitdiff
Reload config+theme on SIGHUP
authorJohan Malm <jgm323@gmail.com>
Fri, 25 Sep 2020 18:42:40 +0000 (19:42 +0100)
committerJohan Malm <jgm323@gmail.com>
Fri, 25 Sep 2020 18:42:40 +0000 (19:42 +0100)
src/action.c
src/common/dir.c
src/config/rcxml.c
src/keyboard.c
src/main.c
src/server.c

index 4ae7e7d21157728c11d798b6df8f4e19f26b44c0..4f933f741493fb90dbc7c1f9d6de886f1cf12b90 100644 (file)
@@ -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 {
index 75adb0722fa7b345c5156d60ee4156087a0d0ce8..6184ae1108324be5e97eb0156640b3a4101449fd 100644 (file)
@@ -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),
index 1c5f7da5e974b380b7048663645227511b36b2fa..ecee8edc314f680e170d8d120b306dc6dd2fc752 100644 (file)
@@ -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);
index ffd270af0f8e0d52873493361e32f39b0044b168..e7a0574826c22c4e9d46044ee32598fc1eca1d1a 100644 (file)
@@ -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;
                        }
                }
index b42f02c2e4eaa39185b9a1b935b96d3bbc1301b0..5a20204b948a1309029da7b22deeb4067acbaf5b 100644 (file)
@@ -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 */
index 11a7746e1987387f55f39615616eb012f0fcaa28..e65e189630997d49bbe06d5644c6afd1df40dc3d 100644 (file)
@@ -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);
 }