gimp but for windows: a wayland compositor
git clone https://github.com/m-col/wimp
Files | Refs | Readme

Commit 58e796b69bf3f9205404d2cec9210a942c95f336
Parent: 778af7f2d707ed8aa2590a49809e637205c380f7
Author: mcol <mcol@posteo.net>
Date: 2021-01-23 00:06:56 +0000
Committer: mcol <mcol@posteo.net>
Committed: 2021-01-23 00:06:56 +0000

Load defaults using load_config(), set up config reloading action

src/types.h Modified

@@ -33,6 +33,7 @@
     struct wl_display *display;
     struct wlr_backend *backend;
     struct wlr_renderer *renderer;
+    char *config_file;
 
     struct wlr_output_layout *output_layout;
     struct wl_list outputs;

src/deskwm.c Modified

@@ -12,6 +12,7 @@
 
 #include "config.h"
 #include "cursor.h"
+#include "desk.h"
 #include "deskwm.h"
 #include "keyboard.h"
 #include "log.h"
@@ -33,16 +34,17 @@
 {
     int opt;
     int log_level = WLR_ERROR;
-    char *config = NULL;
+    struct server server;
+    server.config_file = NULL;
 
-    while ((opt = getopt(argc, argv, "hcdi")) != -1) {
+    while ((opt = getopt(argc, argv, "hc:di")) != -1) {
         switch (opt) {
 	    case 'h':
 		printf(usage);
 		return EXIT_SUCCESS;
 		break;
 	    case 'c':
-		config = strdup(optarg);
+		server.config_file = strdup(optarg);
 		break;
 	    case 'd':
 		log_level = WLR_DEBUG;
@@ -56,7 +58,6 @@
     init_log(log_level);
 
     // create
-    struct server server;
     server.display = wl_display_create();
     server.backend = wlr_backend_autocreate(server.display, NULL);
     server.renderer = wlr_backend_get_renderer(server.backend);
@@ -68,14 +69,27 @@
     wlr_data_device_manager_create(server.display);
     wlr_primary_selection_v1_device_manager_create(server.display);
 
+    // initialise
     wl_list_init(&server.desks);
+    wl_list_init(&server.key_bindings);
+    wl_list_init(&server.mouse_bindings);
+    wl_list_init(&server.marks);
+    server.mark_waiting = false;
+    server.on_mouse_motion = NULL;
+    server.on_mouse_scroll = NULL;
     server.can_steal_focus = true;
-
-    // read config
-    load_config(&server, config);
-    free(config);
+    server.mark_indicator.box.width = 25;
+    server.mark_indicator.box.height = 25;
+    server.mark_indicator.box.x = 0;
+    server.mark_indicator.box.y = 0;
+    server.desk_count = 0;
+    add_desk(&server);
+    server.current_desk = wl_container_of(server.desks.next, server.current_desk, link);
 
     // configure
+    load_defaults(&server);
+    locate_config(&server);
+    load_config(&server, NULL);
     set_up_outputs(&server);
     set_up_shell(&server);
     set_up_cursor(&server);

src/config.h Modified

@@ -4,6 +4,8 @@
 #include "types.h"
 
 void assign_colour(char *hex, float dest[4]);
-void load_config(struct server *server, char *config);
+void load_defaults(struct server *server);
+void load_config(struct server *server, FILE *stream);
+void locate_config(struct server *server);
 
 #endif

src/config.c Modified

@@ -14,6 +14,17 @@
 #define is_decimal(s) (strspn(s, "0123456789.") == strlen(s))
 
 
+static const char *DEFAULT_CONFIG =  "\n\
+zoom_min 0.5\n\
+zoom_max 3\n\
+mark_indicator #000000\n\
+vt_switching on\n\
+set_modifier Logo\n\
+bind Ctrl Escape shutdown\n\
+scroll_direction natural\n\
+";
+
+
 enum wlr_keyboard_modifier modifier_by_name(char *mod) {
     if (strcasecmp(mod, "shift") == 0)
 	return WLR_MODIFIER_SHIFT;
@@ -97,6 +108,8 @@
 	kb->data = calloc(1, sizeof(enum direction));
 	*(enum direction *)(kb->data) = direction_from_name(data);
     }
+    else if (strcasecmp(name, "reload_config") == 0)
+	kb->action = &reload_config;
 }
 
 
@@ -109,6 +122,14 @@
 }
 
 
+void free_binding(struct binding *kb) {
+    if (kb->data)
+	free(kb->data);
+    wl_list_remove(&kb->link);
+    free(kb);
+}
+
+
 void add_binding(struct server *server, char *data, int line) {
     struct binding *kb = calloc(1, sizeof(struct binding));
     enum wlr_keyboard_modifier mod;
@@ -149,18 +170,16 @@
 	return;
     }
 
-    struct binding *kb_existing;
+    struct binding *kb_existing, *tmp;
     struct wl_list *bindings;
     if (is_mouse_binding) {
 	bindings = &server->mouse_bindings;
     } else {
 	bindings = &server->key_bindings;
     }
-    wl_list_for_each(kb_existing, bindings, link) {
+    wl_list_for_each_safe(kb_existing, tmp, bindings, link) {
 	if (kb_existing->key == kb->key && kb_existing->mods == kb->mods) {
-	    wlr_log(WLR_ERROR, "Config line %i: binding exists for key combo.", line);
-	    free(kb);
-	    return;
+	    free_binding(kb_existing);
 	}
     }
     wl_list_insert(bindings->prev, &kb->link);
@@ -234,31 +253,6 @@
 }
 
 
-static void set_defaults(struct server *server) {
-    add_desk(server);
-    server->current_desk =
-	wl_container_of(server->desks.next, server->current_desk, link);
-
-    server->mod = WLR_MODIFIER_LOGO;
-    wl_list_init(&server->key_bindings);
-    wl_list_init(&server->mouse_bindings);
-    server->on_mouse_motion = NULL;
-    server->on_mouse_scroll = NULL;
-    server->zoom_min = 0.5;
-    server->zoom_max = 3;
-    server->reverse_scrolling = false;
-    server->vt_switching = true;
-
-    wl_list_init(&server->marks);
-    server->mark_waiting = false;
-    assign_colour("#000000", server->mark_indicator.colour);
-    server->mark_indicator.box.width = 25;
-    server->mark_indicator.box.height = 25;
-    server->mark_indicator.box.x = 0;
-    server->mark_indicator.box.y = 0;
-}
-
-
 static void setup_vt_switching(struct server *server) {
     if (!server->vt_switching)
 	return;
@@ -304,32 +298,29 @@
 }
 
 
-void load_config(struct server *server, char *config) {
-    set_defaults(server);
+void load_defaults(struct server *server) {
+    char *buffer = NULL;
+    size_t size = 0;
+    FILE *stream = open_memstream(&buffer, &size);
+    fprintf(stream, DEFAULT_CONFIG);
+    rewind(stream);
+    load_config(server, stream);
+    free(buffer);
+}
 
-    if (config == NULL) {
-	char *xdg_config_home = getenv("XDG_CONFIG_HOME");
-	if (xdg_config_home && *xdg_config_home) {
-	    config = "$XDG_CONFIG_HOME/.config/deskwm.conf";
-	} else {
-	    config = "$HOME/.config/deskwm.conf";
-	}
-    };
-    wordexp_t p;
-    wordexp(config, &p, WRDE_NOCMD | WRDE_UNDEF);
 
-    if (access(p.we_wordv[0], R_OK) == -1) {
-	wlr_log(WLR_ERROR, "%s not accessible. Using defaults.", p.we_wordv[0]);
-	wordfree(&p);
-	return;
+void load_config(struct server *server, FILE *stream) {
+    if (stream == NULL) {
+	if (server->config_file == NULL) {
+	    return;
+	}
+	stream = fopen(server->config_file, "r");
     }
-    FILE *fd = fopen(p.we_wordv[0], "r");
-    wordfree(&p);
-
     char *s;
     char linebuf[1024];
     int line = 0;
-    while (fgets(linebuf, sizeof(linebuf), fd)) {
+
+    while (fgets(linebuf, sizeof(linebuf), stream)) {
 	line++;
 	if (!(s = strtok(linebuf, " \t\n\r")) || s[0] == '#') {
 	    continue;
@@ -366,7 +357,34 @@
 		server->vt_switching = false;
 	}
     }
-    fclose(fd);
+    fclose(stream);
 
     setup_vt_switching(server);
 }
+
+
+void locate_config(struct server *server)
+{
+    char *config;
+    char *xdg_config;
+
+    if (server->config_file == NULL) {
+	xdg_config = getenv("XDG_CONFIG_HOME");
+	config = (xdg_config && *xdg_config) ?
+	    "$XDG_CONFIG_HOME/.config/deskwm.conf" : "$HOME/.config/deskwm.conf";
+	server->config_file = strdup(config);
+    };
+
+    wordexp_t p;
+    wordexp(server->config_file, &p, WRDE_NOCMD | WRDE_UNDEF);
+    free(server->config_file);
+
+    if (access(p.we_wordv[0], R_OK) == -1) {
+	wlr_log(WLR_ERROR, "%s not accessible. Using defaults.", p.we_wordv[0]);
+	server->config_file = NULL;
+    } else {
+	server->config_file = strdup(p.we_wordv[0]);
+    }
+
+    wordfree(&p);
+}

src/action.h Modified

@@ -20,5 +20,6 @@
 void actually_go_to_mark(struct server *server, const xkb_keysym_t sym);
 void toggle_fullscreen(struct server *server, void *data);
 void halfimize(struct server *server, void *data);
+void reload_config(struct server *server, void *data);
 
 #endif

src/action.c Modified

@@ -4,6 +4,7 @@
 #include <wlr/types/wlr_output_layout.h>
 
 #include "action.h"
+#include "config.h"
 #include "desk.h"
 #include "shell.h"
 #include "types.h"
@@ -290,3 +291,9 @@
     view->y = (y - view->surface->geometry.y) / zoom;
     wlr_xdg_toplevel_set_size(view->surface, width / zoom, height / zoom);
 }
+
+
+void reload_config(struct server *server, void *data) {
+    load_defaults(server);
+    load_config(server, NULL);
+}

readme.rst Modified

@@ -16,8 +16,6 @@
 To do list:
  - border decorations
  - make configuration much nicer and remove all the strcmps
- - read default configuration as string
-    - then add action to read config
  - fix issue where Shift-using key bindings require pre-shifted key in config
  - pan desk when focussing window in direction that isn't in view
  - xwayland

deskwm.conf Modified

@@ -35,6 +35,7 @@
 # Define key bindings
 # additional modifiers, key, action(, data)
 bind	Ctrl	Escape		shutdown
+bind	Ctrl	r		reload_config
 
 # These actions act on windows
 bind	Ctrl	q		close_current_window