[gtk/wip/carlosg/for-master: 2/3] gdk/surface: Delay gdk_surface_request_motion() requests internally
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/carlosg/for-master: 2/3] gdk/surface: Delay gdk_surface_request_motion() requests internally
- Date: Tue, 8 Dec 2020 22:27:56 +0000 (UTC)
commit 80d4a08e306e36486e45542af0cdc58f5ad21e45
Author: Carlos Garnacho <carlosg gnome org>
Date: Tue Dec 8 21:33:06 2020 +0100
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
gdk/gdksurface.c | 28 ++++++++++++++++++++++------
gdk/gdksurfaceprivate.h | 2 ++
2 files changed, 24 insertions(+), 6 deletions(-)
---
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index 012864479a..b6f739c5c0 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -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);
}
/**
diff --git a/gdk/gdksurfaceprivate.h b/gdk/gdksurfaceprivate.h
index 27a3966fe7..2126371853 100644
--- a/gdk/gdksurfaceprivate.h
+++ b/gdk/gdksurfaceprivate.h
@@ -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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]