summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/config.c51
-rw-r--r--src/entry.h6
-rw-r--r--src/main.c41
-rw-r--r--src/tofi.h18
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;
diff --git a/src/main.c b/src/main.c
index 15af4c0..4df34a4 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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.
diff --git a/src/tofi.h b/src/tofi.h
index 63d9e6b..be4e750 100644
--- a/src/tofi.h
+++ b/src/tofi.h
@@ -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;
};