ignore modifiers for KeyRelease bindings
For the following binding: # Simulate ctrl+v upon pressing $mod+x bindsym --release $mod+x exec --no-startup-id xdotool key --clearmodifiers ctrl+v you can now use either: 1. press $mod, press x, release x, release $mod 2. press $mod, press x, release $mod, release x fixes #485
This commit is contained in:
parent
c6c6d3a952
commit
548d74015c
|
@ -202,7 +202,17 @@ struct regex {
|
|||
struct Binding {
|
||||
/** If true, the binding should be executed upon a KeyRelease event, not a
|
||||
* KeyPress (the default). */
|
||||
bool release;
|
||||
enum {
|
||||
/* This binding will only be executed upon KeyPress events */
|
||||
B_UPON_KEYPRESS = 0,
|
||||
/* This binding will be executed either upon a KeyRelease event, or… */
|
||||
B_UPON_KEYRELEASE = 1,
|
||||
/* …upon a KeyRelease event, even if the modifiers don’t match. This
|
||||
* state is triggered from get_binding() when the corresponding
|
||||
* KeyPress (!) happens, so that users can release the modifier keys
|
||||
* before releasing the actual key. */
|
||||
B_UPON_KEYRELEASE_IGNORE_MODS = 2,
|
||||
} release;
|
||||
|
||||
/** Symbol the user specified in configfile, if any. This needs to be
|
||||
* stored with the binding to be able to re-convert it into a keycode
|
||||
|
|
|
@ -913,8 +913,8 @@ bindsym:
|
|||
;
|
||||
|
||||
optional_release:
|
||||
/* empty */ { $$ = false; }
|
||||
| TOK_RELEASE { $$ = true; }
|
||||
/* empty */ { $$ = B_UPON_KEYPRESS; }
|
||||
| TOK_RELEASE { $$ = B_UPON_KEYRELEASE; }
|
||||
;
|
||||
|
||||
for_window:
|
||||
|
|
28
src/config.c
28
src/config.c
|
@ -57,13 +57,35 @@ static void grab_keycode_for_binding(xcb_connection_t *conn, Binding *bind, uint
|
|||
Binding *get_binding(uint16_t modifiers, bool key_release, xcb_keycode_t keycode) {
|
||||
Binding *bind;
|
||||
|
||||
if (!key_release) {
|
||||
/* On a KeyPress event, we first reset all
|
||||
* B_UPON_KEYRELEASE_IGNORE_MODS bindings back to B_UPON_KEYRELEASE */
|
||||
TAILQ_FOREACH(bind, bindings, bindings) {
|
||||
/* First compare the modifiers */
|
||||
if (bind->mods != modifiers)
|
||||
if (bind->release == B_UPON_KEYRELEASE_IGNORE_MODS)
|
||||
bind->release = B_UPON_KEYRELEASE;
|
||||
}
|
||||
|
||||
/* Then we transition the KeyRelease bindings into a state where the
|
||||
* modifiers no longer matter for the KeyRelease event so that users
|
||||
* can release the modifier key before releasing the actual key. */
|
||||
TAILQ_FOREACH(bind, bindings, bindings) {
|
||||
if (bind->release == B_UPON_KEYRELEASE && !key_release)
|
||||
bind->release = B_UPON_KEYRELEASE_IGNORE_MODS;
|
||||
}
|
||||
}
|
||||
|
||||
TAILQ_FOREACH(bind, bindings, bindings) {
|
||||
/* First compare the modifiers (unless this is a
|
||||
* B_UPON_KEYRELEASE_IGNORE_MODS binding and this is a KeyRelease
|
||||
* event) */
|
||||
if (bind->mods != modifiers &&
|
||||
(bind->release != B_UPON_KEYRELEASE_IGNORE_MODS ||
|
||||
!key_release))
|
||||
continue;
|
||||
|
||||
/* Check if the binding is for a KeyPress or a KeyRelease event */
|
||||
if (bind->release != key_release)
|
||||
if ((bind->release == B_UPON_KEYPRESS && key_release) ||
|
||||
(bind->release >= B_UPON_KEYRELEASE && !key_release))
|
||||
continue;
|
||||
|
||||
/* If a symbol was specified by the user, we need to look in
|
||||
|
|
Loading…
Reference in New Issue