[gtk/container-focus-cleanup] wip: move the layout callbacks to gtkwindow.c



commit 8b2c103c2ecfcdffbda7158c62ad8adee66ded58
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Apr 20 16:12:33 2020 -0400

    wip: move the layout callbacks to gtkwindow.c
    
    This keep toplevel-only machinery out of gtkwidget.c,
    and avoids some GTK_IS_ROOT special-casing in there.

 gtk/gtkcsswidgetnode.c |   7 ++-
 gtk/gtkwidget.c        | 119 +------------------------------------------------
 gtk/gtkwidgetprivate.h |   9 ----
 gtk/gtkwindow.c        | 108 ++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkwindowprivate.h |   5 +++
 5 files changed, 118 insertions(+), 130 deletions(-)
---
diff --git a/gtk/gtkcsswidgetnode.c b/gtk/gtkcsswidgetnode.c
index f32bdc8453..b8aaf45302 100644
--- a/gtk/gtkcsswidgetnode.c
+++ b/gtk/gtkcsswidgetnode.c
@@ -24,6 +24,7 @@
 #include "gtksettingsprivate.h"
 #include "gtkstylecontextprivate.h"
 #include "gtkwidgetprivate.h"
+#include "gtkwindowprivate.h"
 
 G_DEFINE_TYPE (GtkCssWidgetNode, gtk_css_widget_node, GTK_TYPE_CSS_NODE)
 
@@ -45,7 +46,7 @@ gtk_css_widget_node_queue_callback (GtkWidget     *widget,
   GtkCssNode *node = user_data;
 
   gtk_css_node_invalidate_frame_clock (node, TRUE);
-  gtk_widget_queue_restyle (widget);
+  gtk_window_queue_restyle (GTK_WINDOW (widget));
 
   return G_SOURCE_CONTINUE;
 }
@@ -55,9 +56,7 @@ gtk_css_widget_node_queue_validate (GtkCssNode *node)
 {
   GtkCssWidgetNode *widget_node = GTK_CSS_WIDGET_NODE (node);
 
-  if (widget_node->widget &&
-      GTK_IS_ROOT (widget_node->widget) &&
-      GTK_IS_CONTAINER (widget_node->widget))
+  if (widget_node->widget && GTK_IS_ROOT (widget_node->widget))
     widget_node->validate_cb_id = gtk_widget_add_tick_callback (widget_node->widget,
                                                                 gtk_css_widget_node_queue_callback,
                                                                 node,
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index d101e6ec75..2801c96e9a 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -2615,9 +2615,6 @@ gtk_widget_destroy (GtkWidget *widget)
 
   g_return_if_fail (GTK_IS_WIDGET (widget));
 
-  if (priv->restyle_pending)
-    priv->restyle_pending = FALSE;
-
   if (!priv->in_destruction)
     g_object_run_dispose (G_OBJECT (widget));
 }
@@ -2887,112 +2884,6 @@ gtk_widget_unmap (GtkWidget *widget)
     }
 }
 
-static gboolean
-gtk_widget_needs_idle_sizer (GtkWidget *widget)
-{
-  GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
-
-  if (priv->restyle_pending)
-    return TRUE;
-
-  return gtk_widget_needs_allocate (widget);
-}
-
-static void
-gtk_widget_idle_sizer (GdkFrameClock *clock,
-                       GtkWidget     *widget)
-{
-  GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
-
-  /* We validate the style contexts in a single loop before even trying
-   * to handle resizes instead of doing validations inline.
-   * This is mostly necessary for compatibility reasons with old code,
-   * because both css_changed and size_allocate functions often change
-   * styles and so could cause infinite loops in this function.
-   *
-   * It's important to note that even an invalid style context returns
-   * sane values. So the result of an invalid style context will never be
-   * a program crash, but only a wrong layout or rendering.
-   */
-  if (priv->restyle_pending)
-    {
-      priv->restyle_pending = FALSE;
-      gtk_css_node_validate (gtk_widget_get_css_node (widget));
-    }
-
-  /* we may be invoked with a container_resize_queue of NULL, because
-   * queue_resize could have been adding an extra idle function while
-   * the queue still got processed. we better just ignore such case
-   * than trying to explicitly work around them with some extra flags,
-   * since it doesn't cause any actual harm.
-   */
-  if (gtk_widget_needs_allocate (widget))
-    {
-      if (GTK_IS_ROOT (widget))
-        gtk_native_check_resize (GTK_NATIVE (widget));
-      else
-        g_warning ("gtk_widget_idle_sizer() called on a non-native non-window");
-    }
-
-  if (!gtk_widget_needs_idle_sizer (widget))
-    {
-      gtk_widget_stop_idle_sizer (widget);
-    }
-  else
-    {
-      gdk_frame_clock_request_phase (clock,
-                                     GDK_FRAME_CLOCK_PHASE_LAYOUT);
-    }
-}
-
-void
-gtk_widget_start_idle_sizer (GtkWidget *widget)
-{
-  GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
-  GdkFrameClock *clock;
-
-  if (priv->resize_handler != 0)
-    return;
-
-  if (!gtk_widget_needs_idle_sizer (widget))
-    return;
-
-  clock = gtk_widget_get_frame_clock (widget);
-  if (clock == NULL)
-    return;
-  
-  priv->resize_handler = g_signal_connect (clock, "layout",
-                                           G_CALLBACK (gtk_widget_idle_sizer), widget);
-  gdk_frame_clock_request_phase (clock,
-                                 GDK_FRAME_CLOCK_PHASE_LAYOUT);
-}
-
-void
-gtk_widget_stop_idle_sizer (GtkWidget *widget)
-{
-  GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
-
-  if (priv->resize_handler == 0)
-    return;
-
-  g_signal_handler_disconnect (gtk_widget_get_frame_clock (widget),
-                               priv->resize_handler);
-  priv->resize_handler = 0;
-}
-
-void
-gtk_widget_queue_restyle (GtkWidget *widget)
-{
-  GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
-
-  if (priv->restyle_pending)
-    return;
-
-  priv->restyle_pending = TRUE;
-  gtk_widget_start_idle_sizer (widget);
-}
-
-
 typedef struct _GtkTickCallbackInfo GtkTickCallbackInfo;
 
 struct _GtkTickCallbackInfo
