mirror of
https://codeberg.org/dnkl/foot.git
synced 2026-03-30 11:10:23 -04:00
config: key-bindings: verify key combo isn't already mapped to another action
This commit is contained in:
parent
c58f9a9ef9
commit
5cbd0527d7
2 changed files with 53 additions and 11 deletions
58
config.c
58
config.c
|
|
@ -449,6 +449,47 @@ parse_section_csd(const char *key, const char *value, struct config *conf,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
verify_key_combo(const struct config *conf, const char *combo, const char *path, unsigned lineno)
|
||||||
|
{
|
||||||
|
for (enum binding_action action = 0; action < BIND_ACTION_COUNT; action++) {
|
||||||
|
if (conf->bindings.key[action] == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char *copy = strdup(conf->bindings.key[action]);
|
||||||
|
|
||||||
|
for (char *save = NULL, *collision = strtok_r(copy, " ", &save);
|
||||||
|
collision != NULL;
|
||||||
|
collision = strtok_r(NULL, " ", &save))
|
||||||
|
{
|
||||||
|
if (strcmp(combo, collision) == 0) {
|
||||||
|
LOG_ERR("%s:%d: %s already mapped to %s", path, lineno, combo, binding_action_map[action]);
|
||||||
|
free(copy);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
free(copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct xkb_context *ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
|
struct xkb_keymap *keymap = xkb_keymap_new_from_names(
|
||||||
|
ctx, &(struct xkb_rule_names){0}, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||||
|
|
||||||
|
bool valid_combo = input_parse_key_binding_for_action(
|
||||||
|
keymap, BIND_ACTION_NONE, combo, NULL);
|
||||||
|
|
||||||
|
xkb_keymap_unref(keymap);
|
||||||
|
xkb_context_unref(ctx);
|
||||||
|
|
||||||
|
if (!valid_combo) {
|
||||||
|
LOG_ERR("%s:%d: invalid key combination: %s", path, lineno, combo);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
parse_section_key_bindings(
|
parse_section_key_bindings(
|
||||||
const char *key, const char *value, struct config *conf,
|
const char *key, const char *value, struct config *conf,
|
||||||
|
|
@ -461,18 +502,13 @@ parse_section_key_bindings(
|
||||||
if (strcmp(key, binding_action_map[action]) != 0)
|
if (strcmp(key, binding_action_map[action]) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
struct xkb_context *ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
if (strcmp(value, "NONE") == 0) {
|
||||||
struct xkb_keymap *keymap = xkb_keymap_new_from_names(
|
free(conf->bindings.key[action]);
|
||||||
ctx, &(struct xkb_rule_names){0}, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
conf->bindings.key[action] = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool valid_combo = input_parse_key_binding_for_action(
|
if (!verify_key_combo(conf, value, path, lineno)) {
|
||||||
keymap, action, value, NULL);
|
|
||||||
|
|
||||||
xkb_keymap_unref(keymap);
|
|
||||||
xkb_context_unref(ctx);
|
|
||||||
|
|
||||||
if (!valid_combo) {
|
|
||||||
LOG_ERR("%s:%d: invalid key combination: %s", path, lineno, value);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,12 @@ upper case.
|
||||||
|
|
||||||
Note that *Alt* is usually called *Mod1*.
|
Note that *Alt* is usually called *Mod1*.
|
||||||
|
|
||||||
|
A key combination can only be mapped to *one* action. Lets say you
|
||||||
|
want to bind *Control*+*Shift*+*R* to *fullscreen*. Since this is the
|
||||||
|
default shortcut for *search-start*, you first need to unmap the
|
||||||
|
default binding. This can be done by setting _action_=*NONE*;
|
||||||
|
e.g. *search-start*=*NONE*.
|
||||||
|
|
||||||
*scrollback-up*
|
*scrollback-up*
|
||||||
Scrolls up/back in history. Default: _Shift+Page_Up_.
|
Scrolls up/back in history. Default: _Shift+Page_Up_.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue