gdk/surface: Delay gdk_surface_request_motion() requests internally

Those requests are received while dealing with the ::layout frame
clock phase, this has the unintended side effect of making the
frame clock "rewind" to handle ::flush-events again during this
frame, which delays everything and practically halves the frame
rate.

We do intend to make the motion events dispatches on the next frame,
so do this in an idle at a slightly lower priority than layout/draw,
so the ::flush-events phase is actually requested for the next frame.

Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/3264
This commit is contained in:
Carlos Garnacho 2020-12-08 21:33:06 +01:00
parent 47d0b5ad0c
commit 80d4a08e30
2 changed files with 24 additions and 6 deletions

View File

@ -681,6 +681,8 @@ gdk_surface_finalize (GObject *object)
{
GdkSurface *surface = GDK_SURFACE (object);
g_clear_handle_id (&surface->request_motion_id, g_source_remove);
g_signal_handlers_disconnect_by_func (surface->display,
seat_removed_cb, surface);
@ -2408,6 +2410,19 @@ gdk_surface_flush_events (GdkFrameClock *clock,
surface->frame_clock_events_paused = TRUE;
}
static gboolean
request_motion_cb (void *data)
{
GdkSurface *surface = GDK_SURFACE (data);
GdkFrameClock *clock = gdk_surface_get_frame_clock (surface);
if (clock)
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
surface->request_motion_id = 0;
return G_SOURCE_REMOVE;
}
static void
gdk_surface_resume_events (GdkFrameClock *clock,
void *data)
@ -2419,6 +2434,13 @@ gdk_surface_resume_events (GdkFrameClock *clock,
_gdk_display_unpause_events (surface->display);
surface->frame_clock_events_paused = FALSE;
}
if (surface->request_motion)
{
surface->request_motion_id =
g_idle_add_full (GDK_PRIORITY_REDRAW + 1,
request_motion_cb, surface, NULL);
}
}
static void
@ -2912,13 +2934,7 @@ gdk_surface_handle_event (GdkEvent *event)
void
gdk_surface_request_motion (GdkSurface *surface)
{
GdkFrameClock *frame_clock;
surface->request_motion = TRUE;
frame_clock = gdk_surface_get_frame_clock (surface);
if (frame_clock)
gdk_frame_clock_request_phase (frame_clock, GDK_FRAME_CLOCK_PHASE_FLUSH_EVENTS);
}
/**

View File

@ -80,6 +80,8 @@ struct _GdkSurface
guint shortcuts_inhibited : 1;
guint request_motion : 1;
guint request_motion_id;
struct {
GdkGravity surface_anchor;
GdkGravity rect_anchor;