Skip to content

Grabs (Pt. 5)

Carlos Garnacho requested to merge carlosg/mutter:wip/grabs-pt5 into main

(currently includes !3269 (merged))

In this MR, the Wayland pointer and keyboard grab mechanisms get rewritten over an unified MetaWaylandEventInterface featuring more device-agnostic interfaces, both for focus management and press/motion/release conversion. These event interfaces are managed by a MetaWaylandInput object (that becomes the main "wayland event handler") and are designed to be stackable by default, with the default MetaWaylandSeat handler at the bottom. This is meant to naturally handle all the existing possible combinations of Wayland "grabs":

  • DnD from popups
  • pointer constraints in popups
  • pointer constraints and shortcut inhibition (planned to be reimplemented over this, sharing code with xwayland keyboard grabs)
  • DnD while constrained
  • profit?

The topmost event handler is always effective, and is in control about when to chain up its logic to the parent implementation, in picking or event handling. This allows being able to e.g. delegate handling of unhandled devices, or rely on default picking logic, without direct access to MetaWaylandPointer/etc interfaces.

The one vtable method where chaining up is mandatory and not optional is focus(), the caller is however allowed to change the focused surface to NULL. This allows both:

  • Stacking of "friendly" event interfaces without causing focus changes (e.g. a grabbing xdg_popup should not trigger wl_pointer.leave + enter while being created)
  • Coherent focus changes on event interfaces that swap the outgoing Wayland interfaces (e.g. wl_pointer.leave/tool.proximity_out/touch.cancel before wl_data_device.enter)

And this focusing logic also works face to the outer layers. This wayland mechanism is integrated with ClutterGrab in both ways:

  • Grabs happening outside of Wayland will unfocus all ongoing input, and grabs disappearing will bring it back.
  • Event interfaces may optionally request a grab, so that other interaction is prevented while the Wayland grab is ongoing. This is used for:
    • Popups
    • DnD

Before all of this, a number of small fixes and refactors to have things fall in place. And after, some sweet sweet cleanups (bypass_clutter, bypass_wayland, begone).

Altogether, this fixes a number of longstanding bugs that is probably worth hunting around for dups in gitlab:

  • DnD from popups works
  • DnD with tablets and touch works (pending GTK fixes gtk!6608 (merged))
  • Dismissing popups with tablets and touch if clicking outside the app works
  • Pointer "leaves" Clutter widgetry correctly too when hidden
  • DnD becomes naturally motion compressed, with less chances to kill unresponsive clients with 1000Hz mice.
  • Probably others I forgot

See also gnome-shell!3028 (merged)

Edited by Robert Mader

Merge request reports