GNOME Bugzilla – Bug 653101
ClutterDragAction jitters randomly on actors with 45° rotation
Last modified: 2021-06-10 11:31:39 UTC
Test program to demonstrate the problem is attached. The issue is that clutter_actor_transform_stage_point is used, but that is not guaranteed to work, and ClutterDragAction doesn't check the return value to see if it worked or not. So, it gets back garbage values, which then are used to move the actor about, causing it to randomly jitter. I have little idea about how to fix this - is it a problem with clutter_actor_transform_stage_point, that it doesn't deal with this case very well, or should ClutterDragAction do something cleverer?
sadly, there isn't much we can do to fix transform_stage_point(): 3D perspective transformations with 2D layers will end up with points that simply cannot be transformed into meaningful values. DragAction should probably just bail out if transform_stage_point() returns FALSE and not emit a drag-motion signal.
Created attachment 190361 [details] program to demonstrate the problem
> DragAction should probably just bail out if transform_stage_point() returns > FALSE and not emit a drag-motion signal. Unfortunately, it looks like when transform_stage_point() fails, it is due to the actor's position, not the co-ordinates we want to transform - so, unless the actor is otherwise moved, all future calls to t_s_p() will also fail for that actor - resulting in the actor getting stuck.
on further investigation, it's not a problem of transform_stage_point(), nor of the moving. when rotating, we apply a modelview transformation when painting, on top of the allocation; dragging around uses the move_by() method, which uses the allocated position of the actor instead. so, there's a slight disconnect between what we're moving and what happens to the actor while being painted. this evidently leads to non-pixel-aligned positioning that manifest as "jumping". I honestly don't know how to fix this without changing the meaning and semantics of how ClutterActor works in ways that are not really compatible.
*** Bug 656894 has been marked as a duplicate of this bug. ***
in bug 656894 it turns out that the effect is greater if the rotation factor is bigger, so it's really the case of "move_by() affects allocation, rotate() affects modelview".
one solution would be to sub-class the DragAction and override the drag_motion() virtual function to not use clutter_actor_move_by(), and instead move the actor by taking into account the transformations. this could probably be done in Clutter itself so we wouldn't have to change the move_by() semantics — though it would probably be more expensive.
*** Bug 681862 has been marked as a duplicate of this bug. ***
ClutterDragAction in master has ::drag-progress, which allows overriding the default handler for ::drag-motion, so at least you can have a work-around for actors that are known to be transformed.
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.