GNOME Bugzilla – Bug 681021
ClutterClickAction and ClutterText internal event handling conflict
Last modified: 2021-06-10 11:31:46 UTC
Have a piece of code snippet: let label = new Clutter.Text({ reactive: true, text: "Hello, world!" }); let action = new Clutter.ClickAction(); action.connect('long-press', function(a, b, state) { if (state == Clutter.LongPressState.QUERY) return action.get_button() == 1; if (state == Clutter.LongPressState.ACTIVATE) log('activated'); return false; }); label.add_action(action); Click (press and release immediately, not a long press) on the label. Wait around for a second or two. 'activated' gets logged to the console. WTF?
this is a fun one. a ClutterText will check if it's editable OR selectable in order to handle the CLUTTER_BUTTON_PRESS event; otherwise, it will install a grab, which will lead to the ClickAction's capture on the stage to be ignored, as grabbed actors will skip the capture/bubble phase; which, in turn, will lead the ClickAction to never cancel the long-press timeout. quick workaround: setting the selectable property to false should restore the ClickAction functionality. obviously, the ClickAction should be expected to work only on ClutterText actors that do not allow editing and selection, given that the ClutterText's implementation will interfere with the ClickAction's event handling; we could consider :selectable to only apply if :editable is also TRUE, so the condition for handling event should be (editable AND selectable). this would, though, prevent the ability to position the cursor on a non-selectable text; a more complex approach would be to allow setting the cursor if (editable AND show_cursor) are set, and only allow selection if selectable is also set. I'll come up with a patch.
We install a ClickAction on editable and selectable actors and expect them to work. Is there some way to install a hack to make ClutterText (or actors in general I guess) go through the actions event handling, even when grabbed?
(In reply to comment #2) > We install a ClickAction on editable and selectable actors and expect them to > work. that is not a fair expectation, considering that the ClutterText has a lot of code to handle events. ClutterClickAction cannot guarantee to be able to change the behaviour of actors that do have event handling code, as opposed to other actions stacked together. > Is there some way to install a hack to make ClutterText (or actors in general I > guess) go through the actions event handling, even when grabbed? no, that defeats the purpose and intent of grabbing. it may be possible to remove the pointer grab from ClutterText and use a capture instead, but then we would go in a tricky territory of precedence of signal callbacks.
(In reply to comment #3) > (In reply to comment #2) > > We install a ClickAction on editable and selectable actors and expect them to > > work. > > that is not a fair expectation, considering that the ClutterText has a lot of > code to handle events. ClutterClickAction cannot guarantee to be able to change > the behaviour of actors that do have event handling code, as opposed to other > actions stacked together. I'm not sure what expectation we were supposed to have, other than "ClutterClickAction should just work". Should we write our own click tracking and long press tracking code? > no, that defeats the purpose and intent of grabbing. I thought the purpose was to stop other actors from receiving events, and get events even when outside the actor, not to stop action handling on the same actor.
(In reply to comment #4) > (In reply to comment #3) > > (In reply to comment #2) > > > We install a ClickAction on editable and selectable actors and expect them to > > > work. > > > > that is not a fair expectation, considering that the ClutterText has a lot of > > code to handle events. ClutterClickAction cannot guarantee to be able to change > > the behaviour of actors that do have event handling code, as opposed to other > > actions stacked together. > > I'm not sure what expectation we were supposed to have, other than > "ClutterClickAction should just work". there are constraints on how much an action can "just work". > Should we write our own click tracking > and long press tracking code? when using ClutterText is probably safer to do so, especially if time is of essence. > > no, that defeats the purpose and intent of grabbing. > > I thought the purpose was to stop other actors from receiving events, and get > events even when outside the actor, not to stop action handling on the same > actor. Actions are (currently) implemented opaquely: the event handling code is sealed inside the action itself, and thus uses normal event propagation. even if we switched ClutterAction to be integrated inside the event handling sequence outside of the capture/bubble phase (something I've been playing with for clutter 2.0 as a model for gtk 4.0), grabs would still be what they are now: a way to circumvent the entire event delivery, and just send events to the actor's implementation. ClutterText (like some other actor in St) still uses grabbing; in theory, it should be perfectly fine to switch to a capture, but that introduces other issues. there's also the related matter that ClutterAction is meant to provide behaviour to actors that don't have event handling code inside their own classes; if they do have event handling code, it means that they rely on event handling to happen in specific ways - and that the event handling is, de facto, encoded inside the class itself. at some ultimate point, there is no way to avoid that - unless the actor has any API to forego any event handling (hence the :editable and :selectable properties inside ClutterText).
It's not meant to be generic, no, but is there anything wrong to have clutter_actor_give_event_to_actions (actor, event); to integrate with the action framework? The bug here is not asking for a redesign of the system. It's saying "ClutterClickAction and ClutterText don't mesh well"
Can I get a ping on this?
(In reply to comment #6) > It's not meant to be generic, no, but is there anything wrong to have > clutter_actor_give_event_to_actions (actor, event); to integrate with the > action framework? because: i. it introduces a weird API that works around the documented event flow, i.e. an override to the override. ii. it goes against the implementation of an actor, which can be completely opaque to Clutter. even if we solve the problem of ClutterText, any actor using the grab API will have the same interaction issues. if I introduced an override to grabs, which are already an override to the normal event flow delivery mechanism, what happens to the next bug opened by somebody that really, *really* doesn't want actions to interfere with an actor - for instance, StScrollBar? shall I introduce an override for the override to the override? > The bug here is not asking for a redesign of the system. It's saying > "ClutterClickAction and ClutterText don't mesh well" nothing short of a redesign of the system will fix this. if the creator of an actor decided to use grabs, nothing short of breaking documented behaviour will prevent grabs from overriding event handlers. again: one solution is to switch ClutterText to use a capture on the stage, instead of a grab. this option will have drawbacks, especially if people are actually connecting to button-press/motion/button-release signals externally. I'm tempted to just close this bug as WONTFIX, even though in the future we may be able to let ClutterText play nicely with the actions by reimplementing its event handling code in terms of action themselves, or by changing the action event handling to be able to take precedence over/entirely replace grabs. the current way to avoid a grab is to set the Text.selectable property to false; I don't foresee any other option, least of all generic, to break the grab machinery.
*** Bug 683509 has been marked as a duplicate of this bug. ***
*** Bug 683510 has been marked as a duplicate of this bug. ***
I wonder if the right solution would be to drop the ClutterClickAction on the shell side, and have ClutterText itself handle right click and long-press by emitting a "context-menu" signal.
GNOME is going to shut down bugzilla.gnome.org in favor of gitlab.gnome.org. As part of that, we are mass-closing older open tickets in bugzilla.gnome.org which have not seen updates for a longer time (resources are unfortunately quite limited so not every ticket can get handled). If you can still reproduce the situation described in this ticket in a recent and supported software version of clutter, then please follow https://wiki.gnome.org/GettingInTouch/BugReportingGuidelines and create a ticket at https://gitlab.gnome.org/GNOME/clutter/-/issues/ Thank you for your understanding and your help.