wayland: Simplify wl_touch.frame handling

We want to coalesce multiple touch events into the same wl_touch.frame
event. Instead of poking internals to peek the touch events (and their
slots) coming at us before we handle them, simplify things by queueing
the event at a slightly lower priority than events, so we are ensured
to handle all pending input events before sending the event.

If there's no pending events, we can just send the frame event. As it
doesn't make sense to hold any longer.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1486
This commit is contained in:
Carlos Garnacho 2020-05-06 13:26:15 +02:00 committed by Jonas Ådahl
parent 7e0d80be39
commit 3a65ee7c6a
2 changed files with 23 additions and 40 deletions

View File

@ -401,35 +401,34 @@ touch_send_frame_event (MetaWaylandTouch *touch)
g_list_free (surfaces); g_list_free (surfaces);
} }
static void static gboolean
check_send_frame_event (MetaWaylandTouch *touch, queue_frame_event_cb (MetaWaylandTouch *touch)
const ClutterEvent *event)
{ {
gboolean send_frame_event;
#ifdef HAVE_NATIVE_BACKEND
MetaBackend *backend = meta_get_backend ();
ClutterEventSequence *sequence;
gint32 slot;
if (META_IS_BACKEND_NATIVE (backend))
{
sequence = clutter_event_get_event_sequence (event);
slot = meta_event_native_sequence_get_slot (sequence);
touch->frame_slots &= ~(1 << slot);
if (touch->frame_slots == 0)
send_frame_event = TRUE;
else
send_frame_event = FALSE;
}
else
#endif /* HAVE_NATIVE_BACKEND */
{
send_frame_event = TRUE;
}
if (send_frame_event)
touch_send_frame_event (touch); touch_send_frame_event (touch);
touch->queued_frame_id = 0;
return G_SOURCE_REMOVE;
}
static void
send_or_queue_frame_event (MetaWaylandTouch *touch)
{
if (clutter_events_pending ())
{
if (touch->queued_frame_id == 0)
{
touch->queued_frame_id =
g_idle_add_full (CLUTTER_PRIORITY_EVENTS + 1,
(GSourceFunc) queue_frame_event_cb,
touch, NULL);
}
}
else
{
/* There's no more events */
g_clear_handle_id (&touch->queued_frame_id, g_source_remove);
touch_send_frame_event (touch);
}
} }
gboolean gboolean
@ -454,7 +453,7 @@ meta_wayland_touch_handle_event (MetaWaylandTouch *touch,
return FALSE; return FALSE;
} }
check_send_frame_event (touch, event); send_or_queue_frame_event (touch);
return FALSE; return FALSE;
} }
@ -520,21 +519,6 @@ evdev_filter_func (struct libinput_event *event,
switch (libinput_event_get_type (event)) switch (libinput_event_get_type (event))
{ {
case LIBINPUT_EVENT_TOUCH_DOWN:
case LIBINPUT_EVENT_TOUCH_UP:
case LIBINPUT_EVENT_TOUCH_MOTION: {
struct libinput_event_touch *touch_event;
int32_t slot;
touch_event = libinput_event_get_touch_event (event);
slot = libinput_event_touch_get_slot (touch_event);
/* XXX: Could theoretically overflow, 64 slots should be
* enough for most hw/usecases though.
*/
touch->frame_slots |= (1 << slot);
break;
}
case LIBINPUT_EVENT_TOUCH_CANCEL: case LIBINPUT_EVENT_TOUCH_CANCEL:
/* Clutter translates this into individual CLUTTER_TOUCH_CANCEL events, /* Clutter translates this into individual CLUTTER_TOUCH_CANCEL events,
* which are not so useful when sending a global signal as the protocol * which are not so useful when sending a global signal as the protocol

View File

@ -41,10 +41,9 @@ struct _MetaWaylandTouch
struct wl_list resource_list; struct wl_list resource_list;
guint queued_frame_id;
GHashTable *touch_surfaces; /* HT of MetaWaylandSurface->MetaWaylandTouchSurface */ GHashTable *touch_surfaces; /* HT of MetaWaylandSurface->MetaWaylandTouchSurface */
GHashTable *touches; /* HT of sequence->MetaWaylandTouchInfo */ GHashTable *touches; /* HT of sequence->MetaWaylandTouchInfo */
guint64 frame_slots;
}; };
void meta_wayland_touch_enable (MetaWaylandTouch *touch); void meta_wayland_touch_enable (MetaWaylandTouch *touch);