@@ -3212,9 +3103,6 @@ gtk_widget_connect_frame_clock (GtkWidget *widget)
   GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
   GdkFrameClock *frame_clock;
 
-  if (GTK_IS_ROOT (widget))
-    gtk_widget_start_idle_sizer (widget);
-
   frame_clock = gtk_widget_get_frame_clock (widget);
 
   if (priv->tick_callbacks != NULL && !priv->clock_tick_id)
@@ -3233,9 +3121,6 @@ gtk_widget_disconnect_frame_clock (GtkWidget *widget)
 {
   GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
 
-  if (GTK_IS_ROOT (widget))
-    gtk_widget_stop_idle_sizer (widget);
-
   gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE);
 
   if (priv->clock_tick_id)
@@ -10552,9 +10437,9 @@ gtk_widget_set_alloc_needed (GtkWidget *widget)
       if (!priv->visible)
         break;
 
-      if (GTK_IS_ROOT (widget))
+      if (GTK_IS_WINDOW (widget))
         {
-          gtk_widget_start_idle_sizer (widget);
+          gtk_window_start_layout (GTK_WINDOW (widget));
           break;
         }
 
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index 9133db9edb..db969f4cb2 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -111,8 +111,6 @@ struct _GtkWidgetPrivate
   guint   halign              : 4;
   guint   valign              : 4;
 
-  guint   restyle_pending     : 1;
-
   GtkOverflow overflow;
   guint8 alpha;
   guint8 user_alpha;
@@ -130,8 +128,6 @@ struct _GtkWidgetPrivate
   guint clock_tick_id;
   GList *tick_callbacks;
 
-  guint resize_handler;
-
   /* Surface relative transform updates callbacks */
   GtkWidgetSurfaceTransformData *surface_transform_data;
 
@@ -365,11 +361,6 @@ guint             gtk_widget_add_surface_transform_changed_callback (GtkWidget
 void              gtk_widget_remove_surface_transform_changed_callback (GtkWidget *widget,
                                                                         guint      id);
 
-/* resize machinery */
-void     gtk_widget_queue_restyle    (GtkWidget        *widget);
-void     gtk_widget_stop_idle_sizer  (GtkWidget        *widget);
-void     gtk_widget_start_idle_sizer (GtkWidget        *widget);
-
 /* focus vfuncs for non-focusable non-containers */
 gboolean gtk_widget_grab_focus_none  (GtkWidget        *widget);
 gboolean gtk_widget_focus_none       (GtkWidget        *widget,
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 0b5874931a..c02742e055 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -238,8 +238,12 @@ typedef struct
   guint    hide_on_close             : 1;
   guint    in_emit_close_request     : 1;
 
+  guint    restyle_pending           : 1;
+
   GdkSurfaceTypeHint type_hint;
 
+  guint resize_handler;
+
   GtkGesture *click_gesture;
   GtkGesture *drag_gesture;
   GtkGesture *bubble_drag_gesture;
@@ -3996,6 +4000,9 @@ gtk_window_destroy (GtkWidget *widget)
   if (priv->group)
     gtk_window_group_remove_window (priv->group, window);
 
+  if (priv->restyle_pending)
+    priv->restyle_pending = FALSE;
+
   GTK_WIDGET_CLASS (gtk_window_parent_class)->destroy (widget);
 }
 
@@ -4797,6 +4804,8 @@ gtk_window_realize (GtkWidget *widget)
 
   GTK_WIDGET_CLASS (gtk_window_parent_class)->realize (widget);
 
+  gtk_window_start_layout (window);
+
   if (priv->renderer == NULL)
     priv->renderer = gsk_renderer_new_for_surface (surface);
 
@@ -4912,6 +4921,8 @@ gtk_window_unrealize (GtkWidget *widget)
   g_signal_handlers_disconnect_by_func (surface, surface_render, widget);
   g_signal_handlers_disconnect_by_func (surface, surface_event, widget);
 
+  gtk_window_stop_layout (window);
+
   GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
 
   gdk_surface_set_widget (surface, NULL);
@@ -8007,3 +8018,100 @@ gtk_window_maybe_update_cursor (GtkWindow *window,
         break;
     }
 }
