swaywm / sway

i3-compatible Wayland compositor
https://swaywm.org
MIT License
14.57k stars 1.11k forks source link

bindsym to mouse button release doesn't work #5333

Open ChrisLane opened 4 years ago

ChrisLane commented 4 years ago

I've found that I am unable to bind to the release of mouse buttons.

Steps to reproduce:

  1. Bind command to spare mouse button with bindsym --whole-window --release
  2. Refresh config (same after restart too)
  3. Press mouse button that was bound
  4. Nothing happens

Additional info

rileyinman commented 4 years ago

I can confirm that this is an issue, I have a keyboard running QMK firmware that binds extra keys such as volume, brightness, and mouse buttons to a rotary encoder and this is affecting my ability to use these bindings. The events still show up in evtest, but once they reach higher levels they are swallowed and do nothing.

rileyinman commented 4 years ago

@ChrisLane just to make sure this is the same bug I'm having, do the button events show up if you try using xev? I find that's the level at which I stop being able to see them register.

Xyene commented 4 years ago

Just for clarification,

bindsym --whole-window --release BTN_EXTRA notify-send "key released"

is not valid since notify-send is not a Sway command. Since it's external, you need to wrap it in exec:

bindsym --whole-window --release BTN_EXTRA exec notify-send "key released"

Does this fix your issue?

ChrisLane commented 4 years ago

Unfortunately not @Xyene, the notification was only for the example anyway. My first test was binding the button to exec firefox. Nothing I've tried so far works.

Xyene commented 4 years ago

Hmm, nothing immediately comes to mind, and I'm unable to reproduce this locally.

I'd suggest adding some debug prints in trigger_pointer_button_binding, and see if we reach the else branch of if (state == WLR_BUTTON_PRESSED). If we do, then poking into get_active_mouse_binding would be the next step.

If we're not even hitting trigger_pointer_button_binding on release, I'd start from handle_pointer_button and drilling down from there.

joshuarubin commented 4 years ago

I'm running into this issue as well. The mouse release event is detected by both libinput --debug-events and xev. The bindsym without --release also works fine as well.

jonmast commented 4 years ago

I'm also having trouble binding to mouse button release with bindsym --release button2 kill. I added some debug prints as suggested by @Xyene and trigger_pointer_button_binding doesn't seem to get called for the release, but only on the initial click. handler_pointer_button does get called but it's apparently delegating to the seatop_move_tiling handler instead of the default one (I guess it's for the case of this being the start of a drag?).

From there I've sort of lost the thread, I'm not sure how the different handlers were supposed to interact. Hoping someone else will be able to make sense of it, and I'm happy to do additional debugging if I have some pointers on where I should be looking.

Xyene commented 4 years ago

Thanks @jonmast, that's useful information. Indeed, if we're in seatop_move_tiling, then releasing buttons is not wired up to anything. We don't enter (or shouldn't enter) seatop_move_tiling just by dragging though; either the click must have happened on a titlebar, or the modifier key must've been pressed. The relevant code is this chunk (note the && (mod_pressed || on_titlebar) && guard):

https://github.com/swaywm/sway/blob/657587964e5d8e444ac64829a0aab309c25ff50f/sway/input/seatop_default.c#L455-L473

Adding some debug prints to see how we get to seatop_begin_move_tiling in that block of code would be useful.

jonmast commented 4 years ago

@Xyene Thanks for the speedy response! The click was on the titlebar in my case, so nothing surprising in that code block. Are release events not supported there?

If I click inside the window it goes into seatop_down instead of seatop_move_tiling, but that doesn't seem to trigger bindings either.

Xyene commented 4 years ago

OK, I understand what's going on now.

Release bindings are triggered only when the release hits seatop_default. When clicking a window, the press goes through seatop_default (and the press binding gets fired), before starting seatop_down. seatop_down receives the eventual release event and resets to seatop_default, but since the release didn't go through seatop_default, the binding isn't fired.

Pressing and releasing on an empty workspace will trigger the release binding, since we never enter seatop_down in that case -- which is why I wasn't able to reproduce it in https://github.com/swaywm/sway/issues/5333#issuecomment-646762263.

Xyene commented 3 years ago

@jonmast (or anyone else interested), could you try out https://github.com/swaywm/sway/pull/5778 and see if it makes things work as you expect them to?

jonmast commented 3 years ago

@Xyene Thanks for working on this. I tried this out but I don't think it works for my use case, I wanted to bind an event on the titlebar which goes through seatop_move_tiling rather than seatop_down.

I experimented with a --whole-window binding like the original issue of this ticket but that didn't seem to work either. I'm less confident that isn't simply an error on my part though since I'm not entirely sure how it was intended to work.

ChrisLane commented 3 years ago

@Xyene The keybinding works when my cursor is over my sway-bg background but does not when the cursor is over a window.

No errors in my sway log when pressing the keybind.

With swaywm/sway@c523aa623bc5e5b5897c0f337058aa7308871fef and swaywm/wlroots@f0ddcd361ea8b20b0a5da8effc30d8c51540f948

LukasDrsman commented 3 years ago

@Xyene This issue seems to persists in version 1.5-e5913f81 on arch

I tried to do this:

bindsym --whole-window BTN_FORWARD seat - cursor press button1
bindsym --whole-window --release BTN_FORWARD seat - cursor release button1

both wev and libinput debug-events seem to register both BTN_FORWARD events, but the cursor release never seems to occur. I've tried mapping seat - cursor release button1 to a separate key (without --release), which worked flawlessly