From 0419a00e0b23ecc101b089d366a4fe33ccfb8dd8 Mon Sep 17 00:00:00 2001 From: DreamMaoMao <2523610504@qq.com> Date: Wed, 8 Oct 2025 13:39:31 +0800 Subject: [PATCH] feat: add setoption dispatch to allow change option by mmsg --- src/config/parse_config.h | 90 ++++++++++++++++++++++++++++++------- src/dispatch/bind_declare.h | 3 +- src/dispatch/bind_define.h | 6 +++ 3 files changed, 81 insertions(+), 18 deletions(-) diff --git a/src/config/parse_config.h b/src/config/parse_config.h index 0dc0388..4fe7ea0 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -358,21 +358,25 @@ void trim_whitespace(char *str) { } int parse_double_array(const char *input, double *output, int max_count) { - char *dup = strdup(input); // 复制一份用于修改 + char *dup = strdup(input); char *token; int count = 0; + // 先清空整个数组 + memset(output, 0, max_count * sizeof(double)); + token = strtok(dup, ","); while (token != NULL && count < max_count) { - trim_whitespace(token); // 对每一个分割后的 token 去除前后空格 + trim_whitespace(token); char *endptr; double val = strtod(token, &endptr); if (endptr == token || *endptr != '\0') { fprintf(stderr, "Error: Invalid number in array: %s\n", token); free(dup); - return -1; // 解析失败 + return -1; } - output[count++] = val; + output[count] = val; // 赋值到当前count位置 + count++; // 然后才自增 token = strtok(NULL, ","); } @@ -769,6 +773,50 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, func = focuslast; } else if (strcmp(func_name, "toggle_trackpad_enable") == 0) { func = toggle_trackpad_enable; + } else if (strcmp(func_name, "setoption") == 0) { + func = setoption; + + (*arg).v = strdup(arg_value); + + // 收集需要拼接的参数 + const char *non_empty_params[4] = {NULL}; + int param_index = 0; + + if (arg_value2 && arg_value2[0] != '\0') + non_empty_params[param_index++] = arg_value2; + if (arg_value3 && arg_value3[0] != '\0') + non_empty_params[param_index++] = arg_value3; + if (arg_value4 && arg_value4[0] != '\0') + non_empty_params[param_index++] = arg_value4; + if (arg_value5 && arg_value5[0] != '\0') + non_empty_params[param_index++] = arg_value5; + + // 处理拼接 + if (param_index == 0) { + (*arg).v2 = strdup(""); + } else { + // 计算总长度 + size_t len = 0; + for (int i = 0; i < param_index; i++) { + len += strlen(non_empty_params[i]); + } + len += (param_index - 1) + 1; // 逗号数 + null终止符 + + char *temp = malloc(len); + if (temp) { + char *cursor = temp; + for (int i = 0; i < param_index; i++) { + if (i > 0) { + *cursor++ = ','; + } + size_t param_len = strlen(non_empty_params[i]); + memcpy(cursor, non_empty_params[i], param_len); + cursor += param_len; + } + *cursor = '\0'; + (*arg).v2 = temp; + } + } } else if (strcmp(func_name, "setkeymode") == 0) { func = setkeymode; (*arg).v = strdup(arg_value); @@ -919,17 +967,7 @@ void run_exec_once() { } } -void parse_config_line(Config *config, const char *line) { - char key[256], value[256]; - if (sscanf(line, "%[^=]=%[^\n]", key, value) != 2) { - // fprintf(stderr, "Error: Invalid line format: %s\n", line); - return; - } - - // Then trim each part separately - trim_whitespace(key); - trim_whitespace(value); - +void parse_option(Config *config, char *key, char *value) { if (strcmp(key, "keymode") == 0) { snprintf(config->keymode, sizeof(config->keymode), "%.27s", value); } else if (strcmp(key, "animations") == 0) { @@ -2074,6 +2112,20 @@ void parse_config_line(Config *config, const char *line) { } } +void parse_config_line(Config *config, const char *line) { + char key[256], value[256]; + if (sscanf(line, "%[^=]=%[^\n]", key, value) != 2) { + // fprintf(stderr, "Error: Invalid line format: %s\n", line); + return; + } + + // Then trim each part separately + trim_whitespace(key); + trim_whitespace(value); + + parse_option(config, key, value); +} + void parse_config_file(Config *config, const char *file_path) { FILE *file; // 检查路径是否以 ~/ 开头 @@ -2970,8 +3022,7 @@ void reapply_tagrule(void) { } } -void reload_config(const Arg *arg) { - parse_config(); +void reset_option(void) { init_baked_points(); handlecursoractivity(); reset_keyboard_layout(); @@ -2989,3 +3040,8 @@ void reload_config(const Arg *arg) { arrange(selmon, false); } + +void reload_config(const Arg *arg) { + parse_config(); + reset_option(); +} diff --git a/src/dispatch/bind_declare.h b/src/dispatch/bind_declare.h index 2f553d2..48fae78 100644 --- a/src/dispatch/bind_declare.h +++ b/src/dispatch/bind_declare.h @@ -64,4 +64,5 @@ void toggle_render_border(const Arg *arg); void create_virtual_output(const Arg *arg); void destroy_all_virtual_output(const Arg *arg); void focuslast(const Arg *arg); -void toggle_trackpad_enable(const Arg *arg); \ No newline at end of file +void toggle_trackpad_enable(const Arg *arg); +void setoption(const Arg *arg); \ No newline at end of file diff --git a/src/dispatch/bind_define.h b/src/dispatch/bind_define.h index 3184975..85c6871 100644 --- a/src/dispatch/bind_define.h +++ b/src/dispatch/bind_define.h @@ -1353,3 +1353,9 @@ void zoom(const Arg *arg) { focusclient(sel, 1); arrange(selmon, false); } + +void setoption(const Arg *arg) { + parse_option(&config, arg->v, arg->v2); + override_config(); + reset_option(); +} \ No newline at end of file