Commit a8d0f418fed1d9b87eec9260797c9218c1fc1d6b Parent: 633817107890cb3ad744e06cd3d687d7b5dc5e40 Author: mcol <mcol@posteo.net> Date: 2021-02-15 01:34:43 +0000 Committer: mcol <mcol@posteo.net> Committed: 2021-02-15 01:34:43 +0000 Convert config-reading logic into client-message parsing Configuration is now done via client interface `wimptool` over socket IPC. All mention of config files is and the example script has been converted. Currently all IPC messages go directly into configuration processing, but future work will also funnel message parsing into actions that require remote data (e.g. select viewport using slurp), and any subscriptions (e.g. programs that want to listen to state changes).
wimp.conf Modified
@@ -1,3 +1,5 @@ +#!/usr/bin/env bash +# # # ██ ██ ██ ████████ ██████ # ██ ██ ██ ██ ██ ██ ██ ██ @@ -7,106 +9,106 @@ # ██ ██ # ██ # -# All possible options are described here. Lines that start with '#' are -# ignored. Options that are commented out contain their default values. +# Example startup script. +# +# All possible options are described here. +# Options that are commented out contain their default values. +# The executable 'wimptool' configures wimp by sending messages to it. # -# Config is read from the first found of: -# -c command line argument -# $XDG_CONFIG_HOME/.config/wimp/config -# $HOME/.config/wimp/config - -# This will be executed after setting up the compositor. -#auto_start ${XDG_CONFIG_HOME:-$HOME}/.config/wimp/autostart - -#desks 2 -#desk 1 background #31475c -#desk 1 borders normal #3e3e73 -#desk 1 corners normal #31315c -#desk 1 borders focus #47315c -#desk 1 corners focus #7e5992 -#desk 1 borders width 6 -#desk 2 background #3e3e73 -#desk 2 borders normal #31475c -#desk 1 corners normal #3e5973 -#desk 2 borders focus #47315c -#desk 1 corners focus #7e5992 -#desk 2 borders width 6 -desk 1 background ~/path/to/tiling-image.png +# The first to be found of these paths is run as a startup script: +# $XDG_CONFIG_HOME/.config/wimp/startup +# $HOME/.config/wimp/startup +# + +#wimptool desks 2 +#wimptool desk 1 background #31475c +#wimptool desk 1 borders normal #3e3e73 +#wimptool desk 1 corners normal #31315c +#wimptool desk 1 borders focus #47315c +#wimptool desk 1 corners focus #7e5992 +#wimptool desk 1 borders width 6 +#wimptool desk 2 background #3e3e73 +#wimptool desk 2 borders normal #31475c +#wimptool desk 1 corners normal #3e5973 +#wimptool desk 2 borders focus #47315c +#wimptool desk 1 corners focus #7e5992 +#wimptool desk 2 borders width 6 +wimptool desk 1 background ~/path/to/tiling-image.png # Magnification bounds -#zoom_min 0.2 -#zoom_max 5 +#wimptool zoom_min 0.2 +#wimptool zoom_max 5 # Set the colour for the mark setter/getter indicator -#mark_indicator #000000 +#wimptool mark_indicator #000000 # Whether to allow VT switching: on or off. -#vt_switching on +#wimptool vt_switching on # natural or reverse scrolling -#scroll_direction natural +#wimptool scroll_direction natural # Focus when moving the pointer over a window -#auto_focus on +#wimptool auto_focus on ## Key bindings # Can be one of: Shift, Caps, Ctrl, Alt, Mod2, Mod3, Logo, Mod5 -#set_modifier Logo +#wimptool set_modifier Logo # additional modifiers, key, action -bind Ctrl Escape shutdown -bind Ctrl r reload_config +wimptool bind Ctrl Escape shutdown +wimptool bind Ctrl r reload_config # These actions act on windows -bind Ctrl q close_window -bind j focus down -bind k focus up -bind h focus left -bind l focus right -bind f toggle_fullscreen -bind Shift m maximize -bind Shift 1 send_to_desk 1 -bind Shift 2 send_to_desk 2 +wimptool bind Ctrl q close_window +wimptool bind j focus down +wimptool bind k focus up +wimptool bind h focus left +wimptool bind l focus right +wimptool bind f toggle_fullscreen +wimptool bind Shift m maximize +wimptool bind Shift 1 send_to_desk 1 +wimptool bind Shift 2 send_to_desk 2 # These give the focussed window half of the screen -bind Shift j halfimize down -bind Shift k halfimize up -bind Shift h halfimize left -bind Shift l halfimize right +wimptool bind Shift j halfimize down +wimptool bind Shift k halfimize up +wimptool bind Shift h halfimize left +wimptool bind Shift l halfimize right # And these act on desks -bind Tab next_desk -bind ISO_Left_Tab prev_desk -bind i zoom 15 -bind o zoom -15 -bind r reset_zoom +wimptool bind Tab next_desk +wimptool bind ISO_Left_Tab prev_desk +wimptool bind i zoom 15 +wimptool bind o zoom -15 +wimptool bind r reset_zoom # These pan the desk using the given percentage changes in x and y -bind s pan_desk 0 40 -bind w pan_desk 0 -40 -bind a pan_desk -40 0 -bind d pan_desk 40 0 +wimptool bind s pan_desk 0 40 +wimptool bind w pan_desk 0 -40 +wimptool bind a pan_desk -40 0 +wimptool bind d pan_desk 40 0 # The line after 'exec' is executed by /bin/sh -bind Return exec gnome-terminal +wimptool bind Return exec gnome-terminal # We can execute windows as scratchpads with a fixed geometry like this, where # the geometry is specified as <width>x<height>+<x>+<y> -bind Ctrl e scratchpad 1000x800+20+20 footclient mutt +wimptool bind Ctrl e scratchpad 1000x800+20+20 footclient mutt # A percentage of the used output can also be requested: -bind Ctrl t scratchpad 50%+50%+0+0 footclient tmux +wimptool bind Ctrl t scratchpad 50%+50%+0+0 footclient tmux # These two actions can be used to mark and go to set positions. Each one, once # pressed, waits for the next key press and uses that as the 'mark', e.g. # hitting 'mod + m' then 'a' will save the current position, then hitting 'mod # + `' then 'a' later will move to that marked position. These can be cancelled # with the escape key. -bind m set_mark -bind grave go_to_mark +wimptool bind m set_mark +wimptool bind grave go_to_mark # Possible mouse bindings: motion, scroll, pinch, drag{1,2,3} (+ additional modifiers) -bind scroll pan_desk -bind pinch zoom -bind Shift scroll zoom -bind drag1 move_window +wimptool bind scroll pan_desk +wimptool bind pinch zoom +wimptool bind Shift scroll zoom +wimptool bind drag1 move_window
src/wimptool.c Modified
@@ -41,6 +41,7 @@ char buffer[BUFSIZ] = {0}; for (int i = 1; i < argc; i++) { strcat(buffer, argv[i]); + strcat(buffer, " "); } if (send(sock, buffer, strlen(buffer), 0) == -1) {
src/types.h Modified
@@ -40,10 +40,6 @@ struct wlr_backend *backend; struct wlr_renderer *renderer; - char *config_directory; - char *config_file; - char *auto_start; - struct wlr_output_layout *output_layout; struct wl_listener output_layout_change_listener; struct wl_list outputs; @@ -111,7 +107,6 @@ struct wlr_box grab_geobox; uint32_t resize_edges; double zoom_min, zoom_max; - bool vt_switching; bool auto_focus; struct wl_list scratchpads;
src/main.c Modified
@@ -37,6 +37,9 @@ .mark_indicator.box.y = 0, .scratchpad_waiting = false, .auto_focus = true, + .reverse_scrolling = false, + .zoom_min = 0.2, + .zoom_max = 5, }; @@ -50,8 +53,6 @@ static void shutdown() { - free(wimp.config_directory); - free(wimp.config_file); wl_list_remove(&wimp.new_output_listener.link); wl_list_remove(&wimp.new_xdg_surface_listener.link); wl_list_remove(&wimp.decoration_listener.link); @@ -120,7 +121,6 @@ { int opt; int log_level = WLR_ERROR; - wimp.config_file = NULL; while ((opt = getopt(argc, argv, "hc:di")) != -1) { switch (opt) { @@ -128,9 +128,6 @@ printf(usage); return EXIT_SUCCESS; break; - case 'c': - wimp.config_file = strdup(optarg); - break; case 'd': log_level = WLR_DEBUG; break; @@ -163,14 +160,13 @@ wl_list_init(&wimp.scratchpads); // configure - locate_config(); - load_config(); set_up_inputs(); set_up_outputs(); set_up_shell(); set_up_cursor(); set_up_decorations(); set_up_layer_shell(); + set_up_defaults(); // start if (!start_ipc(socket) || !wlr_backend_start(wimp.backend)) { @@ -178,7 +174,7 @@ return EXIT_FAILURE; } setenv("WAYLAND_DISPLAY", socket, true); - schedule_auto_start(); + schedule_startup(); centre_cursor(); wlr_log(WLR_INFO, "Starting with WAYLAND_DISPLAY=%s.", socket); wl_display_run(wimp.display);
src/ipc.c Modified
@@ -27,7 +27,7 @@ ssize_t len = recv(fd, buffer, sizeof(buffer) - 1, 0); if (len > 0) { buffer[len] = '\0'; - parse_message(buffer, len); + parse_message(buffer); } close(fd); }
src/config.h Modified
@@ -4,9 +4,8 @@ #include "types.h" void assign_colour(char *hex, float dest[4]); -void schedule_auto_start(); -void parse_message(char *buffer, ssize_t len); -void load_config(); -void locate_config(); +void parse_message(char *buffer); +void schedule_startup(); +void set_up_defaults(); #endif
src/config.c Modified
@@ -16,33 +16,8 @@ #define is_number(s) (strspn(s, "0123456789.-") == strlen(s)) #define is_number_perc(s) (strspn(s, "0123456789.-%") == strlen(s)) -#define CONFIG_HOME "$HOME/.config/wimp/" -#define CONFIG_HOME_XDG "$XDG_CONFIG_HOME/wimp/" - - -static const char *DEFAULT_CONFIG = "\n\ -desks 2\n\ -desk 2 background #3e3e73\n\ -desk 2 borders normal #31475c\n\ -desk 2 corners normal #3e5973\n\ -zoom_min 0.2\n\ -zoom_max 5\n\ -mark_indicator #47315c\n\ -vt_switching on\n\ -scroll_direction natural\n\ -set_modifier Logo\n\ -bind Ctrl Escape shutdown\n\ -"; - - -static char *expand(char *path) { - wordexp_t p; - wordexp(path, &p, WRDE_NOCMD | WRDE_UNDEF); - free(path); - char *new = strdup(p.we_wordv[0]); - wordfree(&p); - return new; -} +#define CONFIG_HOME "$HOME/.config/wimp/startup" +#define CONFIG_HOME_XDG "$XDG_CONFIG_HOME/wimp/startup" struct value_map { @@ -94,16 +69,16 @@ } -static bool dir_handler(struct binding *kb, char *data, int line) { +static bool dir_handler(struct binding *kb, char *data) { kb->data = calloc(1, sizeof(enum direction)); - *(enum direction *)(kb->data) = get(dirs, data); + *(enum direction *)(kb->data) = get(dirs, strtok(data, " \t\n\r")); return true; } -static bool str_handler(struct binding *kb, char *data, int line) { +static bool str_handler(struct binding *kb, char *data) { if (!data) { - wlr_log(WLR_ERROR, "Config line %i: requires arguments.", line); + wlr_log(WLR_ERROR, "Command requires arguments."); return false; } if (is_number(data)) { @@ -117,7 +92,7 @@ } -static bool motion_handler(struct binding *kb, char *data, int line) { +static bool motion_handler(struct binding *kb, char *data) { char *s; if (!data) { goto err; @@ -145,7 +120,7 @@ return true; err: - wlr_log(WLR_ERROR, "Config line %i malformed/incomplete.", line); + wlr_log(WLR_ERROR, "Command malformed/incomplete."); return false; } @@ -207,7 +182,7 @@ static int scratchpad_id = 0; -static bool scratchpad_handler(struct binding *kb, char *data, int line) { +static bool scratchpad_handler(struct binding *kb, char *data) { char *geo, *command; struct wlr_box box; if (!data) { @@ -237,7 +212,7 @@ return true; err: - wlr_log(WLR_ERROR, "Config line %i malformed/incomplete.", line); + wlr_log(WLR_ERROR, "Command malformed/incomplete."); return false; } @@ -245,7 +220,7 @@ static struct { const char *name; const action action; - bool (*data_handler)(struct binding *kb, char *data, int line); + bool (*data_handler)(struct binding *kb, char *data); } action_map[] = { { "shutdown", &shutdown, NULL }, { "exec", &exec_command, &str_handler }, @@ -262,7 +237,6 @@ { "toggle_fullscreen", &toggle_fullscreen, NULL }, { "halfimize", &halfimize, &dir_handler }, { "maximize", &maximize, NULL }, - { "reload_config", &reload_config, NULL }, { "send_to_desk", &send_to_desk, &str_handler }, { "scratchpad", &toggle_scratchpad, &scratchpad_handler }, }; @@ -286,7 +260,7 @@ }; -static bool assign_action(const char *name, char *data, struct binding *kb, int line) { +static bool assign_action(const char *name, char *data, struct binding *kb) { kb->action = NULL; kb->data = NULL; size_t i; @@ -314,7 +288,7 @@ if (strcmp(action_map[i].name, name) == 0) { kb->action = action_map[i].action; if (action_map[i].data_handler != NULL) { - if (!action_map[i].data_handler(kb, data, line)){ + if (!action_map[i].data_handler(kb, data)){ return false; } } @@ -335,7 +309,7 @@ } -static void add_binding(char *data, const int line) { +static void add_binding(char *data) { struct binding *kb = calloc(1, sizeof(struct binding)); enum wlr_keyboard_modifier mod; char *s = strtok(data, " \t\n\r"); @@ -360,7 +334,7 @@ if (kb->key == XKB_KEY_NoSymbol) { kb->key = get(mouse_keys, s); if (kb->key == 0) { - wlr_log(WLR_ERROR, "Config line %i: No such key '%s'.", line, s); + wlr_log(WLR_ERROR, "No such key '%s'.", s); free(kb); return; } @@ -370,10 +344,10 @@ // action s = strtok(NULL, " \t\n\r"); if (!s) { - wlr_log(WLR_ERROR, "Config line %i: malformed option.", line); + wlr_log(WLR_ERROR, "Command malformed/incompleted."); return; } - if (!assign_action(s, strtok(NULL, "\n\r"), kb, line)) { + if (!assign_action(s, strtok(NULL, "\n\r"), kb)) { free(kb); return; } @@ -436,6 +410,7 @@ wallpaper->height, cairo_image_surface_get_data(canvas) ); desk->wallpaper = wallpaper; + damage_all_outputs(); cairo_destroy(cr); cairo_surface_destroy(image); cairo_surface_destroy(canvas); @@ -457,11 +432,12 @@ } -static void setup_vt_switching() { - if (!wimp.vt_switching) { - return; - } +static void disable_vt_switching() { + // TODO +} + +static void setup_vt_switching() { uint32_t func_keys[] = { XKB_KEY_F1, XKB_KEY_F2, @@ -484,253 +460,202 @@ } -struct source { - struct wl_event_source *wl_event_source; -}; - - -static int _auto_start(void *data) { - struct source *source = data; - wl_event_source_remove(source->wl_event_source); - free(source); - - char *script = wimp.auto_start; - if (fork() == 0) { - if (execl(script, script, (void *)NULL) == -1) { - exit(EXIT_FAILURE); - } - } else { - wlr_log(WLR_DEBUG, "Running autostart script: %s", script); - } - free(wimp.auto_start); - return 0; -} - - -void schedule_auto_start() { - if (wimp.auto_start) { - wimp.auto_start = expand(wimp.auto_start); - } else { - wimp.auto_start = strndup( - wimp.config_directory, strlen(wimp.config_directory) + strlen("autostart") - ); - strcat(wimp.auto_start, "autostart"); +void parse_message(char *message) { + char *s; + if (!(s = strtok(message, " \t\n\r"))) { + return; } - if (is_executable(wimp.auto_start)) { - struct wl_event_loop *event_loop = wl_display_get_event_loop(wimp.display); - struct source *source = calloc(1, sizeof(struct source)); - source->wl_event_source = wl_event_loop_add_timer(event_loop, _auto_start, source); - wl_event_source_timer_update(source->wl_event_source, 1); + // desks <int> + if (!strcasecmp(s, "desks")) { + if ((s = strtok(NULL, " \t\n\r")) && is_number(s)) { + configure_desks(strtod(s, NULL)); + } } -} - - -void parse_message(char *buffer, ssize_t len) { - printf("msg: %s\n", buffer); -} + // desk ... + else if (!strcasecmp(s, "desk")) { + if ((s = strtok(NULL, " \t\n\r")) && is_number(s)) { + int index = strtod(s, NULL) - 1; + s = strtok(NULL, " \t\n\r"); + struct desk *desk; + bool found = false; + wl_list_for_each(desk, &wimp.desks, link) { + if (desk->index == index) { + found = true; + break; + } + } + if (!found) { + return; + } -static void parse_config(FILE *stream) { - char *s; - char linebuf[1024]; - int line = 0; - int index; - - while (fgets(linebuf, sizeof(linebuf), stream)) { - line++; - if (!(s = strtok(linebuf, " \t\n\r")) || s[0] == '#') { - continue; - } - - // desks <int> - if (!strcasecmp(s, "desks")) { - if ((s = strtok(NULL, " \t\n\r")) && is_number(s)) { - configure_desks(strtod(s, NULL)); + // desk <index> background #rrggbb + // desk <index> background ~/path/to/image.png + if (!strcasecmp(s, "background")) { + if ((s = strtok(NULL, " \t\n\r"))) { + set_wallpaper(desk, s); + } } - } - // desk ... - else if (!strcasecmp(s, "desk")) { - if ((s = strtok(NULL, " \t\n\r")) && is_number(s)) { - index = strtod(s, NULL) - 1; + // desk <index> borders [focus|normal] <#rrggbb> + // desk <index> borders width <int> + else if (!strcasecmp(s, "borders")) { s = strtok(NULL, " \t\n\r"); - struct desk *desk; - bool found = false; - wl_list_for_each(desk, &wimp.desks, link) { - if (desk->index == index) { - found = true; - break; - } + if (!strcasecmp(s, "normal")) { + assign_colour(strtok(NULL, " \t\n\r"), desk->border_normal); } - if (!found) { - continue; + else if (!strcasecmp(s, "focus")) { + assign_colour(strtok(NULL, " \t\n\r"), desk->border_focus); } - - // desk <index> background #rrggbb - // desk <index> background ~/path/to/image.png - if (!strcasecmp(s, "background")) { - if ((s = strtok(NULL, " \t\n\r"))) { - set_wallpaper(desk, s); + else if (!strcasecmp(s, "width")) { + if ((s = strtok(NULL, " \t\n\r")) && is_number(s)) { + desk->border_width = strtod(s, NULL); } } + } - // desk <index> borders [focus|normal] <#rrggbb> - // desk <index> borders width <int> - else if (!strcasecmp(s, "borders")) { - s = strtok(NULL, " \t\n\r"); - if (!strcasecmp(s, "normal")) { - assign_colour(strtok(NULL, " \t\n\r"), desk->border_normal); - } - else if (!strcasecmp(s, "focus")) { - assign_colour(strtok(NULL, " \t\n\r"), desk->border_focus); - } - else if (!strcasecmp(s, "width")) { - if ((s = strtok(NULL, " \t\n\r")) && is_number(s)) { - desk->border_width = strtod(s, NULL); - } - } + // desk <index> corners [focus|normal] <#rrggbb> + else if (!strcasecmp(s, "corners")) { + s = strtok(NULL, " \t\n\r"); + if (!strcasecmp(s, "normal")) { + assign_colour(strtok(NULL, " \t\n\r"), desk->corner_normal); } - - // desk <index> corners [focus|normal] <#rrggbb> - else if (!strcasecmp(s, "corners")) { - s = strtok(NULL, " \t\n\r"); - if (!strcasecmp(s, "normal")) { - assign_colour(strtok(NULL, " \t\n\r"), desk->corner_normal); - } - else if (!strcasecmp(s, "focus")) { - assign_colour(strtok(NULL, " \t\n\r"), desk->corner_focus); - } + else if (!strcasecmp(s, "focus")) { + assign_colour(strtok(NULL, " \t\n\r"), desk->corner_focus); } } } + } - // zoom_min <float> - else if (!strcasecmp(s, "zoom_min")) { - if ((s = strtok(NULL, " \t\n\r")) && is_number(s)) { - wimp.zoom_min = strtod(s, NULL); - } - } - - // zoom_max <float> - else if (!strcasecmp(s, "zoom_max")) { - if ((s = strtok(NULL, " \t\n\r")) && is_number(s)) { - wimp.zoom_max = strtod(s, NULL); - } - } - - // mark_indicator #rrggbb - else if (!strcasecmp(s, "mark_indicator")) { - assign_colour(strtok(NULL, " \t\n\r"), wimp.mark_indicator.colour); - wimp.mark_indicator.box.x = 0; - wimp.mark_indicator.box.y = 0; + // zoom_min <float> + else if (!strcasecmp(s, "zoom_min")) { + if ((s = strtok(NULL, " \t\n\r")) && is_number(s)) { + wimp.zoom_min = strtod(s, NULL); } + } - // vt_switching [off|on] - else if (!strcasecmp(s, "vt_switching")) { - s = strtok(NULL, " \t\n\r"); - if (!strcasecmp(s, "off")) - wimp.vt_switching = false; - else if (!strcasecmp(s, "on")) - wimp.vt_switching = true; + // zoom_max <float> + else if (!strcasecmp(s, "zoom_max")) { + if ((s = strtok(NULL, " \t\n\r")) && is_number(s)) { + wimp.zoom_max = strtod(s, NULL); } + } - // scroll_direciton [natural|reverse] - else if (!strcasecmp(s, "scroll_direction")) { - s = strtok(NULL, " \t\n\r"); - if (!strcasecmp(s, "natural")) - wimp.reverse_scrolling = false; - else if (!strcasecmp(s, "reverse")) - wimp.reverse_scrolling = true; - } + // mark_indicator #rrggbb + else if (!strcasecmp(s, "mark_indicator")) { + assign_colour(strtok(NULL, " \t\n\r"), wimp.mark_indicator.colour); + wimp.mark_indicator.box.x = 0; + wimp.mark_indicator.box.y = 0; + } - // e.g.: set_modifier logo - else if (!strcasecmp(s, "set_modifier")) { - if ((s = strtok(NULL, " \t\n\r"))) { - enum wlr_keyboard_modifier mod = get(mods, s); - if (mod) - wimp.mod = mod; - else - wlr_log(WLR_ERROR, "Config line %i: invalid modifier name '%s'.", line, s); - } - } + // vt_switching [off|on] + else if (!strcasecmp(s, "vt_switching")) { + s = strtok(NULL, " \t\n\r"); + if (!strcasecmp(s, "off")) + disable_vt_switching(); + else if (!strcasecmp(s, "on")) + setup_vt_switching(); + } - // bind [<modifiers>] <key> <action> - else if (!strcasecmp(s, "bind")) { - add_binding(strtok(NULL, ""), line); + // scroll_direciton [natural|reverse] + else if (!strcasecmp(s, "scroll_direction")) { + s = strtok(NULL, " \t\n\r"); + if (!strcasecmp(s, "natural")) + wimp.reverse_scrolling = false; + else if (!strcasecmp(s, "reverse")) + wimp.reverse_scrolling = true; + } + + // e.g.: set_modifier logo + else if (!strcasecmp(s, "set_modifier")) { + if ((s = strtok(NULL, " \t\n\r"))) { + enum wlr_keyboard_modifier mod = get(mods, s); + if (mod) + wimp.mod = mod; + else + wlr_log(WLR_ERROR, "Invalid modifier name '%s'.", s); } + } - // auto_start ~/script/to/execute.sh - else if (!strcasecmp(s, "auto_start")) { - wimp.auto_start = strdup(strtok(NULL, " \t\n\r")); - } + // bind [<modifiers>] <key> <action> + else if (!strcasecmp(s, "bind")) { + add_binding(strtok(NULL, "")); + } - // auto_focus [on|off] - else if (!strcasecmp(s, "auto_focus")) { - s = strtok(NULL, " \t\n\r"); - if (!strcasecmp(s, "off")) { - wimp.auto_focus = false; - } else if (!strcasecmp(s, "on")) { - wimp.auto_focus = true; - } + // auto_focus [on|off] + else if (!strcasecmp(s, "auto_focus")) { + s = strtok(NULL, " \t\n\r"); + if (!strcasecmp(s, "off")) { + wimp.auto_focus = false; + } else if (!strcasecmp(s, "on")) { + wimp.auto_focus = true; } + } - // other non-empty, non-commented lines - else { - wlr_log(WLR_ERROR, "Config line %i: unknown option '%s'.", line, s); - } + // other non-empty, non-commented lines + else { + wlr_log(WLR_ERROR, "Unknown command '%s'.", s); } } -void load_config() { - FILE *stream; - - // remove existing keybindings - struct binding *kb, *tmp; - wl_list_for_each_safe(kb, tmp, &wimp.mouse_bindings, link) { - free_binding(kb); - } - wl_list_for_each_safe(kb, tmp, &wimp.key_bindings, link) { - free_binding(kb); - } - - drop_scratchpads(); +struct startup_data { + struct wl_event_source *wl_event_source; + char *script; +}; - // load defaults - char *buffer = NULL; - size_t size = 0; - stream = open_memstream(&buffer, &size); - fprintf(stream, DEFAULT_CONFIG); - rewind(stream); - parse_config(stream); - free(buffer); - fclose(stream); - // load configuration file - if (is_readable(wimp.config_file)) { - stream = fopen(wimp.config_file, "r"); - parse_config(stream); - fclose(stream); +static int _startup(void *vdata) { + struct startup_data *data = vdata; + wl_event_source_remove(data->wl_event_source); + if (fork() == 0) { + if (execl(data->script, data->script, (void *)NULL) == -1) { + exit(EXIT_FAILURE); + } } else { - wlr_log(WLR_ERROR, "%s not accessible. Using defaults.", wimp.config_file); + wlr_log(WLR_DEBUG, "Running startup script: %s", data->script); } - - setup_vt_switching(); + free(data->script); + free(data); + return 0; } -void locate_config() { +void schedule_startup() { char *xdg_config = getenv("XDG_CONFIG_HOME"); char *config_dir = (xdg_config && *xdg_config) ? CONFIG_HOME_XDG : CONFIG_HOME; - wimp.config_directory = strdup(config_dir); - wimp.config_directory = expand(wimp.config_directory); - config_dir = wimp.config_directory; + struct startup_data *data = calloc(1, sizeof(struct startup_data)); + wordexp_t p; + wordexp(config_dir, &p, WRDE_NOCMD | WRDE_UNDEF); + data->script = strdup(p.we_wordv[0]); + wordfree(&p); - if (wimp.config_file == NULL) { - wimp.config_file = strndup(config_dir, strlen(config_dir) + strlen("config")); - strcat(wimp.config_file, "config"); + if (is_executable(data->script)) { + struct wl_event_loop *event_loop = wl_display_get_event_loop(wimp.display); + data->wl_event_source = wl_event_loop_add_timer(event_loop, _startup, data); + wl_event_source_timer_update(data->wl_event_source, 1); } else { - wimp.config_file = expand(wimp.config_file); + wlr_log(WLR_ERROR, "Cannot run startup script: %s", data->script); + free(data->script); + free(data); + } + +} + + +void set_up_defaults(){ + char defaults[][64] = { + "desks 2", + "desk 2 background #3e3e73", + "desk 2 borders normal #31475c", + "desk 2 corners normal #3e5973", + "mark_indicator #47315c", + "set_modifier Logo", + "bind Ctrl Escape shutdown", }; + for (size_t i = 0; i < sizeof(defaults) / sizeof(defaults[0]); i++) { + parse_message(defaults[i]); + } + setup_vt_switching(); }
src/action.h Modified
@@ -24,7 +24,6 @@ void toggle_fullscreen(void *data); void halfimize(void *data); void maximize(void *data); -void reload_config(void *data); void send_to_desk(void *data); void toggle_scratchpad(void *data);
src/action.c Modified
@@ -414,12 +414,6 @@ } -void reload_config(void *data) { - load_config(); - damage_all_outputs(); // in case wallpaper has changed -} - - void send_to_desk(void *data) { struct view *view = wl_container_of(wimp.current_desk->views.next, view, link); int index = *(double*)data - 1;