[gtk/matthiasc/surface-state-rework: 20/80] Pass the layout signal via GdkSurface to GtkRoot




commit 2d5d486a09e98bc1eaf7abcd2bb7aed528a55b4b
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Tue Nov 24 22:02:53 2020 +0100

    Pass the layout signal via GdkSurface to GtkRoot
    
    Don't have GtkRoot listen directly to the layout signal on the frame
    clock, but let it pass through GdkSurface. This will allow GdkSurface to
    be more involved in the layout phase.

 gdk/gdksurface.c       | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 gdk/gdksurface.h       |  3 +++
 gtk/gtkroot.c          | 21 ++++++++++++++-------
 gtk/gtkwidget.c        |  2 +-
 gtk/gtkwidgetprivate.h |  2 ++
 5 files changed, 66 insertions(+), 8 deletions(-)
---
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index f5f4a5790d..226a7c7e53 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -1370,6 +1370,45 @@ gdk_surface_process_updates_internal (GdkSurface *surface)
   g_object_unref (surface);
 }
 
+static void
+gdk_surface_layout_on_clock (GdkFrameClock *clock,
+                             void          *data)
+{
+  GdkSurface *surface = GDK_SURFACE (data);
+
+  g_return_if_fail (GDK_IS_SURFACE (surface));
+
+  if (GDK_SURFACE_DESTROYED (surface))
+    return;
+
+  if (!GDK_SURFACE_IS_MAPPED (surface))
+    return;
+
+  if (surface->update_freeze_count)
+    return;
+
+  g_signal_emit (surface, signals[LAYOUT], 0, surface->width, surface->height);
+}
+
+void
+gdk_surface_request_layout (GdkSurface *surface)
+{
+  GdkFrameClock *frame_clock;
+
+  if (surface->update_freeze_count ||
+      gdk_surface_is_toplevel_frozen (surface))
+    {
+      surface->pending_phases |= GDK_FRAME_CLOCK_PHASE_LAYOUT;
+      return;
+    }
+
+  frame_clock = gdk_surface_get_frame_clock (surface);
+  g_return_if_fail (frame_clock);
+
+  gdk_frame_clock_request_phase (frame_clock,
+                                 GDK_FRAME_CLOCK_PHASE_LAYOUT);
+}
+
 static void
 gdk_surface_paint_on_clock (GdkFrameClock *clock,
                             void          *data)
@@ -2451,6 +2490,10 @@ gdk_surface_set_frame_clock (GdkSurface     *surface,
                         "resume-events",
                         G_CALLBACK (gdk_surface_resume_events),
                         surface);
+      g_signal_connect (G_OBJECT (clock),
+                        "layout",
+                        G_CALLBACK (gdk_surface_layout_on_clock),
+                        surface);
       g_signal_connect (G_OBJECT (clock),
                         "paint",
                         G_CALLBACK (gdk_surface_paint_on_clock),
@@ -2471,6 +2514,9 @@ gdk_surface_set_frame_clock (GdkSurface     *surface,
       g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
                                             G_CALLBACK (gdk_surface_resume_events),
                                             surface);
+      g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
+                                            G_CALLBACK (gdk_surface_layout_on_clock),
+                                            surface);
       g_signal_handlers_disconnect_by_func (G_OBJECT (surface->frame_clock),
                                             G_CALLBACK (gdk_surface_paint_on_clock),
                                             surface);
diff --git a/gdk/gdksurface.h b/gdk/gdksurface.h
index 6b2cfcd03b..4c47fe659b 100644
--- a/gdk/gdksurface.h
+++ b/gdk/gdksurface.h
@@ -118,6 +118,9 @@ void          gdk_surface_beep            (GdkSurface       *surface);
 GDK_AVAILABLE_IN_ALL
 void       gdk_surface_queue_render       (GdkSurface       *surface);
 
