Skip to content

Commit

Permalink
Add --physical-keybindings option.
Browse files Browse the repository at this point in the history
  • Loading branch information
philj56 committed Jul 16, 2023
1 parent 0f1b2a8 commit 47a7f68
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 24 deletions.
1 change: 1 addition & 0 deletions completions/tofi
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ _tofi()
--print-index
--hide-input
--hidden-character
--physical-keybindings
--drun-launch
--terminal
--hint-font
Expand Down
4 changes: 4 additions & 0 deletions doc/config
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,10 @@
# This option only has an effect when hide-input is set to true.
hidden-character = "*"

# If true, use physical keys for shortcuts, regardless of the current
# keyboard layout. If false, use the current layout's keys.
physical-keybindings = true

# Instead of printing the selected entry, print the 1-based index of
# the selection. This option has no effect in run or drun mode. If
# require-match is set to false, non-matching input will still result
Expand Down
7 changes: 7 additions & 0 deletions doc/tofi.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ options.
>
> Default: \*
**physical-keybindings**=*true\|false*

> If true, use physical keys for shortcuts, regardless of the current
> keyboard layout. If false, use the current layout's keys.
>
> Default: true
**print-index**=*true\|false*

> Instead of printing the selected entry, print the 1-based index of the
Expand Down
6 changes: 6 additions & 0 deletions doc/tofi.5.scd
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ options.

Default: \*

*physical-keybindings*=_true|false_
If true, use physical keys for shortcuts, regardless of the current
keyboard layout. If false, use the current layout's keys.

Default: true

