clutter: Only pick on motion or touch update events

Aside from ENTER/LEAVE, there are only two kinds of events that can move
the pointer, motion events and touch update events. Everything else
keeps the pointer at it's current position.

The reason we pick inside _clutter_process_event_details() is that we
want to set the event actor. Now if an event can't move the pointer, it
also can't change the event actor (well, it can subsequently by
triggering changes to the scenegraph, but that's handled elsewhere), so
there's no need to pick a new event actor when we get those events.
Instead, simply reuse the actor that's already associated with the
current input device as the event actor for non MOTION/TOUCH_UPDATE
events.

Events where a device or a touchpoint goes away (like DEVICE_REMOVED or
TOUCH_END/CANCEL) also affect picking, they don't need a repick, but
instead the actor associated with the device/touchpoint needs to be
unassociated. This is ensured by invoking remove_device_for_event() on
those events and will not be affected by this change.

This should improve performance while scrolling quite a bit, since
scroll events come in unthrottled and we now no longer do a repick on
each one of those.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1729>
This commit is contained in:
Jonas Dreßler 2021-02-11 17:34:07 +01:00 committed by Marge Bot
parent d5b69d9cc0
commit 734a185915

View File

@ -1701,8 +1701,18 @@ _clutter_process_event_details (ClutterActor *stage,
break;
}
event->any.source =
update_device_for_event (CLUTTER_STAGE (stage), event, TRUE);
if (event->type == CLUTTER_MOTION)
{
event->any.source =
update_device_for_event (CLUTTER_STAGE (stage), event, TRUE);
}
else
{
event->any.source =
clutter_stage_get_device_actor (CLUTTER_STAGE (stage),
device,
NULL);
}
if (event->any.source == NULL)
break;
@ -1796,8 +1806,18 @@ _clutter_process_event_details (ClutterActor *stage,
break;
}
event->any.source =
update_device_for_event (CLUTTER_STAGE (stage), event, TRUE);
if (event->type == CLUTTER_TOUCH_UPDATE)
{
event->any.source =
update_device_for_event (CLUTTER_STAGE (stage), event, TRUE);
}
else
{
event->any.source =
clutter_stage_get_device_actor (CLUTTER_STAGE (stage),
device,
event->touch.sequence);
}
if (event->any.source == NULL)
break;