diff --git a/src/config/parse_config.h b/src/config/parse_config.h index e424b62..1de39fe 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -191,6 +191,12 @@ typedef struct { GestureBinding *gesture_bindings; int gesture_bindings_count; + char **exec; + int exec_count; + + char **exec_once; + int exec_once_count; + } Config; typedef void (*FuncType)(const Arg *); @@ -552,6 +558,24 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, char *arg_v return func; } +void run_exec() { + Arg arg; + + for(int i = 0; i < config.exec_count; i++) { + arg.v = config.exec[i]; + spawn(&arg); + } +} + +void run_exec_once() { + Arg arg; + + for(int i = 0; i < config.exec_once_count; i++) { + arg.v = config.exec_once[i]; + spawn(&arg); + } +} + void parse_config_line(Config *config, const char *line) { char key[256], value[256]; if (sscanf(line, "%[^=]=%[^\n]", key, value) != 2) { @@ -1010,6 +1034,39 @@ void parse_config_line(Config *config, const char *line) { } setenv(env_type, env_value, 1); + } else if (strncmp(key, "exec", 9) == 0) { + char **new_exec = realloc(config->exec, (config->exec_count + 1) * sizeof(char *)); + if (!new_exec) { + fprintf(stderr, "Error: Failed to allocate memory for exec\n"); + return; + } + config->exec = new_exec; + + config->exec[config->exec_count] = strdup(value); + if (!config->exec[config->exec_count]) { + fprintf(stderr, "Error: Failed to duplicate exec string\n"); + return; + } + + config->exec_count++; + + } else if (strncmp(key, "exec-once", 9) == 0) { + + char **new_exec_once = realloc(config->exec_once, (config->exec_once_count + 1) * sizeof(char *)); + if (!new_exec_once) { + fprintf(stderr, "Error: Failed to allocate memory for exec_once\n"); + return; + } + config->exec_once = new_exec_once; + + config->exec_once[config->exec_once_count] = strdup(value); + if (!config->exec_once[config->exec_once_count]) { + fprintf(stderr, "Error: Failed to duplicate exec_once string\n"); + return; + } + + config->exec_once_count++; + } else if (strncmp(key, "bind", 4) == 0) { config->key_bindings = realloc(config->key_bindings, @@ -1227,6 +1284,16 @@ void free_config(void) { } free(config.gesture_bindings); + for(i = 0; i < config.exec_count; i++) { + free(config.exec[i]); + } + free(config.exec); + + for(i = 0; i < config.exec_once_count; i++) { + free(config.exec_once[i]); + } + free(config.exec_once); + free(config.scroller_proportion_preset); config.scroller_proportion_preset = NULL; config.scroller_proportion_preset_count = 0; @@ -1491,6 +1558,7 @@ void reload_config(const Arg *arg) { free_config(); parse_config(); init_baked_points(); + run_exec(); wl_list_for_each(c, &clients, link) { if (c && !c->iskilling) { if (c->bw) { diff --git a/src/maomao.c b/src/maomao.c index 2dab1ac..915ed16 100644 --- a/src/maomao.c +++ b/src/maomao.c @@ -5064,10 +5064,14 @@ run(char *startup_cmd) { wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y); wlr_cursor_set_xcursor(cursor, cursor_mgr, "left_ptr"); + run_exec(); + run_exec_once(); + /* Run the Wayland event loop. This does not return until you exit the * compositor. Starting the backend rigged up all of the necessary event * loop configuration to listen to libinput events, DRM events, generate * frame events at the refresh rate, and so on. */ + wl_display_run(dpy); } @@ -5476,7 +5480,6 @@ void handle_foreign_destroy(struct wl_listener *listener, void *data) { void setup(void) { // signal(SIGSEGV, signalhandler); - parse_config(); init_baked_points();