+
+static gboolean
+gtk_window_needs_layout (GtkWindow *window)
+{
+  GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
+
+  if (priv->restyle_pending)
+    return TRUE;
+
+  return gtk_widget_needs_allocate (GTK_WIDGET (window));
+}
+
+static void
+gtk_window_layout_cb (GdkFrameClock *clock,
+                      GtkWindow     *window)
+{
+  GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
+  GtkWidget *widget = GTK_WIDGET (window);
+
+  /* We validate the style contexts in a single loop before even trying
+   * to handle resizes instead of doing validations inline.
+   * This is mostly necessary for compatibility reasons with old code,
+   * because both css_changed and size_allocate functions often change
+   * styles and so could cause infinite loops in this function.
+   *
+   * It's important to note that even an invalid style context returns
+   * sane values. So the result of an invalid style context will never be
+   * a program crash, but only a wrong layout or rendering.
+   */
+  if (priv->restyle_pending)
+    {
+      priv->restyle_pending = FALSE;
+      gtk_css_node_validate (gtk_widget_get_css_node (widget));
+    }
+
+  /* we may be invoked with a container_resize_queue of NULL, because
+   * queue_resize could have been adding an extra idle function while
+   * the queue still got processed. we better just ignore such case
+   * than trying to explicitly work around them with some extra flags,
+   * since it doesn't cause any actual harm.
+   */
+  if (gtk_widget_needs_allocate (widget))
+    gtk_native_check_resize (GTK_NATIVE (window));
+
+  if (!gtk_window_needs_layout (window))
+    gtk_window_stop_layout (window);
+  else
+    gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
+}
+
+void
+gtk_window_start_layout (GtkWindow *window)
+{
+  GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
+  GdkFrameClock *clock;
+
+  if (priv->resize_handler != 0)
+    return;
+
+  if (!gtk_window_needs_layout (window))
+    return;
+
+  clock = gtk_widget_get_frame_clock (GTK_WIDGET (window));
+  if (clock == NULL)
+    return;
+
+  priv->resize_handler = g_signal_connect (clock, "layout",
+                                           G_CALLBACK (gtk_window_layout_cb), window);
+  gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
+}
+
+void
+gtk_window_stop_layout (GtkWindow *window)
+{
+  GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
+  GdkFrameClock *clock;
+
+  if (priv->resize_handler == 0)
+    return;
+
+  clock = gtk_widget_get_frame_clock (GTK_WIDGET (window));
+  g_signal_handler_disconnect (clock, priv->resize_handler);
+  priv->resize_handler = 0;
+}
+
+void
+gtk_window_queue_restyle (GtkWindow *window)
+{
+  GtkWindowPrivate *priv = gtk_window_get_instance_private (window);
+
+  if (priv->restyle_pending)
+    return;
+
+  priv->restyle_pending = TRUE;
+
+  gtk_window_start_layout (window);
+}
diff --git a/gtk/gtkwindowprivate.h b/gtk/gtkwindowprivate.h
index 948644f574..1cde20fc80 100644
--- a/gtk/gtkwindowprivate.h
+++ b/gtk/gtkwindowprivate.h
@@ -141,6 +141,11 @@ GtkWidget *      gtk_window_pick_popover (GtkWindow   *window,
 void             gtk_window_set_extra_input_region (GtkWindow      *window,
                                                     cairo_region_t *region);
 
+void             gtk_window_start_layout  (GtkWindow *window);
+void             gtk_window_stop_layout   (GtkWindow *window);
+void             gtk_window_queue_restyle (GtkWindow *window);
+
+
 G_END_DECLS
 
 #endif /* __GTK_WINDOW_PRIVATE_H__ */


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