diff options
author | Phil Jones <philj56@gmail.com> | 2022-06-23 10:15:28 +0100 |
---|---|---|
committer | Phil Jones <philj56@gmail.com> | 2022-06-23 10:15:28 +0100 |
commit | 7756d7f462b1223f253805967118e08224ff9aaf (patch) | |
tree | 00140512a07905aa578865240a613a623082508d /src | |
parent | c149768f888efbf9ab237730280402bd607894ac (diff) |
Allow percentages for window size & margins.
Diffstat (limited to 'src')
-rw-r--r-- | src/config.c | 51 | ||||
-rw-r--r-- | src/entry.h | 6 | ||||
-rw-r--r-- | src/main.c | 41 | ||||
-rw-r--r-- | src/tofi.h | 18 |
4 files changed, 75 insertions, 41 deletions
diff --git a/src/config.c b/src/config.c index fa1b41a..e68a725 100644 --- a/src/config.c +++ b/src/config.c @@ -21,11 +21,12 @@ static char *strip(const char *str); static bool parse_option(struct tofi *tofi, size_t lineno, const char *option, const char *value); static char *get_config_path(void); -static int parse_anchor(size_t lineno, const char *str, bool *err); +static int8_t parse_anchor(size_t lineno, const char *str, bool *err); static bool parse_bool(size_t lineno, const char *str, bool *err); static struct color parse_color(size_t lineno, const char *str, bool *err); static uint32_t parse_uint32(size_t lineno, const char *str, bool *err); static int32_t parse_int32(size_t lineno, const char *str, bool *err); +static uint32_t parse_uint32_percent(size_t lineno, const char *str, bool *err, uint32_t max); /* * Function-like macro. Yuck. @@ -237,10 +238,7 @@ bool parse_option(struct tofi *tofi, size_t lineno, const char *option, const ch } else if (strcasecmp(option, "entry-color") == 0) { tofi->window.entry.background_color = parse_color(lineno, value, &err); } else if (strcasecmp(option, "font-name") == 0) { - if (tofi->window.entry.font_name) { - free(tofi->window.entry.font_name); - } - tofi->window.entry.font_name = strdup(value); + snprintf(tofi->window.entry.font_name, N_ELEM(tofi->window.entry.font_name), "%s", value); } else if (strcasecmp(option, "font-size") == 0) { tofi->window.entry.font_size = parse_uint32(lineno, value, &err); } else if (strcasecmp(option, "num-results") == 0) { @@ -250,10 +248,7 @@ bool parse_option(struct tofi *tofi, size_t lineno, const char *option, const ch } else if (strcasecmp(option, "outline-color") == 0) { tofi->window.entry.border.outline_color = parse_color(lineno, value, &err); } else if (strcasecmp(option, "prompt-text") == 0) { - if (tofi->window.entry.prompt_text) { - free(tofi->window.entry.prompt_text); - } - tofi->window.entry.prompt_text = strdup(value); + snprintf(tofi->window.entry.prompt_text, N_ELEM(tofi->window.entry.prompt_text), "%s", value); } else if (strcasecmp(option, "result-padding") == 0) { tofi->window.entry.result_padding = parse_int32(lineno, value, &err); } else if (strcasecmp(option, "border-width") == 0) { @@ -265,17 +260,17 @@ bool parse_option(struct tofi *tofi, size_t lineno, const char *option, const ch } else if (strcasecmp(option, "selection-color") == 0) { tofi->window.entry.selection_color = parse_color(lineno, value, &err); } else if (strcasecmp(option, "width") == 0) { - tofi->window.width = parse_uint32(lineno, value, &err); + tofi->window.width = parse_uint32_percent(lineno, value, &err, tofi->output_width / tofi->window.scale); } else if (strcasecmp(option, "height") == 0) { - tofi->window.height = parse_uint32(lineno, value, &err); + tofi->window.height = parse_uint32_percent(lineno, value, &err, tofi->output_height / tofi->window.scale); } else if (strcasecmp(option, "margin-top") == 0) { - tofi->window.margin_top = parse_uint32(lineno, value, &err); + tofi->window.margin_top = parse_uint32_percent(lineno, value, &err, tofi->output_height / tofi->window.scale); } else if (strcasecmp(option, "margin-bottom") == 0) { - tofi->window.margin_bottom = parse_uint32(lineno, value, &err); + tofi->window.margin_bottom = parse_uint32_percent(lineno, value, &err, tofi->output_height / tofi->window.scale); } else if (strcasecmp(option, "margin-left") == 0) { - tofi->window.margin_left = parse_uint32(lineno, value, &err); + tofi->window.margin_left = parse_uint32_percent(lineno, value, &err, tofi->output_width / tofi->window.scale); } else if (strcasecmp(option, "margin-right") == 0) { - tofi->window.margin_right = parse_uint32(lineno, value, &err); + tofi->window.margin_right = parse_uint32_percent(lineno, value, &err, tofi->output_width / tofi->window.scale); } else if (strcasecmp(option, "horizontal") == 0) { tofi->window.entry.horizontal = parse_bool(lineno, value, &err); } else if (strcasecmp(option, "hide-cursor") == 0) { @@ -327,7 +322,7 @@ bool parse_bool(size_t lineno, const char *str, bool *err) return false; } -int parse_anchor(size_t lineno, const char *str, bool *err) +int8_t parse_anchor(size_t lineno, const char *str, bool *err) { if(strcasecmp(str, "top-left") == 0) { return ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP @@ -410,3 +405,27 @@ int32_t parse_int32(size_t lineno, const char *str, bool *err) } return ret; } + +uint32_t parse_uint32_percent(size_t lineno, const char *str, bool *err, uint32_t max) +{ + errno = 0; + char *endptr; + int32_t ret = strtoul(str, &endptr, 0); + if (endptr == str) { + PARSE_ERROR(lineno, "Failed to parse \"%s\" as unsigned int.\n", str); + if (err) { + *err = true; + } + } else if (errno || ret < 0) { + PARSE_ERROR(lineno, "Unsigned int value \"%s\" out of range.\n", str); + if (err) { + *err = true; + } + } + if (!err || !*err) { + if (*endptr == '%') { + ret = max * ret / 100; + } + } + return ret; +} diff --git a/src/entry.h b/src/entry.h index d0295bc..7ceb215 100644 --- a/src/entry.h +++ b/src/entry.h @@ -16,6 +16,8 @@ #include "string_vec.h" #define MAX_INPUT_LENGTH 128 +#define MAX_PROMPT_LENGTH 128 +#define MAX_FONT_NAME_LENGTH 128 struct entry { struct image image; @@ -41,8 +43,8 @@ struct entry { bool horizontal; uint32_t num_results; uint32_t font_size; - char *font_name; - char *prompt_text; + char font_name[MAX_FONT_NAME_LENGTH]; + char prompt_text[MAX_PROMPT_LENGTH]; uint32_t corner_radius; uint32_t padding; int32_t result_padding; @@ -422,7 +422,12 @@ static void output_mode( int32_t height, int32_t refresh) { - /* Deliberately left blank */ + struct tofi *tofi = data; + if (flags & WL_OUTPUT_MODE_CURRENT) { + log_debug("Output mode %dx%d\n", width, height); + tofi->output_width = MAX(width, tofi->output_width); + tofi->output_height = MAX(height, tofi->output_height); + } } static void output_scale( @@ -574,13 +579,13 @@ static void usage() " --num-results <n> Maximum number of results to display.\n" " --selection-color <color> Color of selected result.\n" " --result-padding <px> Spacing between results. Can be negative.\n" -" --width <px> Width of the window.\n" -" --height <px> Height of the window.\n" +" --width <px|%> Width of the window.\n" +" --height <px|%> Height of the window.\n" " --anchor <position> Location on screen to anchor window.\n" -" --margin-top <px> Offset from top of screen.\n" -" --margin-bottom <px> Offset from bottom of screen.\n" -" --margin-left <px> Offset from left of screen.\n" -" --margin-right <px> Offset from right of screen.\n" +" --margin-top <px|%> Offset from top of screen.\n" +" --margin-bottom <px|%> Offset from bottom of screen.\n" +" --margin-left <px|%> Offset from left of screen.\n" +" --margin-right <px|%> Offset from right of screen.\n" " --hide-cursor <true|false> Hide the cursor.\n" ); } @@ -687,20 +692,22 @@ int main(int argc, char *argv[]) .color = {0.976f, 0.149f, 0.447f, 1.0f}, .outline_color = {0.031f, 0.031f, 0.0f, 1.0f}, }, - .font_name = strdup("Sans Bold"), + .font_name = "Sans Bold", .font_size = 24, - .prompt_text = strdup("run: "), + .prompt_text = "run: ", .num_results = 5, .padding = 8, .background_color = {0.106f, 0.114f, 0.118f, 1.0f}, .foreground_color = {1.0f, 1.0f, 1.0f, 1.0f}, .selection_color = {0.976f, 0.149f, 0.447f, 1.0f} } - } + }, + .anchor = ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP + | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM + | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT + | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT, }; - parse_args(&tofi, argc, argv); - log_debug("Generating command list.\n"); log_indent(); tofi.window.entry.history = history_load(); @@ -747,7 +754,7 @@ int main(int argc, char *argv[]) /* * The next roundtrip causes the listeners we set up in * registry_global() to be called. Notably, the output should be - * configured, telling us the scale factor. + * configured, telling us the scale factor and size. */ log_debug("Second roundtrip start.\n"); log_indent(); @@ -756,6 +763,12 @@ int main(int argc, char *argv[]) log_debug("Second roundtrip done.\n"); /* + * 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); + + /* * Next, we create the Wayland surface, which takes on the * layer shell role. */ @@ -924,8 +937,6 @@ int main(int argc, char *argv[]) string_vec_destroy(&tofi.window.entry.commands); string_vec_destroy(&tofi.window.entry.results); history_destroy(&tofi.window.entry.history); - free(tofi.window.entry.font_name); - free(tofi.window.entry.prompt_text); #endif /* * For release builds, skip straight to display disconnection and quit. @@ -10,7 +10,7 @@ #include "wlr-layer-shell-unstable-v1.h" struct tofi { - /* Globals */ + /* Wayland globals */ struct wl_display *wl_display; struct wl_registry *wl_registry; struct wl_compositor *wl_compositor; @@ -19,13 +19,20 @@ struct tofi { struct wl_shm *wl_shm; struct zwlr_layer_shell_v1 *zwlr_layer_shell; - /* Objects */ + /* Wayland objects */ struct wl_keyboard *wl_keyboard; struct wl_pointer *wl_pointer; + /* Keyboard objects */ + struct xkb_state *xkb_state; + struct xkb_context *xkb_context; + struct xkb_keymap *xkb_keymap; + /* State */ bool submit; bool closed; + int32_t output_width; + int32_t output_height; struct { struct surface surface; struct zwlr_layer_surface_v1 *zwlr_layer_surface; @@ -40,13 +47,8 @@ struct tofi { int32_t margin_right; } window; - /* Keyboard state */ - struct xkb_state *xkb_state; - struct xkb_context *xkb_context; - struct xkb_keymap *xkb_keymap; - /* Options */ - int anchor; + int8_t anchor; bool hide_cursor; }; |