[gtk: 18/88] gtk/root: Validate css node after update




commit 0c8d97e3f7b73f02b0376d1a7723ef7aba732efb
Author: Jonas Ådahl <jadahl gmail com>
Date:   Tue Nov 24 18:33:05 2020 +0100

    gtk/root: Validate css node after update
    
    It should happen before layout, but after the animation tick, thus after
    the update.

 gdk/gdksurface.c | 26 ++++++++++++++++++++
 gtk/gtkroot.c    | 72 +++++++++++++++++++++++++++++++++++++++-----------------
 2 files changed, 77 insertions(+), 21 deletions(-)
---
diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c
index 0d36a58a03..6cd7686bb2 100644
--- a/gdk/gdksurface.c
+++ b/gdk/gdksurface.c
@@ -78,6 +78,7 @@
 enum {
   POPUP_LAYOUT_CHANGED,
   SIZE_CHANGED,
+  LAYOUT,
   RENDER,
   EVENT,
   ENTER_MONITOR,
@@ -571,6 +572,31 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
                   G_TYPE_INT,
                   G_TYPE_INT);
 
+  /**
+   * GdkSurface::layout:
+   * @surface: the #GdkSurface
+   * @width: the current width
+   * @height: the current height
+   *
+   * Emitted when the size of @surface is changed, or when relayout should
+   * be performed.
+   *
+   * Surface size is reported in ”application pixels”, not
+   * ”device pixels” (see gdk_surface_get_scale_factor()).
+   */
+  signals[LAYOUT] =
+    g_signal_new (g_intern_static_string ("layout"),
+                  G_OBJECT_CLASS_TYPE (object_class),
+                  G_SIGNAL_RUN_FIRST,
+                  0,
+                  NULL,
+                  NULL,
+                  NULL,
+                  G_TYPE_NONE,
+                  2,
+                  G_TYPE_INT,
+                  G_TYPE_INT);
+
   /**
    * GdkSurface::render:
    * @surface: the #GdkSurface
diff --git a/gtk/gtkroot.c b/gtk/gtkroot.c
index 33000c28fc..a480173695 100644
--- a/gtk/gtkroot.c
+++ b/gtk/gtkroot.c
@@ -44,7 +44,8 @@
  */
 
 static GQuark quark_restyle_pending;
-static GQuark quark_resize_handler;
+static GQuark quark_layout_handler;
+static GQuark quark_after_update_handler;
 
 G_DEFINE_INTERFACE_WITH_CODE (GtkRoot, gtk_root, GTK_TYPE_WIDGET,
                               g_type_interface_add_prerequisite (g_define_type_id, GTK_TYPE_NATIVE))
@@ -83,7 +84,8 @@ gtk_root_default_init (GtkRootInterface *iface)
   iface->set_focus = gtk_root_default_set_focus;
 
   quark_restyle_pending = g_quark_from_static_string ("gtk-root-restyle-pending");
-  quark_resize_handler = g_quark_from_static_string ("gtk-root-resize-handler");
+  quark_layout_handler = g_quark_from_static_string ("gtk-root-layout-handler");
+  quark_after_update_handler = g_quark_from_static_string ("gtk-root-after-update-handler");
 }
 
 /**
@@ -171,8 +173,8 @@ gtk_root_needs_layout (GtkRoot *self)
 }
 
 static void
-gtk_root_layout_cb (GdkFrameClock *clock,
-                    GtkRoot       *self)
+gtk_root_after_update_cb (GdkFrameClock *clock,
+                          GtkRoot       *self)
 {
   GtkWidget *widget = GTK_WIDGET (self);
 
@@ -188,9 +190,17 @@ gtk_root_layout_cb (GdkFrameClock *clock,
    */
   if (g_object_get_qdata (G_OBJECT (self), quark_restyle_pending))
     {
-      g_object_set_qdata (G_OBJECT (self), quark_restyle_pending, NULL);
       gtk_css_node_validate (gtk_widget_get_css_node (widget));
     }
+}
+
+static void
+gtk_root_layout_cb (GdkFrameClock *clock,
+                    GtkRoot       *self)
+{
+  GtkWidget *widget = GTK_WIDGET (self);
+
+  g_object_set_qdata (G_OBJECT (self), quark_restyle_pending, NULL);
 
   /* we may be invoked with a container_resize_queue of NULL, because
    * queue_resize could have been adding an extra idle function while
@@ -219,20 +229,17 @@ gtk_root_layout_cb (GdkFrameClock *clock,
         }
     }
 
-  if (!gtk_root_needs_layout (self))
-    gtk_root_stop_layout (self);
-  else
-    gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
+  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);
+    }
 }
 
 void
 gtk_root_start_layout (GtkRoot *self)
 {
   GdkFrameClock *clock;
-  guint resize_handler;
-
-  if (g_object_get_qdata (G_OBJECT (self), quark_resize_handler))
-    return;
 
   if (!gtk_root_needs_layout (self))
     return;
@@ -241,10 +248,25 @@ gtk_root_start_layout (GtkRoot *self)
   if (clock == NULL)
     return;
 
-  resize_handler = g_signal_connect (clock, "layout",
-                                     G_CALLBACK (gtk_root_layout_cb), self);
-  g_object_set_qdata (G_OBJECT (self), quark_resize_handler, GINT_TO_POINTER (resize_handler));
+  if (!g_object_get_qdata (G_OBJECT (self), quark_layout_handler))
+    {
+      guint layout_handler;
+      guint after_update_handler;
+
+      after_update_handler =
+        g_signal_connect_after (clock, "update",
+                                G_CALLBACK (gtk_root_after_update_cb), self);
+      g_object_set_qdata (G_OBJECT (self), quark_after_update_handler,
+                          GINT_TO_POINTER (after_update_handler));
+
+      layout_handler =
+        g_signal_connect (clock, "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);
 }
 
@@ -252,16 +274,24 @@ void
 gtk_root_stop_layout (GtkRoot *self)
 {
   GdkFrameClock *clock;
-  guint resize_handler;
+  guint layout_handler;
+  guint after_update_handler;
 
-  resize_handler = GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (self), quark_resize_handler));
+  layout_handler =
+    GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (self),
+                                         quark_layout_handler));
+  after_update_handler =
+    GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (self),
+                                         quark_after_update_handler));
 
-  if (resize_handler == 0)
+  if (layout_handler == 0)
     return;
 
   clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
-  g_signal_handler_disconnect (clock, resize_handler);
-  g_object_set_qdata (G_OBJECT (self), quark_resize_handler, NULL);
+  g_signal_handler_disconnect (clock, 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);
 }
 
 void


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