swaywm/sway

`keysym --release` is unreliable

Opened this issue · 5 comments

  • Sway Version: 1.6.1

  • Description:

    • Configure bindsym --release Alt_R notify-send foobar
    • Press Alt_R key
    • Press another key, e.g. Alt_L
    • Release Alt_R

If any key is pressed before releasing the configured key, the bindsym command is not executed. The same bug happens if I bind to e.g. a letter key.

According to the discussion here, a similar issue was fixed back in 2018, so this might be a regression. My use case is that I would like to configure a push-to-talk button through sway that mutes the microphone when let go.

k3d3 commented

I get the same thing.

I use bindsym for my Mumble push-to-talk, and my config contains

bindsym --no-repeat --whole-window           BTN_SIDE       exec mumble rpc starttalking
bindsym --no-repeat --whole-window --release BTN_SIDE       exec mumble rpc stoptalking

So it uses the button on the side of my mouse. If I hold that button down, left-click the mouse, then release that side button, Mumble keeps my mic activated.

k3d3 commented

I'm looking through the code, and it appears my problem comes down to how modifiers are handled in bindings.

I don't specify any modifiers with my button press, so if I'm holding down shift when I release the mouse button, the binding does not match.

I believe the issue comes down to this line

if (modifiers ^ binding->modifiers ||
where it checks if the modifier state is exactly the same as the binding.

Is this the right way to do it? Shouldn't we mask instead, so that a binding that accepts shift works if you're holding down both shift and ctrl, for example? Or that any set of modifiers is allowed if the binding doesn't specify any?

k3d3 commented

As far as pushing keys, it appears this is intended i3 behaviour, however releasing keys ignores modifiers.

So combined with #6616, the best way to solve this is to (unfortunately) spam the sway config with every combination of modifier keys that you commonly press. For my mumble PTT use-case:

bindsym --no-repeat --whole-window BTN_SIDE                 exec mumble rpc starttalking
bindsym --no-repeat --whole-window Ctrl+BTN_SIDE            exec mumble rpc starttalking
bindsym --no-repeat --whole-window Shift+BTN_SIDE           exec mumble rpc starttalking
bindsym --no-repeat --whole-window Mod4+BTN_SIDE            exec mumble rpc starttalking
bindsym --no-repeat --whole-window Ctrl+Shift+BTN_SIDE      exec mumble rpc starttalking
bindsym --no-repeat --whole-window Ctrl+Mod4+BTN_SIDE       exec mumble rpc starttalking
bindsym --no-repeat --whole-window Shift+Mod4+BTN_SIDE      exec mumble rpc starttalking
bindsym --no-repeat --whole-window Ctrl+Shift+Mod4+BTN_SIDE exec mumble rpc starttalking

It's not pretty, but it works.

k3d3 commented

@emersion If I were to create a PR that adds a new flag to bindsym, maybe --mask-modifiers, that changes the behaviour to what I had explained before (pressing a button ignores the state of modifiers not mentioned in the binding, i.e. matching a modifier subset), would this be considered for merging?

Unlikely, in general we're not adding new features unless i3 has them.