Skip to content

clutter/stage: Don't set implicit_grab_cancelled to TRUE if there are none

Jonas Dreßler requested to merge verdre/mutter:fix-2700 into main

The assertion for !implicit_grab_cancelled in the grab_actor == old_grab_actor case of clutter_stage_notify_grab_on_pointer_entry() is meant to do a simple sanity-check to ensure the grab machinery is working as intended: During a seat grab, all input gets delivered to the tree inside the grab, and all implicit grabs outside of that tree are cancelled.

When a new seat grab on the same actor as the existing one happens, we run through the cancellation machinery for implicit grabs anyway, so we might as well check that the assumption mentioned above holds true: By asserting that no implicit grabs were cancelled, we know that no implicit grabs exist outside of the existing seat grab tree.

This assertion is slightly over-eager though due to the way we set implicit_grab_cancelled: We initialize it to TRUE in the entry->press_count > 0 case and then only set it to FALSE once we find an implicit grab that may remain active. If there are no implicit grabs though (while entry->press_count is still >0), we never set implicit_grab_cancelled to FALSE, triggering the assertion in question even though no implicit grabs got cancelled.

There's two possible solutions for this: Either dropping the assertion, or refactoring the way we set implicit_grab_cancelled so that it's no longer set to TRUE when there are no implicit grabs. This commit implements the latter.

Closes: #2700 (closed)

Fixes: debbd88f ("clutter/stage: Cancel parts of implicit grabs when ClutterGrabs happen")

Edited by Jonas Dreßler

Merge request reports