diff options
-rw-r--r-- | completions/tofi | 2 | ||||
-rw-r--r-- | doc/config | 10 | ||||
-rw-r--r-- | doc/tofi.1.md | 11 | ||||
-rw-r--r-- | doc/tofi.1.scd | 9 | ||||
-rw-r--r-- | doc/tofi.5.md | 17 | ||||
-rw-r--r-- | doc/tofi.5.scd | 15 | ||||
-rw-r--r-- | src/config.c | 97 | ||||
-rw-r--r-- | src/config.h | 3 | ||||
-rw-r--r-- | src/entry.h | 4 | ||||
-rw-r--r-- | src/main.c | 46 | ||||
-rw-r--r-- | src/tofi.h | 6 |
11 files changed, 150 insertions, 70 deletions
diff --git a/completions/tofi b/completions/tofi index 218d8fc..048aafc 100644 --- a/completions/tofi +++ b/completions/tofi @@ -54,8 +54,6 @@ _tofi() ;; --help|-h) ;; - --late-keyboard-init) - ;; --*) return 0 ;; @@ -95,6 +95,10 @@ # ### Window positioning # + # The name of the output to appear on. An empty string will use the + # default output chosen by the compositor. + output = "" + # Location on screen to anchor the window to. # # Supported values: top-left, top, top-right, right, bottom-right, @@ -120,3 +124,9 @@ # If true, directly launch applications on selection when in drun mode. # Otherwise, just print the command line to stdout. drun-launch = false + + # Delay keyboard initialisation until after the first draw to screen. + # This option is experimental, and will cause tofi to miss keypresses + # for a short time after launch. The only reason to use this option is + # performance on slow systems. + late-keyboard-init = false diff --git a/doc/tofi.1.md b/doc/tofi.1.md index b3dee5c..8d3c960 100644 --- a/doc/tofi.1.md +++ b/doc/tofi.1.md @@ -42,17 +42,6 @@ a future version of tofi. > Specify path to custom config file. -**--output** \<name\> - -> Select the output to appear on. - -**--late-keyboard-init** - -> Delay keyboard initialisation until after the first draw to screen. -> This option is experimental, and will cause tofi to miss keypresses -> for a short time after launch. The only reason to use this option is -> performance on slow systems. - All config file options described in **tofi**(5) are also accepted, in the form **--key=value**. diff --git a/doc/tofi.1.scd b/doc/tofi.1.scd index f85e18d..8b6618d 100644 --- a/doc/tofi.1.scd +++ b/doc/tofi.1.scd @@ -39,15 +39,6 @@ nothing, and may be removed in a future version of tofi. *-c, --config* <path> Specify path to custom config file. -*--output* <name> - Select the output to appear on. - -*--late-keyboard-init* - Delay keyboard initialisation until after the first draw to screen. - This option is experimental, and will cause tofi to miss keypresses - for a short time after launch. The only reason to use this option is - performance on slow systems. - All config file options described in *tofi*(5) are also accepted, in the form *--key=value*. diff --git a/doc/tofi.5.md b/doc/tofi.5.md index c425b1b..23f4cb2 100644 --- a/doc/tofi.5.md +++ b/doc/tofi.5.md @@ -154,6 +154,14 @@ options. > > Default: center +**output**=*name* + +> The name of the output to appear on, if multiple outputs are present. +> If empty, the compositor will choose which output to display the +> window on (usually the currently focused output). +> +> Default: "" + **margin-top**=*px\|%* > Offset from top of screen. See **PERCENTAGE VALUES** for more @@ -256,6 +264,15 @@ options. > > Default: true +**late-keyboard-init**=*true\|false* + +> Delay keyboard initialisation until after the first draw to screen. +> This option is experimental, and will cause tofi to miss keypresses +> for a short time after launch. The only reason to use this option is +> performance on slow systems. +> +> Default: false + # COLORS Colors can be specified in the form *RGB*, *RGBA*, *RRGGBB* or diff --git a/doc/tofi.5.scd b/doc/tofi.5.scd index 9841b1f..c36f98c 100644 --- a/doc/tofi.5.scd +++ b/doc/tofi.5.scd @@ -135,6 +135,13 @@ options. Default: center +*output*=_name_ + The name of the output to appear on, if multiple outputs are present. + If empty, the compositor will choose which output to display the window + on (usually the currently focused output). + + Default: "" + *margin-top*=_px|%_ Offset from top of screen. See *PERCENTAGE VALUES* for more information. Only has an effect when anchored to the top of the screen. @@ -222,6 +229,14 @@ options. Default: true +*late-keyboard-init*=_true|false_ + Delay keyboard initialisation until after the first draw to screen. + This option is experimental, and will cause tofi to miss keypresses + for a short time after launch. The only reason to use this option is + performance on slow systems. + + Default: false + # COLORS Colors can be specified in the form _RGB_, _RGBA_, _RRGGBB_ or _RRGGBBAA_, diff --git a/src/config.c b/src/config.c index 47f964d..7ee29e8 100644 --- a/src/config.c +++ b/src/config.c @@ -17,6 +17,11 @@ /* Anyone with a 10M config file is doing something very wrong */ #define MAX_CONFIG_SIZE (10*1024*1024) +struct uint32_percent { + uint32_t value; + bool percent; +}; + static char *strip(const char *str); static bool parse_option(struct tofi *tofi, const char *filename, size_t lineno, const char *option, const char *value); static char *get_config_path(void); @@ -26,7 +31,7 @@ static bool parse_bool(const char *filename, size_t lineno, const char *str, boo static struct color parse_color(const char *filename, size_t lineno, const char *str, bool *err); static uint32_t parse_uint32(const char *filename, size_t lineno, const char *str, bool *err); static int32_t parse_int32(const char *filename, size_t lineno, const char *str, bool *err); -static uint32_t parse_uint32_percent(const char *filename, size_t lineno, const char *str, bool *err, uint32_t max); +static struct uint32_percent parse_uint32_percent(const char *filename, size_t lineno, const char *str, bool *err); /* * Function-like macro. Yuck. @@ -231,6 +236,7 @@ char *strip(const char *str) bool parse_option(struct tofi *tofi, const char *filename, size_t lineno, const char *option, const char *value) { bool err = false; + struct uint32_percent percent; if (strcasecmp(option, "anchor") == 0) { tofi->anchor = parse_anchor(filename, lineno, value, &err); } else if (strcasecmp(option, "background-color") == 0) { @@ -270,25 +276,45 @@ bool parse_option(struct tofi *tofi, const char *filename, size_t lineno, const } else if (strcasecmp(option, "selection-background") == 0) { tofi->window.entry.selection_background_color = parse_color(filename, lineno, value, &err); } else if (strcasecmp(option, "width") == 0) { - tofi->window.width = parse_uint32_percent(filename, lineno, value, &err, tofi->output_width); + percent = parse_uint32_percent(filename, lineno, value, &err); + tofi->window.width = percent.value; + tofi->window.width_is_percent = percent.percent; } else if (strcasecmp(option, "height") == 0) { - tofi->window.height = parse_uint32_percent(filename, lineno, value, &err, tofi->output_height); + percent = parse_uint32_percent(filename, lineno, value, &err); + tofi->window.height = percent.value; + tofi->window.height_is_percent = percent.percent; } else if (strcasecmp(option, "margin-top") == 0) { - tofi->window.margin_top = parse_uint32_percent(filename, lineno, value, &err, tofi->output_height); + percent = parse_uint32_percent(filename, lineno, value, &err); + tofi->window.margin_top = percent.value; + tofi->window.margin_top_is_percent = percent.percent; } else if (strcasecmp(option, "margin-bottom") == 0) { - tofi->window.margin_bottom = parse_uint32_percent(filename, lineno, value, &err, tofi->output_height); + percent = parse_uint32_percent(filename, lineno, value, &err); + tofi->window.margin_bottom = percent.value; + tofi->window.margin_bottom_is_percent = percent.percent; } else if (strcasecmp(option, "margin-left") == 0) { - tofi->window.margin_left = parse_uint32_percent(filename, lineno, value, &err, tofi->output_width); + percent = parse_uint32_percent(filename, lineno, value, &err); + tofi->window.margin_left = percent.value; + tofi->window.margin_left_is_percent = percent.percent; } else if (strcasecmp(option, "margin-right") == 0) { - tofi->window.margin_right = parse_uint32_percent(filename, lineno, value, &err, tofi->output_width); + percent = parse_uint32_percent(filename, lineno, value, &err); + tofi->window.margin_right = percent.value; + tofi->window.margin_right_is_percent = percent.percent; } else if (strcasecmp(option, "padding-top") == 0) { - tofi->window.entry.padding_top = parse_uint32_percent(filename, lineno, value, &err, tofi->output_height); + percent = parse_uint32_percent(filename, lineno, value, &err); + tofi->window.entry.padding_top = percent.value; + tofi->window.entry.padding_top_is_percent = percent.percent; } else if (strcasecmp(option, "padding-bottom") == 0) { - tofi->window.entry.padding_bottom = parse_uint32_percent(filename, lineno, value, &err, tofi->output_height); + percent = parse_uint32_percent(filename, lineno, value, &err); + tofi->window.entry.padding_bottom = percent.value; + tofi->window.entry.padding_bottom_is_percent = percent.percent; } else if (strcasecmp(option, "padding-left") == 0) { - tofi->window.entry.padding_left = parse_uint32_percent(filename, lineno, value, &err, tofi->output_width); + percent = parse_uint32_percent(filename, lineno, value, &err); + tofi->window.entry.padding_left = percent.value; + tofi->window.entry.padding_left_is_percent = percent.percent; } else if (strcasecmp(option, "padding-right") == 0) { - tofi->window.entry.padding_right = parse_uint32_percent(filename, lineno, value, &err, tofi->output_width); + percent = parse_uint32_percent(filename, lineno, value, &err); + tofi->window.entry.padding_right = percent.value; + tofi->window.entry.padding_right_is_percent = percent.percent; } else if (strcasecmp(option, "horizontal") == 0) { tofi->window.entry.horizontal = parse_bool(filename, lineno, value, &err); } else if (strcasecmp(option, "hide-cursor") == 0) { @@ -304,6 +330,8 @@ bool parse_option(struct tofi *tofi, const char *filename, size_t lineno, const tofi->window.entry.harfbuzz.disable_hinting = !parse_bool(filename, lineno, value, &err); } else if (strcasecmp(option, "late-keyboard-init") == 0) { tofi->late_keyboard_init = parse_bool(filename, lineno, value, &err); + } else if (strcasecmp(option, "output") == 0) { + snprintf(tofi->target_output_name, N_ELEM(tofi->target_output_name), "%s", value); } else { PARSE_ERROR(filename, lineno, "Unknown option \"%s\"\n", option); err = true; @@ -311,13 +339,47 @@ bool parse_option(struct tofi *tofi, const char *filename, size_t lineno, const return !err; } -void apply_option(struct tofi *tofi, const char *option, const char *value) +void config_apply(struct tofi *tofi, const char *option, const char *value) { if (!parse_option(tofi, "", 0, option, value)) { exit(EXIT_FAILURE); }; } +void config_fix_percentages(struct tofi *tofi) +{ + if (tofi->window.width_is_percent) { + tofi->window.width = tofi->window.width * tofi->output_width / 100; + } + if (tofi->window.height_is_percent) { + tofi->window.height = tofi->window.height * tofi->output_height / 100; + } + if (tofi->window.margin_top_is_percent) { + tofi->window.margin_top = tofi->window.margin_top * tofi->output_height / 100; + } + if (tofi->window.margin_bottom_is_percent) { + tofi->window.margin_bottom = tofi->window.margin_bottom * tofi->output_height / 100; + } + if (tofi->window.margin_left_is_percent) { + tofi->window.margin_left = tofi->window.margin_left * tofi->output_width / 100; + } + if (tofi->window.margin_right_is_percent) { + tofi->window.margin_right = tofi->window.margin_right * tofi->output_width / 100; + } + if (tofi->window.entry.padding_top_is_percent) { + tofi->window.entry.padding_top = tofi->window.entry.padding_top * tofi->output_height / 100; + } + if (tofi->window.entry.padding_bottom_is_percent) { + tofi->window.entry.padding_bottom = tofi->window.entry.padding_bottom * tofi->output_height / 100; + } + if (tofi->window.entry.padding_left_is_percent) { + tofi->window.entry.padding_left = tofi->window.entry.padding_left * tofi->output_width / 100; + } + if (tofi->window.entry.padding_right_is_percent) { + tofi->window.entry.padding_right = tofi->window.entry.padding_right * tofi->output_width / 100; + } +} + char *get_config_path() { char *base_dir = getenv("XDG_CONFIG_HOME"); @@ -450,17 +512,18 @@ int32_t parse_int32(const char *filename, size_t lineno, const char *str, bool * return ret; } -uint32_t parse_uint32_percent(const char *filename, size_t lineno, const char *str, bool *err, uint32_t max) +struct uint32_percent parse_uint32_percent(const char *filename, size_t lineno, const char *str, bool *err) { errno = 0; char *endptr; - int32_t ret = strtoul(str, &endptr, 0); + int32_t val = strtoul(str, &endptr, 0); + bool percent = false; if (endptr == str) { PARSE_ERROR(filename, lineno, "Failed to parse \"%s\" as unsigned int.\n", str); if (err) { *err = true; } - } else if (errno || ret < 0) { + } else if (errno || val < 0) { PARSE_ERROR(filename, lineno, "Unsigned int value \"%s\" out of range.\n", str); if (err) { *err = true; @@ -468,8 +531,8 @@ uint32_t parse_uint32_percent(const char *filename, size_t lineno, const char *s } if (!err || !*err) { if (*endptr == '%') { - ret = max * ret / 100; + percent = true; } } - return ret; + return (struct uint32_percent){ val, percent }; } diff --git a/src/config.h b/src/config.h index 65e4f4d..c8db6b4 100644 --- a/src/config.h +++ b/src/config.h @@ -4,6 +4,7 @@ #include "tofi.h" void config_load(struct tofi *tofi, const char *filename); -void apply_option(struct tofi *tofi, const char *option, const char *value); +void config_apply(struct tofi *tofi, const char *option, const char *value); +void config_fix_percentages(struct tofi *tofi); #endif /* TOFI_CONFIG_H */ diff --git a/src/entry.h b/src/entry.h index 45865af..2dfa47e 100644 --- a/src/entry.h +++ b/src/entry.h @@ -61,6 +61,10 @@ struct entry { uint32_t padding_bottom; uint32_t padding_left; uint32_t padding_right; + bool padding_top_is_percent; + bool padding_bottom_is_percent; + bool padding_left_is_percent; + bool padding_right_is_percent; int32_t selection_background_padding; uint32_t input_width; uint32_t border_width; @@ -824,33 +824,12 @@ const struct option long_options[] = { {"drun-launch", required_argument, NULL, 0}, {"drun-print-exec", required_argument, NULL, 0}, {"hint-font", required_argument, NULL, 0}, - {"output", required_argument, NULL, 'o'}, - {"late-keyboard-init", no_argument, NULL, 'k'}, + {"output", required_argument, NULL, 0}, + {"late-keyboard-init", optional_argument, NULL, 'k'}, {NULL, 0, NULL, 0} }; const char *short_options = ":hc:"; -static void parse_early_args(struct tofi *tofi, int argc, char *argv[]) -{ - /* Handle errors ourselves (i.e. ignore them for now). */ - opterr = 0; - - /* Just check for help, late-keyboard-init and output */ - optind = 1; - int opt = getopt_long(argc, argv, short_options, long_options, NULL); - while (opt != -1) { - if (opt == 'h') { - usage(); - exit(EXIT_SUCCESS); - } else if (opt == 'k') { - tofi->late_keyboard_init = true; - } else if (opt == 'o') { - snprintf(tofi->target_output_name, N_ELEM(tofi->target_output_name), "%s", optarg); - } - opt = getopt_long(argc, argv, short_options, long_options, NULL); - } -} - static void parse_args(struct tofi *tofi, int argc, char *argv[]) { @@ -894,7 +873,17 @@ static void parse_args(struct tofi *tofi, int argc, char *argv[]) opt = getopt_long(argc, argv, short_options, long_options, &option_index); while (opt != -1) { if (opt == 0) { - apply_option(tofi, long_options[option_index].name, optarg); + config_apply(tofi, long_options[option_index].name, optarg); + } else if (opt == 'k') { + /* + * Backwards compatibility for --late-keyboard-init not + * taking an argument. + */ + if (optarg) { + config_apply(tofi, long_options[option_index].name, optarg); + } else { + tofi->late_keyboard_init = true; + } } opt = getopt_long(argc, argv, short_options, long_options, &option_index); } @@ -983,7 +972,7 @@ int main(int argc, char *argv[]) }; wl_list_init(&tofi.output_list); - parse_early_args(&tofi, argc, argv); + parse_args(&tofi, argc, argv); /* * Initial Wayland & XKB setup. @@ -1148,11 +1137,8 @@ int main(int argc, char *argv[]) log_debug("Selected output %s.\n", el->name); } - /* - * We can now parse our arguments and config file, as we know the - * output size required for specifying window sizes in percent. - */ - parse_args(&tofi, argc, argv); + /* We can now calculate any percentages, as we know the output size. */ + config_fix_percentages(&tofi); /* Scale fonts to the correct size. */ tofi.window.entry.font_size *= tofi.window.scale; @@ -60,6 +60,12 @@ struct tofi { int32_t margin_bottom; int32_t margin_left; int32_t margin_right; + bool width_is_percent; + bool height_is_percent; + bool margin_top_is_percent; + bool margin_bottom_is_percent; + bool margin_left_is_percent; + bool margin_right_is_percent; } window; struct { uint32_t rate; |