wmww / gtk-layer-shell

A library to create panels and other desktop components for Wayland using the Layer Shell protocol
GNU General Public License v3.0
318 stars 16 forks source link

GTK Button stuck if pressed mouse moves to other layer #109

Closed pinselimo closed 3 years ago

pinselimo commented 3 years ago

Problem

If a GTK button is pressed and the mouse moves to another layer while being held pressed the button is not properly released. This does not occur if gtk-layer-shell isn't used. This can be easily tested by removing the specific code from the example.

Examples

I have prepared two videos. Both show the same bug with a very simple example. Note how the button itself is not released by looking at its "motion"/animation. I also added text output whenever the press/release signal is emitted. The lower window outputs the window using gtk-layer-shell the upper the one where this part of the code is removed to create a normal GTK-App.

The easiest way to experience this is by setting "mouse_warping container" on sway and have the button open a new window. This is the example used in the first video:

https://user-images.githubusercontent.com/22834676/127349686-f63b0215-90dd-47f6-8daa-2a898e48c6b1.mp4

However, it should be pointed out that the forkExec function doesn't seem to be the issue. The bug can also be reproduced just by moving the mouse while pressed. This is shown in the second video:

https://user-images.githubusercontent.com/22834676/127347733-4e33862a-e512-42d3-bb1c-e60f34607b9b.mp4

Related Bugs

This problem appears e.g. in Waybar (see https://github.com/Alexays/Waybar/issues/1047) when used with sway/wlroots.

Code

For the used example code see https://github.com/pinselimo/gtk-layer-shell/commit/e5307c7e0b5b4495b0bf404efeaac3626c0dd0ac examples/simple-example.c.

Thanks, Simon

wmww commented 3 years ago

I believe this is a Sway/wlroots bug. I can reproduce in Sway, but not Mir. I ran gtk-layer-demo in wayland-debug, which shows the following:

17.6979 wl_pointer@19.1 enter(serial=105571, surface=wl_surface@33.0, surface_x=614.99609375, surface_y=89.2421875) ↲
    ───┤ 2.0101s ├───
19.7080 wl_pointer@19.1 button(serial=105572, time=98234860, button=272:left, state=1:pressed) ↲
    ───┤ 2.2105s ├───
21.9185 wl_pointer@19.1 leave(serial=105573, surface=wl_surface@33.0) ↲
    ───┤ 8.0415s ├───
29.9600 wl_pointer@19.1 enter(serial=105577, surface=wl_surface@33.0, surface_x=518.55859375, surface_y=1.92578125) ↲
    ───┤ 3.0892s ├───
33.0491 wl_pointer@19.1 button(serial=105578, time=98248202, button=272:left, state=1:pressed) ↲
33.0978 wl_pointer@19.1 button(serial=105579, time=98248302, button=272:left, state=0:released) ↲

There clearly should have been a button released event before the 2nd button pressed (as there is on non-layer shell apps), but it's not being sent. This needs to be fixed in wlroots.