summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--completions/tofi3
-rw-r--r--doc/tofi.1.md7
-rw-r--r--doc/tofi.1.scd6
-rw-r--r--src/config.c2
-rw-r--r--src/main.c151
-rw-r--r--src/tofi.h2
6 files changed, 124 insertions, 47 deletions
diff --git a/completions/tofi b/completions/tofi
index d997183..7bf35ed 100644
--- a/completions/tofi
+++ b/completions/tofi
@@ -37,6 +37,7 @@ _tofi()
--hide-cursor
--history
--hint-font
+ --late-keyboard-init
)
case "${prev}" in
@@ -48,6 +49,8 @@ _tofi()
;;
--help|-h)
;;
+ --late-keyboard-init)
+ ;;
--*)
return 0
;;
diff --git a/doc/tofi.1.md b/doc/tofi.1.md
index 6177b2d..491535f 100644
--- a/doc/tofi.1.md
+++ b/doc/tofi.1.md
@@ -34,6 +34,13 @@ on stdin, instead presenting a list of executables in the user's $PATH.
> Specify path to custom config file.
+**--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 405e7df..af9d8de 100644
--- a/doc/tofi.1.scd
+++ b/doc/tofi.1.scd
@@ -31,6 +31,12 @@ instead presenting a list of executables in the user's $PATH.
*-c, --config* <path>
Specify path to custom config file.
+*--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/src/config.c b/src/config.c
index 23faa24..49ffe03 100644
--- a/src/config.c
+++ b/src/config.c
@@ -289,6 +289,8 @@ bool parse_option(struct tofi *tofi, const char *filename, size_t lineno, const
tofi->use_history = parse_bool(filename, lineno, value, &err);
} else if (strcasecmp(option, "hint-font") == 0) {
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 {
PARSE_ERROR(filename, lineno, "Unknown option \"%s\"\n", option);
err = true;
diff --git a/src/main.c b/src/main.c
index 983a8fb..58550c6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -22,6 +22,7 @@
#include "nelem.h"
#include "shm.h"
#include "string_vec.h"
+#include "xmalloc.h"
#undef MAX
#undef MIN
@@ -95,19 +96,26 @@ static void wl_keyboard_keymap(
char *map_shm = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
assert(map_shm != MAP_FAILED);
- struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_string(
- tofi->xkb_context,
- map_shm,
- XKB_KEYMAP_FORMAT_TEXT_V1,
- XKB_KEYMAP_COMPILE_NO_FLAGS);
+ if (tofi->late_keyboard_init) {
+ tofi->xkb_keymap_string = xstrdup(map_shm);
+ } else {
+ struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_string(
+ tofi->xkb_context,
+ map_shm,
+ XKB_KEYMAP_FORMAT_TEXT_V1,
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
+ munmap(map_shm, size);
+ close(fd);
+
+ struct xkb_state *xkb_state = xkb_state_new(xkb_keymap);
+ xkb_keymap_unref(tofi->xkb_keymap);
+ xkb_state_unref(tofi->xkb_state);
+ tofi->xkb_keymap = xkb_keymap;
+ tofi->xkb_state = xkb_state;
+ }
munmap(map_shm, size);
close(fd);
- struct xkb_state *xkb_state = xkb_state_new(xkb_keymap);
- xkb_keymap_unref(tofi->xkb_keymap);
- xkb_state_unref(tofi->xkb_state);
- tofi->xkb_keymap = xkb_keymap;
- tofi->xkb_state = xkb_state;
log_debug("Keyboard configured.\n");
}
@@ -140,6 +148,9 @@ static void wl_keyboard_key(
{
struct tofi *tofi = data;
uint32_t keycode = key + 8;
+ if (tofi->xkb_state == NULL) {
+ return;
+ }
xkb_keysym_t sym = xkb_state_key_get_one_sym(
tofi->xkb_state,
keycode);
@@ -223,6 +234,9 @@ static void wl_keyboard_modifiers(
uint32_t group)
{
struct tofi *tofi = data;
+ if (tofi->xkb_state == NULL) {
+ return;
+ }
xkb_state_update_mask(
tofi->xkb_state,
mods_depressed,
@@ -560,9 +574,10 @@ static void usage()
{
fprintf(stderr, "%s",
"Usage: tofi [options]\n"
+"\n"
" -h, --help Print this message and exit.\n"
" -c, --config Specify a config file.\n"
-" --font <name|path> Font to use.\n"
+" --font <name|path> Font to use.\n"
" --font-size <pt> Point size of text.\n"
" --background-color <color> Color of the background.\n"
" --outline-width <px> Width of the border outlines.\n"
@@ -591,47 +606,70 @@ static void usage()
" --horizontal <true|false> List results horizontally.\n"
" --history <true|false> Sort results by number of usages.\n"
" --hint-font <true|false> Perform font hinting.\n"
+" --late-keyboard-init (EXPERIMENTAL) Delay keyboard initialisation\n"
+" until after the first draw to screen.\n"
);
}
+/* Option parsing with getopt. */
+const struct option long_options[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"config", required_argument, NULL, 'c'},
+ {"anchor", required_argument, NULL, 0},
+ {"background-color", required_argument, NULL, 0},
+ {"corner-radius", required_argument, NULL, 0},
+ {"font", required_argument, NULL, 0},
+ {"font-size", required_argument, NULL, 0},
+ {"num-results", required_argument, NULL, 0},
+ {"selection-color", required_argument, NULL, 0},
+ {"outline-width", required_argument, NULL, 0},
+ {"outline-color", required_argument, NULL, 0},
+ {"prompt-text", required_argument, NULL, 0},
+ {"result-spacing", required_argument, NULL, 0},
+ {"min-input-width", required_argument, NULL, 0},
+ {"border-width", required_argument, NULL, 0},
+ {"border-color", required_argument, NULL, 0},
+ {"text-color", required_argument, NULL, 0},
+ {"width", required_argument, NULL, 0},
+ {"height", required_argument, NULL, 0},
+ {"margin-top", required_argument, NULL, 0},
+ {"margin-bottom", required_argument, NULL, 0},
+ {"margin-left", required_argument, NULL, 0},
+ {"margin-right", required_argument, NULL, 0},
+ {"padding-top", required_argument, NULL, 0},
+ {"padding-bottom", required_argument, NULL, 0},
+ {"padding-left", required_argument, NULL, 0},
+ {"padding-right", required_argument, NULL, 0},
+ {"horizontal", required_argument, NULL, 0},
+ {"hide-cursor", required_argument, NULL, 0},
+ {"history", required_argument, NULL, 0},
+ {"hint-font", required_argument, NULL, 0},
+ {"late-keyboard-init", no_argument, NULL, 1},
+ {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 and late-keyboard-init */
+ 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 == 1) {
+ tofi->late_keyboard_init = true;
+ }
+ opt = getopt_long(argc, argv, short_options, long_options, NULL);
+ }
+}
+
static void parse_args(struct tofi *tofi, int argc, char *argv[])
{
- /* Option parsing with getopt. */
- const struct option long_options[] = {
- {"help", no_argument, NULL, 'h'},
- {"config", required_argument, NULL, 'c'},
- {"anchor", required_argument, NULL, 0},
- {"background-color", required_argument, NULL, 0},
- {"corner-radius", required_argument, NULL, 0},
- {"font", required_argument, NULL, 0},
- {"font-size", required_argument, NULL, 0},
- {"num-results", required_argument, NULL, 0},
- {"selection-color", required_argument, NULL, 0},
- {"outline-width", required_argument, NULL, 0},
- {"outline-color", required_argument, NULL, 0},
- {"prompt-text", required_argument, NULL, 0},
- {"result-spacing", required_argument, NULL, 0},
- {"min-input-width", required_argument, NULL, 0},
- {"border-width", required_argument, NULL, 0},
- {"border-color", required_argument, NULL, 0},
- {"text-color", required_argument, NULL, 0},
- {"width", required_argument, NULL, 0},
- {"height", required_argument, NULL, 0},
- {"margin-top", required_argument, NULL, 0},
- {"margin-bottom", required_argument, NULL, 0},
- {"margin-left", required_argument, NULL, 0},
- {"margin-right", required_argument, NULL, 0},
- {"padding-top", required_argument, NULL, 0},
- {"padding-bottom", required_argument, NULL, 0},
- {"padding-left", required_argument, NULL, 0},
- {"padding-right", required_argument, NULL, 0},
- {"horizontal", required_argument, NULL, 0},
- {"hide-cursor", required_argument, NULL, 0},
- {"history", required_argument, NULL, 0},
- {"hint-font", required_argument, NULL, 0},
- {NULL, 0, NULL, 0}
- };
- const char *short_options = ":hc:";
bool load_default_config = true;
int option_index = 0;
@@ -724,6 +762,8 @@ int main(int argc, char *argv[])
.use_history = true,
};
+ parse_early_args(&tofi, argc, argv);
+
/*
* Initial Wayland & XKB setup.
@@ -921,6 +961,23 @@ int main(int argc, char *argv[])
/* We've just rendered, so we don't need to do it again right now. */
tofi.window.surface.redraw = false;
+ /* If we delayed keyboard initialisation, do it now */
+ if (tofi.late_keyboard_init) {
+ struct xkb_keymap *xkb_keymap = xkb_keymap_new_from_string(
+ tofi.xkb_context,
+ tofi.xkb_keymap_string,
+ XKB_KEYMAP_FORMAT_TEXT_V1,
+ XKB_KEYMAP_COMPILE_NO_FLAGS);
+
+ struct xkb_state *xkb_state = xkb_state_new(xkb_keymap);
+ xkb_keymap_unref(tofi.xkb_keymap);
+ xkb_state_unref(tofi.xkb_state);
+ tofi.xkb_keymap = xkb_keymap;
+ tofi.xkb_state = xkb_state;
+ free(tofi.xkb_keymap_string);
+ tofi.late_keyboard_init = false;
+ }
+
while (wl_display_dispatch(tofi.wl_display) != -1) {
if (tofi.closed) {
break;
diff --git a/src/tofi.h b/src/tofi.h
index 26cd3b1..788a73f 100644
--- a/src/tofi.h
+++ b/src/tofi.h
@@ -24,6 +24,7 @@ struct tofi {
struct wl_pointer *wl_pointer;
/* Keyboard objects */
+ char *xkb_keymap_string;
struct xkb_state *xkb_state;
struct xkb_context *xkb_context;
struct xkb_keymap *xkb_keymap;
@@ -50,6 +51,7 @@ struct tofi {
uint32_t anchor;
bool hide_cursor;
bool use_history;
+ bool late_keyboard_init;
};
#endif /* CLIENT_H */