GTK3 becoming unresponsive to mouse input events without frame callbacks
This is an issue that first appeared in Firefox (https://bugzilla.mozilla.org/show_bug.cgi?id=1615098), but I just reproduced this with gnome settings on Fedora 32: in certain cases, GTK apps can get into a state where they do not respond to mouse input events (like scrolling), until the compositor sends the next frame callback. Input events still get processed, as for example scroll events get honoured - as soon as something triggers the compositor to render a new frame, thus sending frame callbacks.
Unfortunately I haven't found good steps to reproduce - apart from Firefox on Wayland, where this happens a lot in fullscreen mode (although less in Fedora 32, as it already has a patch somewhat circumventing that). This is due to some optimizations in Mutter, preventing frame callbacks to get send to surface used for events in FF, as it's hidden behind another surface for content.
Edit: I now found steps to reproduce this reliably on my local mashine:
- open gnome settings
- select the keyboard shortcuts tab
- resize the window so its bigger than the screen, thus covers the whole area as if maximized, but goes off the screen in all directions
- quickly scroll up and down
Observed behavior:
- scrolling gets stuck and mouse hover effects do not happen any more
- as soon as a frame redraw is triggered (e.g. by hovering the clock in the shell), scroll events get honoured
Notes:
- this happens regardless of mutter!918 (merged) - in fact it does not appear to have anything to do with culling in Mutter, which I suspected earlier. It also happens when all culling optimizations are completely disabled. I suspected it because the before mentioned MR made the firefox bug happen much more. But apparently the culling improvements just unveiled this bug to happen more easily
- The bug can even happen when resizing the window - in fact, as soon as part of the window are off screen the bug starts to appear
Wild guess: certain events block the gtk main loop until the next frame callback - and if the compositor does not issue any because there was no new frame to draw, the app gets stuck.