*print-index*=_true|false_
Instead of printing the selected entry, print the 1-based index of the
selection. This option has no effect in run or drun mode. If
Expand Down
5 changes: 5 additions & 0 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,11 @@ bool parse_option(struct tofi *tofi, const char *filename, size_t lineno, const
tofi->window.entry.hidden_character_utf8_length =
utf32_to_utf8(ch, tofi->window.entry.hidden_character_utf8);
}
} else if (strcasecmp(option, "physical-keybindings") == 0) {
bool val = parse_bool(filename, lineno, value, &err);
if (!err) {
tofi->physical_keybindings = val;
}
} else if (strcasecmp(option, "drun-launch") == 0) {
bool val = parse_bool(filename, lineno, value, &err);
if (!err) {
Expand Down
113 changes: 89 additions & 24 deletions src/input.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "unicode.h"


static uint32_t keysym_to_key(xkb_keysym_t sym);
static void add_character(struct tofi *tofi, xkb_keycode_t keycode);
static void delete_character(struct tofi *tofi);
static void delete_word(struct tofi *tofi);
Expand All @@ -28,13 +29,6 @@ void input_handle_keypress(struct tofi *tofi, xkb_keycode_t keycode)
return;
}

/*
* Use physical key code for shortcuts, ignoring layout changes.
* Linux keycodes are 8 less than XKB keycodes.
*/
const uint32_t key = keycode - 8;

xkb_keysym_t sym = xkb_state_key_get_one_sym(tofi->xkb_state, keycode);
bool ctrl = xkb_state_mod_name_is_active(
tofi->xkb_state,
XKB_MOD_NAME_CTRL,
Expand All @@ -43,49 +37,64 @@ void input_handle_keypress(struct tofi *tofi, xkb_keycode_t keycode)
tofi->xkb_state,
XKB_MOD_NAME_ALT,
XKB_STATE_MODS_EFFECTIVE);
bool shift = xkb_state_mod_name_is_active(
tofi->xkb_state,
XKB_MOD_NAME_SHIFT,
XKB_STATE_MODS_EFFECTIVE);

uint32_t ch = xkb_state_key_get_utf32(tofi->xkb_state, keycode);

/*
* Use physical key code for shortcuts by default, ignoring layout
* changes. Linux keycodes are 8 less than XKB keycodes.
*/
uint32_t key = keycode - 8;
if (!tofi->physical_keybindings) {
xkb_keysym_t sym = xkb_state_key_get_one_sym(tofi->xkb_state, keycode);
key = keysym_to_key(sym);
}

/*
* Alt does not affect which character is selected, so we have to check
* for it explicitly.
*/
if (utf32_isprint(ch) && !alt) {
if (utf32_isprint(ch) && !ctrl && !alt) {
add_character(tofi, keycode);
} else if ((sym == XKB_KEY_BackSpace || key == KEY_W) && ctrl) {
} else if ((key == KEY_BACKSPACE || key == KEY_W) && ctrl) {
delete_word(tofi);
} else if (sym == XKB_KEY_BackSpace) {
} else if (key == KEY_BACKSPACE) {
delete_character(tofi);
} else if (key == KEY_U && ctrl) {
clear_input(tofi);
} else if (key == KEY_V && ctrl) {
paste(tofi);
} else if (sym == XKB_KEY_Left) {
} else if (key == KEY_LEFT) {
previous_cursor_or_result(tofi);
} else if (sym == XKB_KEY_Right) {
} else if (key == KEY_RIGHT) {
next_cursor_or_result(tofi);
} else if (sym == XKB_KEY_Up
|| sym == XKB_KEY_Left
|| sym == XKB_KEY_ISO_Left_Tab
} else if (key == KEY_UP
|| key == KEY_LEFT
|| (key == KEY_TAB && shift)
|| (key == KEY_H && alt)
|| ((key == KEY_K || key == KEY_P) && (ctrl || alt))) {
select_previous_result(tofi);
} else if (sym == XKB_KEY_Down
|| sym == XKB_KEY_Right
|| sym == XKB_KEY_Tab
} else if (key == KEY_DOWN
|| key == KEY_RIGHT
|| key == KEY_TAB
|| (key == KEY_L && alt)
|| ((key == KEY_J || key == KEY_N) && (ctrl || alt))) {
select_next_result(tofi);
} else if (sym == XKB_KEY_Home) {
} else if (key == KEY_HOME) {
reset_selection(tofi);
} else if (sym == XKB_KEY_Page_Up) {
} else if (key == KEY_PAGEUP) {
select_previous_page(tofi);
} else if (sym == XKB_KEY_Page_Down) {
} else if (key == KEY_PAGEDOWN) {
select_next_page(tofi);
} else if (sym == XKB_KEY_Escape
} else if (key == KEY_ESC
|| ((key == KEY_C || key == KEY_LEFTBRACE) && ctrl)) {
tofi->closed = true;
return;
} else if (sym == XKB_KEY_Return || sym == XKB_KEY_KP_Enter) {
} else if (key == KEY_ENTER || key == KEY_KPENTER) {
tofi->submit = true;
return;
}
Expand All @@ -97,7 +106,63 @@ void input_handle_keypress(struct tofi *tofi, xkb_keycode_t keycode)
tofi->window.surface.redraw = true;
}

void reset_selection(struct tofi *tofi) {
static uint32_t keysym_to_key(xkb_keysym_t sym)
{
switch (sym) {
case XKB_KEY_BackSpace:
return KEY_BACKSPACE;
case XKB_KEY_w:
return KEY_W;
case XKB_KEY_u:
return KEY_U;
case XKB_KEY_v:
return KEY_V;
case XKB_KEY_Left:
return KEY_LEFT;
case XKB_KEY_Right:
return KEY_RIGHT;
case XKB_KEY_Up:
return KEY_UP;
case XKB_KEY_ISO_Left_Tab:
return KEY_TAB;
case XKB_KEY_h:
return KEY_H;
case XKB_KEY_k:
return KEY_K;
case XKB_KEY_p:
return KEY_P;
case XKB_KEY_Down:
return KEY_DOWN;
case XKB_KEY_Tab:
return KEY_TAB;
case XKB_KEY_l:
return KEY_L;
case XKB_KEY_j:
return KEY_J;
case XKB_KEY_n:
return KEY_N;
case XKB_KEY_Home:
return KEY_HOME;
case XKB_KEY_Page_Up:
return KEY_PAGEUP;
case XKB_KEY_Page_Down:
return KEY_PAGEDOWN;
case XKB_KEY_Escape:
return KEY_ESC;
case XKB_KEY_c:
return KEY_C;
case XKB_KEY_bracketleft:
return KEY_LEFTBRACE;
case XKB_KEY_Return:
return KEY_ENTER;
case XKB_KEY_KP_Enter:
return KEY_KPENTER;
}
return (uint32_t)-1;
}

void reset_selection(struct tofi *tofi)
{
struct entry *entry = &tofi->window.entry;
entry->selection = 0;
entry->first_result = 0;
Expand Down
2 changes: 2 additions & 0 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -917,6 +917,7 @@ const struct option long_options[] = {
{"print-index", required_argument, NULL, 0},
{"hide-input", required_argument, NULL, 0},
{"hidden-character", required_argument, NULL, 0},
{"physical-keybindings", required_argument, NULL, 0},
{"drun-launch", required_argument, NULL, 0},
{"drun-print-exec", required_argument, NULL, 0},
{"terminal", required_argument, NULL, 0},
Expand Down Expand Up @@ -1198,6 +1199,7 @@ int main(int argc, char *argv[])
.use_history = true,
.require_match = true,
.use_scale = true,
.physical_keybindings = true,
};
wl_list_init(&tofi.output_list);
if (getenv("TERMINAL") != NULL) {
Expand Down
1 change: 1 addition & 0 deletions src/tofi.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ struct tofi {
bool auto_accept_single;
bool print_index;
bool multiple_instance;
bool physical_keybindings;
char target_output_name[MAX_OUTPUT_NAME_LEN];
char default_terminal[MAX_TERMINAL_NAME_LEN];
char history_file[MAX_HISTORY_FILE_NAME_LEN];
Expand Down

0 comments on commit 47a7f68

Please sign in to comment.