+GDK_AVAILABLE_IN_ALL
+void       gdk_surface_request_layout     (GdkSurface       *surface);
+
 GDK_AVAILABLE_IN_ALL
 GdkFrameClock* gdk_surface_get_frame_clock      (GdkSurface     *surface);
 
diff --git a/gtk/gtkroot.c b/gtk/gtkroot.c
index a480173695..6bdf1b74a1 100644
--- a/gtk/gtkroot.c
+++ b/gtk/gtkroot.c
@@ -195,8 +195,10 @@ gtk_root_after_update_cb (GdkFrameClock *clock,
 }
 
 static void
-gtk_root_layout_cb (GdkFrameClock *clock,
-                    GtkRoot       *self)
+gtk_root_layout_cb (GdkSurface *surface,
+                    int         width,
+                    int         height,
+                    GtkRoot    *self)
 {
   GtkWidget *widget = GTK_WIDGET (self);
 
@@ -231,19 +233,22 @@ gtk_root_layout_cb (GdkFrameClock *clock,
 
   if (gtk_root_needs_layout (self))
     {
-      gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_UPDATE);
-      gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
+      gdk_frame_clock_request_phase (gdk_surface_get_frame_clock (surface),
+                                     GDK_FRAME_CLOCK_PHASE_UPDATE);
+      gdk_surface_request_layout (surface);
     }
 }
 
 void
 gtk_root_start_layout (GtkRoot *self)
 {
+  GdkSurface *surface;
   GdkFrameClock *clock;
 
   if (!gtk_root_needs_layout (self))
     return;
 
+  surface = gtk_widget_get_surface (GTK_WIDGET (self));
   clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
   if (clock == NULL)
     return;
@@ -260,19 +265,20 @@ gtk_root_start_layout (GtkRoot *self)
                           GINT_TO_POINTER (after_update_handler));
 
       layout_handler =
-        g_signal_connect (clock, "layout",
+        g_signal_connect (surface, "layout",
                           G_CALLBACK (gtk_root_layout_cb), self);
       g_object_set_qdata (G_OBJECT (self), quark_layout_handler,
                           GINT_TO_POINTER (layout_handler));
     }
 
   gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_UPDATE);
-  gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
+  gdk_surface_request_layout (surface);
 }
 
 void
 gtk_root_stop_layout (GtkRoot *self)
 {
+  GdkSurface *surface;
   GdkFrameClock *clock;
   guint layout_handler;
   guint after_update_handler;
@@ -287,8 +293,9 @@ gtk_root_stop_layout (GtkRoot *self)
   if (layout_handler == 0)
     return;
 
+  surface = gtk_widget_get_surface (GTK_WIDGET (self));
   clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
-  g_signal_handler_disconnect (clock, layout_handler);
+  g_signal_handler_disconnect (surface, layout_handler);
   g_signal_handler_disconnect (clock, after_update_handler);
   g_object_set_qdata (G_OBJECT (self), quark_layout_handler, NULL);
   g_object_set_qdata (G_OBJECT (self), quark_after_update_handler, NULL);
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index f649acfe74..111a382da5 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -3251,7 +3251,7 @@ gtk_widget_remove_surface_transform_changed_callback (GtkWidget *widget,
     }
 }
 
-static GdkSurface *
+GdkSurface *
 gtk_widget_get_surface (GtkWidget *widget)
 {
   GtkNative *native = gtk_widget_get_native (widget);
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index a79ee938da..667df882ce 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -228,6 +228,8 @@ void         gtk_widget_ensure_resize       (GtkWidget *widget);
 void         gtk_widget_ensure_allocate     (GtkWidget *widget);
 void          _gtk_widget_scale_changed     (GtkWidget *widget);
 
+GdkSurface * gtk_widget_get_surface         (GtkWidget *widget);
+
 void         gtk_widget_render              (GtkWidget            *widget,
                                              GdkSurface           *surface,
                                              const cairo_region_t *region);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]