config: key-bindings: verify key combo isn't already mapped to another action

This commit is contained in:
Daniel Eklöf 2020-03-12 17:16:35 +01:00
parent c58f9a9ef9
commit 5cbd0527d7
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
2 changed files with 53 additions and 11 deletions

View file

@ -449,6 +449,47 @@ parse_section_csd(const char *key, const char *value, struct config *conf,
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
parse_section_key_bindings(
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)
continue;
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);
if (strcmp(value, "NONE") == 0) {
free(conf->bindings.key[action]);
conf->bindings.key[action] = NULL;
return true;
}
bool valid_combo = input_parse_key_binding_for_action(
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);
if (!verify_key_combo(conf, value, path, lineno)) {
return false;
}

View file

@ -161,6 +161,12 @@ upper case.
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*
Scrolls up/back in history. Default: _Shift+Page_Up_.