diff --git a/src/config/parse_config.h b/src/config/parse_config.h index f7ce848..1a025e9 100644 --- a/src/config/parse_config.h +++ b/src/config/parse_config.h @@ -550,6 +550,48 @@ static bool starts_with_ignore_case(const char *str, const char *prefix) { return true; } +static char *combine_args_until_empty(char *values[], int count) { + // find the first empty string + int first_empty = count; + for (int i = 0; i < count; i++) { + // check if it's empty: empty string or only contains "0" (initialized) + if (values[i][0] == '\0' || + (strlen(values[i]) == 1 && values[i][0] == '0')) { + first_empty = i; + break; + } + } + + // if there are no valid parameters, return an empty string + if (first_empty == 0) { + return strdup(""); + } + + // calculate the total length + size_t total_len = 0; + for (int i = 0; i < first_empty; i++) { + total_len += strlen(values[i]); + } + // plus the number of commas (first_empty-1 commas) + total_len += (first_empty - 1); + + // allocate memory and concatenate + char *combined = malloc(total_len + 1); + if (combined == NULL) { + return strdup(""); + } + + combined[0] = '\0'; + for (int i = 0; i < first_empty; i++) { + if (i > 0) { + strcat(combined, ","); + } + strcat(combined, values[i]); + } + + return combined; +} + uint32_t parse_mod(const char *mod_str) { if (!mod_str || !*mod_str) { return UINT32_MAX; @@ -1005,10 +1047,14 @@ FuncType parse_func_name(char *func_name, Arg *arg, char *arg_value, (*arg).ui = atoi(arg_value); } else if (strcmp(func_name, "spawn") == 0) { func = spawn; - (*arg).v = strdup(arg_value); + char *values[] = {arg_value, arg_value2, arg_value3, arg_value4, + arg_value5}; + (*arg).v = combine_args_until_empty(values, 5); } else if (strcmp(func_name, "spawn_shell") == 0) { func = spawn_shell; - (*arg).v = strdup(arg_value); + char *values[] = {arg_value, arg_value2, arg_value3, arg_value4, + arg_value5}; + (*arg).v = combine_args_until_empty(values, 5); } else if (strcmp(func_name, "spawn_on_empty") == 0) { func = spawn_on_empty; (*arg).v = strdup(arg_value); // 注意:之后需要释放这个内存 @@ -1385,9 +1431,8 @@ bool parse_option(Config *config, char *key, char *value) { config->scroller_proportion_preset = (float *)malloc(float_count * sizeof(float)); if (!config->scroller_proportion_preset) { - fprintf( - stderr, - "\033[1m\033[31m[ERROR]:\033[33m Memory allocation failed\n"); + fprintf(stderr, "\033[1m\033[31m[ERROR]:\033[33m Memory " + "allocation failed\n"); return false; } @@ -1400,18 +1445,19 @@ bool parse_option(Config *config, char *key, char *value) { while (token != NULL && i < float_count) { if (sscanf(token, "%f", &value_set) != 1) { - fprintf( - stderr, - "\033[1m\033[31m[ERROR]:\033[33m Invalid float value in " - "scroller_proportion_preset: %s\n", - token); + fprintf(stderr, + "\033[1m\033[31m[ERROR]:\033[33m Invalid float " + "value in " + "scroller_proportion_preset: %s\n", + token); free(value_copy); free(config->scroller_proportion_preset); config->scroller_proportion_preset = NULL; return false; } - // Clamp the value between 0.0 and 1.0 (or your desired range) + // Clamp the value between 0.0 and 1.0 (or your desired + // range) config->scroller_proportion_preset[i] = CLAMP_FLOAT(value_set, 0.1f, 1.0f); @@ -1448,9 +1494,8 @@ bool parse_option(Config *config, char *key, char *value) { config->circle_layout = (char **)malloc(string_count * sizeof(char *)); memset(config->circle_layout, 0, string_count * sizeof(char *)); if (!config->circle_layout) { - fprintf( - stderr, - "\033[1m\033[31m[ERROR]:\033[33m Memory allocation failed\n"); + fprintf(stderr, "\033[1m\033[31m[ERROR]:\033[33m Memory " + "allocation failed\n"); return false; } @@ -1606,7 +1651,8 @@ bool parse_option(Config *config, char *key, char *value) { int64_t color = parse_color(value); if (color == -1) { fprintf(stderr, - "\033[1m\033[31m[ERROR]:\033[33m Invalid rootcolor format: " + "\033[1m\033[31m[ERROR]:\033[33m Invalid rootcolor " + "format: " "%s\n", value); return false; @@ -1650,11 +1696,11 @@ bool parse_option(Config *config, char *key, char *value) { } else if (strcmp(key, "maximizescreencolor") == 0) { int64_t color = parse_color(value); if (color == -1) { - fprintf( - stderr, - "\033[1m\033[31m[ERROR]:\033[33m Invalid maximizescreencolor " - "format: %s\n", - value); + fprintf(stderr, + "\033[1m\033[31m[ERROR]:\033[33m Invalid " + "maximizescreencolor " + "format: %s\n", + value); return false; } else { convert_hex_to_rgba(config->maximizescreencolor, color); @@ -1674,7 +1720,8 @@ bool parse_option(Config *config, char *key, char *value) { int64_t color = parse_color(value); if (color == -1) { fprintf(stderr, - "\033[1m\033[31m[ERROR]:\033[33m Invalid scratchpadcolor " + "\033[1m\033[31m[ERROR]:\033[33m Invalid " + "scratchpadcolor " "format: %s\n", value); return false; @@ -1760,11 +1807,11 @@ bool parse_option(Config *config, char *key, char *value) { } else if (strcmp(key, "vrr") == 0) { rule->vrr = CLAMP_INT(atoi(val), 0, 1); } else { - fprintf( - stderr, - "\033[1m\033[31m[ERROR]:\033[33m Unknown monitor rule " - "option:\033[1m\033[31m %s\n", - key); + fprintf(stderr, + "\033[1m\033[31m[ERROR]:\033[33m Unknown " + "monitor rule " + "option:\033[1m\033[31m %s\n", + key); parse_error = true; } } @@ -1824,7 +1871,8 @@ bool parse_option(Config *config, char *key, char *value) { rule->mfact = CLAMP_FLOAT(atof(val), 0.1f, 0.9f); } else { fprintf(stderr, - "\033[1m\033[31m[ERROR]:\033[33m Unknown tag rule " + "\033[1m\033[31m[ERROR]:\033[33m Unknown " + "tag rule " "option:\033[1m\033[31m %s\n", key); parse_error = true; @@ -1882,11 +1930,11 @@ bool parse_option(Config *config, char *key, char *value) { } else if (strcmp(key, "noshadow") == 0) { rule->noshadow = CLAMP_INT(atoi(val), 0, 1); } else { - fprintf( - stderr, - "\033[1m\033[31m[ERROR]:\033[33m Unknown layer rule " - "option:\033[1m\033[31m %s\n", - key); + fprintf(stderr, + "\033[1m\033[31m[ERROR]:\033[33m Unknown " + "layer rule " + "option:\033[1m\033[31m %s\n", + key); parse_error = true; } } @@ -2074,11 +2122,11 @@ bool parse_option(Config *config, char *key, char *value) { return false; } } else { - fprintf( - stderr, - "\033[1m\033[31m[ERROR]:\033[33m Unknown window rule " - "option:\033[1m\033[31m %s\n", - key); + fprintf(stderr, + "\033[1m\033[31m[ERROR]:\033[33m Unknown " + "window rule " + "option:\033[1m\033[31m %s\n", + key); parse_error = true; } } @@ -2178,7 +2226,8 @@ bool parse_option(Config *config, char *key, char *value) { arg_value3[256] = "0\0", arg_value4[256] = "0\0", arg_value5[256] = "0\0"; if (sscanf(value, - "%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[" + "%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^" + ",],%255[" "^,],%255[^\n]", mod_str, keysym_str, func_name, arg_value, arg_value2, arg_value3, arg_value4, arg_value5) < 3) { @@ -2235,11 +2284,11 @@ bool parse_option(Config *config, char *key, char *value) { binding->arg.v3 = NULL; } if (!binding->func) - fprintf( - stderr, - "\033[1m\033[31m[ERROR]:\033[33m Unknown dispatch in bind: " - "\033[1m\033[31m%s\n", - func_name); + fprintf(stderr, + "\033[1m\033[31m[ERROR]:\033[33m Unknown " + "dispatch in bind: " + "\033[1m\033[31m%s\n", + func_name); return false; } else { config->key_bindings_count++; @@ -2265,12 +2314,14 @@ bool parse_option(Config *config, char *key, char *value) { arg_value3[256] = "0\0", arg_value4[256] = "0\0", arg_value5[256] = "0\0"; if (sscanf(value, - "%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[" + "%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^" + ",],%255[" "^,],%255[^\n]", mod_str, button_str, func_name, arg_value, arg_value2, arg_value3, arg_value4, arg_value5) < 3) { fprintf(stderr, - "\033[1m\033[31m[ERROR]:\033[33m Invalid mousebind format: " + "\033[1m\033[31m[ERROR]:\033[33m Invalid mousebind " + "format: " "%s\n", value); return false; @@ -2308,7 +2359,8 @@ bool parse_option(Config *config, char *key, char *value) { } if (!binding->func) fprintf(stderr, - "\033[1m\033[31m[ERROR]:\033[33m Unknown dispatch in " + "\033[1m\033[31m[ERROR]:\033[33m Unknown " + "dispatch in " "mousebind: \033[1m\033[31m%s\n", func_name); return false; @@ -2335,14 +2387,15 @@ bool parse_option(Config *config, char *key, char *value) { arg_value3[256] = "0\0", arg_value4[256] = "0\0", arg_value5[256] = "0\0"; if (sscanf(value, - "%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[" + "%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^" + ",],%255[" "^,],%255[^\n]", mod_str, dir_str, func_name, arg_value, arg_value2, arg_value3, arg_value4, arg_value5) < 3) { - fprintf( - stderr, - "\033[1m\033[31m[ERROR]:\033[33m Invalid axisbind format: %s\n", - value); + fprintf(stderr, + "\033[1m\033[31m[ERROR]:\033[33m Invalid axisbind " + "format: %s\n", + value); return false; } @@ -2379,7 +2432,8 @@ bool parse_option(Config *config, char *key, char *value) { } if (!binding->func) fprintf(stderr, - "\033[1m\033[31m[ERROR]:\033[33m Unknown dispatch in " + "\033[1m\033[31m[ERROR]:\033[33m Unknown " + "dispatch in " "axisbind: \033[1m\033[31m%s\n", func_name); return false; @@ -2407,7 +2461,8 @@ bool parse_option(Config *config, char *key, char *value) { arg_value3[256] = "0\0", arg_value4[256] = "0\0", arg_value5[256] = "0\0"; if (sscanf(value, - "%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[" + "%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^" + ",],%255[" "^\n]", fold_str, func_name, arg_value, arg_value2, arg_value3, arg_value4, arg_value5) < 3) { @@ -2474,7 +2529,8 @@ bool parse_option(Config *config, char *key, char *value) { arg_value3[256] = "0\0", arg_value4[256] = "0\0", arg_value5[256] = "0\0"; if (sscanf(value, - "%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[" + "%255[^,],%255[^,],%255[^,],%255[^,],%255[^,],%255[^" + ",],%255[" "^,],%255[^,],%255[^\n]", mod_str, motion_str, fingers_count_str, func_name, arg_value, arg_value2, arg_value3, arg_value4, arg_value5) < 4) { @@ -2520,7 +2576,8 @@ bool parse_option(Config *config, char *key, char *value) { } if (!binding->func) fprintf(stderr, - "\033[1m\033[31m[ERROR]:\033[33m Unknown dispatch in " + "\033[1m\033[31m[ERROR]:\033[33m Unknown " + "dispatch in " "axisbind: \033[1m\033[31m%s\n", func_name); return false; @@ -3134,8 +3191,8 @@ void set_value_default() { config.hotarea_size = hotarea_size; // 热区大小,10x10 config.hotarea_corner = hotarea_corner; config.enable_hotarea = enable_hotarea; // 是否启用鼠标热区 - config.smartgaps = - smartgaps; /* 1 means no outer gap when there is only one window */ + config.smartgaps = smartgaps; /* 1 means no outer gap when there is + only one window */ config.sloppyfocus = sloppyfocus; /* focus follows mouse */ config.gappih = gappih; /* horiz inner gap between windows */ config.gappiv = gappiv; /* vert inner gap between windows */