[gtk/wip/baedert/resize2] Add a list of resize widgets to GtkRoot



commit b995456171ec75b4de5927fb4fb94343eaec0ec2
Author: Timm Bäder <mail baedert org>
Date:   Mon May 25 19:46:31 2020 +0200

    Add a list of resize widgets to GtkRoot

 gtk/gtkroot.c          | 141 ++++++++++++++++++++++++++++++++++++++++++++-----
 gtk/gtkrootprivate.h   |   5 ++
 gtk/gtkwidget.c        |  80 +++++++++++++++++-----------
 gtk/gtkwidgetprivate.h |   4 ++
 4 files changed, 188 insertions(+), 42 deletions(-)
---
diff --git a/gtk/gtkroot.c b/gtk/gtkroot.c
index aa951ef1d9..e9753bfb5f 100644
--- a/gtk/gtkroot.c
+++ b/gtk/gtkroot.c
@@ -43,6 +43,10 @@
 
 static GQuark quark_restyle_pending;
 static GQuark quark_resize_handler;
+static GQuark quark_resize_widgets;
+static GQuark quark_resize_iteration;
+
+#define MAX_RESIZE_ITERATIONS 2
 
 G_DEFINE_INTERFACE_WITH_CODE (GtkRoot, gtk_root, GTK_TYPE_WIDGET,
                               g_type_interface_add_prerequisite (g_define_type_id, GTK_TYPE_NATIVE))
@@ -82,6 +86,8 @@ gtk_root_default_init (GtkRootInterface *iface)
 
   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_resize_widgets = g_quark_from_static_string ("gtk-root-resize-widgets");
+  quark_resize_iteration = g_quark_from_static_string ("gtk-root-resize-iteration");
 }
 
 /**
@@ -162,9 +168,15 @@ gtk_root_get_focus (GtkRoot *self)
 static gboolean
 gtk_root_needs_layout (GtkRoot *self)
 {
+  GPtrArray *resize_widgets;
+
   if (g_object_get_qdata (G_OBJECT (self), quark_restyle_pending))
     return TRUE;
 
+  resize_widgets = g_object_get_qdata (G_OBJECT (self), quark_resize_widgets);
+  if (resize_widgets && resize_widgets->len > 0)
+    return TRUE;
+
   return gtk_widget_needs_allocate (GTK_WIDGET (self));
 }
 
@@ -173,6 +185,7 @@ gtk_root_layout_cb (GdkFrameClock *clock,
                     GtkRoot       *self)
 {
   GtkWidget *widget = GTK_WIDGET (self);
+  GPtrArray *resize_widgets;
 
   /* We validate the style contexts in a single loop before even trying
    * to handle resizes instead of doing validations inline.
@@ -190,19 +203,64 @@ gtk_root_layout_cb (GdkFrameClock *clock,
       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 (self));
+  resize_widgets = g_object_get_qdata (G_OBJECT (self), quark_resize_widgets);
 
-  if (!gtk_root_needs_layout (self))
-    gtk_root_stop_layout (self);
-  else
-    gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
+  /*g_print ("===================\n");*/
+
+  if (!resize_widgets)
+    {
+      gtk_root_stop_layout (self);
+      return;
+    }
+
+  /*g_message ("Resize widgets: ");*/
+  for (guint p = 0; p < resize_widgets->len; p++)
+    {
+      GtkWidget *w = g_ptr_array_index (resize_widgets, p);
+      /*g_message ("%u: %s %p", p, G_OBJECT_TYPE_NAME (w), w);*/
+    }
+
+  for (int i = 0; i < MAX_RESIZE_ITERATIONS; i++)
+    {
+      /* 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.
+       */
+
+      g_object_set_qdata (G_OBJECT (self), quark_resize_iteration, GINT_TO_POINTER (i + 1));
+
+      for (guint p = 0; p < resize_widgets->len; p++)
+        {
+          GtkWidget *w = g_ptr_array_index (resize_widgets, p);
+          gtk_widget_apply_resize_stuff (w);
+        }
+
+      gtk_root_unqueue_resize (self, GTK_WIDGET (self));
+
+      gtk_native_check_resize (GTK_NATIVE (self));
+
+      if (!gtk_root_needs_layout (self))
+        {
+          gtk_root_stop_layout (self);
+          break;
+        }
+    }
+
+  g_object_set_qdata (G_OBJECT (self), quark_resize_iteration, NULL);
+
+  if (resize_widgets->len > 0)
+    {
+      g_message ("After %d Iterations:", MAX_RESIZE_ITERATIONS);
+      for (guint p = 0; p < resize_widgets->len; p++)
+        {
+          GtkWidget *w = g_ptr_array_index (resize_widgets, p);
+          g_message ("%p: %u: %s %p", self, p, G_OBJECT_TYPE_NAME (w), w);
+        }
+
+      g_ptr_array_set_size (resize_widgets, 0);
+    }
 }
 
 void
@@ -214,6 +272,9 @@ gtk_root_start_layout (GtkRoot *self)
   if (g_object_get_qdata (G_OBJECT (self), quark_resize_handler))
     return;
 
+  if (!g_object_get_qdata (G_OBJECT (self), quark_resize_widgets))
+    return;
+
   if (!gtk_root_needs_layout (self))
     return;
 
@@ -228,12 +289,68 @@ gtk_root_start_layout (GtkRoot *self)
   gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
 }
 
+void
+gtk_root_queue_resize (GtkRoot   *self,
+                       GtkWidget *widget)
+{
+  GPtrArray *resize_widgets = g_object_get_qdata (G_OBJECT (self), quark_resize_widgets);
+  int iteration;
+
+  if (!resize_widgets)
+    {
+      resize_widgets = g_ptr_array_sized_new (16);
+      g_object_set_qdata (G_OBJECT (self), quark_resize_widgets, resize_widgets); // TODO: Use _full
+    }
+
+  /*g_message ("%s: %s %p", __FUNCTION__,*/
+             /*G_OBJECT_TYPE_NAME (widget), widget);*/
+
+  iteration = GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (self), quark_resize_iteration));
+
+  if (iteration != 0)
+    {
+      g_warning ("Adding widget %s %p to be resized while root %s %p is in resize iteration %d",
+                 G_OBJECT_TYPE_NAME (widget), widget,
+                 G_OBJECT_TYPE_NAME (self), self,
+                 iteration);
+    }
+
+  if (!g_ptr_array_find (resize_widgets, widget, NULL)) {
+    g_ptr_array_add (resize_widgets, widget);
+    /*g_message ("Adding %s %p to resize widgets", G_OBJECT_TYPE_NAME (widget), widget);*/
+  }
+}
+
+void
+gtk_root_unqueue_resize (GtkRoot   *self,
+                         GtkWidget *widget)
+{
+  GPtrArray *resize_widgets = g_object_get_qdata (G_OBJECT (self), quark_resize_widgets);
+  guint index;
+
+  if (!resize_widgets)
+    return;
+
+  if (g_ptr_array_find (resize_widgets, widget, &index)) {
+    /*g_message ("Removing %s %p from resize widgets", G_OBJECT_TYPE_NAME (widget), widget);*/
+    g_ptr_array_remove_index_fast (resize_widgets, index);
+  } else {
+    /*g_critical ("Removing %s %p not possible!", G_OBJECT_TYPE_NAME (widget), widget);*/
+  }
+}
+
 void
 gtk_root_stop_layout (GtkRoot *self)
 {
   GdkFrameClock *clock;
+  GPtrArray *resize_widgets;
   guint resize_handler;
 
+  resize_widgets = g_object_get_qdata (G_OBJECT (self), quark_resize_widgets);
+
+  if (resize_widgets)
+    g_ptr_array_set_size (resize_widgets, 0);
+
   resize_handler = GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (self), quark_resize_handler));
 
   if (resize_handler == 0)
diff --git a/gtk/gtkrootprivate.h b/gtk/gtkrootprivate.h
index d4c3174ae0..80c1358e8b 100644
--- a/gtk/gtkrootprivate.h
+++ b/gtk/gtkrootprivate.h
@@ -34,6 +34,11 @@ void             gtk_root_start_layout  (GtkRoot *self);
 void             gtk_root_stop_layout   (GtkRoot *self);
 void             gtk_root_queue_restyle (GtkRoot *self);
 
+void             gtk_root_queue_resize    (GtkRoot   *self,
+                                           GtkWidget *widget);
+void             gtk_root_unqueue_resize  (GtkRoot   *self,
+                                           GtkWidget *widget);
+
 G_END_DECLS
 
 #endif /* __GTK_ROOT_PRIVATE_H__ */
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 509bfe860c..98463771e5 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -2478,6 +2478,7 @@ gtk_widget_unroot (GtkWidget *widget)
     remove_parent_surface_transform_changed_listener (widget);
 
   _gtk_widget_update_parent_muxer (widget);
+  gtk_root_unqueue_resize (priv->root, widget);
 
   GTK_WIDGET_GET_CLASS (widget)->unroot (widget);
 
@@ -3523,10 +3524,12 @@ gtk_widget_queue_allocate (GtkWidget *widget)
 {
   g_return_if_fail (GTK_IS_WIDGET (widget));
 
-  if (_gtk_widget_get_realized (widget))
-    gtk_widget_queue_draw (widget);
+  gtk_widget_queue_resize (widget);
 
-  gtk_widget_set_alloc_needed (widget);
+  /*if (_gtk_widget_get_realized (widget))*/
+    /*gtk_widget_queue_draw (widget);*/
+
+  /*gtk_widget_set_alloc_needed (widget);*/
 }
 
 static inline gboolean
@@ -3537,34 +3540,19 @@ gtk_widget_get_resize_needed (GtkWidget *widget)
   return priv->resize_needed;
 }
 
-/*
- * gtk_widget_queue_resize_internal:
- * @widget: a #GtkWidget
- * 
- * Queue a resize on a widget, and on all other widgets grouped with this widget.
- */
-static void
-gtk_widget_queue_resize_internal (GtkWidget *widget)
+static void gtk_widget_queue_resize_internal (GtkWidget *widget);
+
+void
+gtk_widget_apply_resize_stuff (GtkWidget *widget)
 {
   GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
-  GSList *groups, *l, *widgets;
 
-  if (gtk_widget_get_resize_needed (widget))
+  if (priv->resize_needed)
     return;
 
   priv->resize_needed = TRUE;
   gtk_widget_set_alloc_needed (widget);
 
-  groups = _gtk_widget_get_sizegroups (widget);
-
-  for (l = groups; l; l = l->next)
-  {
-    for (widgets = gtk_size_group_get_widgets (l->data); widgets; widgets = widgets->next)
-      {
-        gtk_widget_queue_resize_internal (widgets->data);
-      }
-  }
-
   if (_gtk_widget_get_visible (widget))
     {
       GtkWidget *parent = _gtk_widget_get_parent (widget);
@@ -3573,8 +3561,44 @@ gtk_widget_queue_resize_internal (GtkWidget *widget)
           if (GTK_IS_NATIVE (widget))
             gtk_widget_queue_allocate (parent);
           else
-            gtk_widget_queue_resize_internal (parent);
+            gtk_widget_apply_resize_stuff (parent);
+        }
+    }
+}
+
+/*
+ * gtk_widget_queue_resize_internal:
+ * @widget: a #GtkWidget
+ *
+ * Queue a resize on a widget, and on all other widgets grouped with this widget.
+ */
+static void
+gtk_widget_queue_resize_internal (GtkWidget *widget)
+{
+  GtkWidgetPrivate *priv = gtk_widget_get_instance_private (widget);
+
+  /*if (!_gtk_widget_get_mapped (widget))*/
+    /*return;*/
+
+  if (priv->root)
+    {
+      GSList *l;
+      gtk_root_start_layout (priv->root);
+      gtk_root_queue_resize (priv->root, widget);
+
+#if 1
+      l = _gtk_widget_get_sizegroups (widget);
+      for (; l; l = l->next)
+        {
+          GSList *widgets;
+          for (widgets = gtk_size_group_get_widgets (l->data); widgets; widgets = widgets->next)
+            {
+              gtk_root_queue_resize (priv->root, widgets->data);
+            }
         }
+#endif
+
+      return;
     }
 }
 
@@ -4022,6 +4046,8 @@ out:
   if (priv->alloc_needed_on_child)
     gtk_widget_ensure_allocate (widget);
 
+  gtk_root_unqueue_resize (priv->root, widget);
+
   gtk_widget_pop_verify_invariants (widget);
 }
 
@@ -10449,12 +10475,6 @@ gtk_widget_set_alloc_needed (GtkWidget *widget)
       if (!priv->visible)
         break;
 
-      if (!priv->parent && GTK_IS_ROOT (widget))
-        {
-          gtk_root_start_layout (GTK_ROOT (widget));
-          break;
-        }
-
       widget = priv->parent;
       if (widget == NULL)
         break;
diff --git a/gtk/gtkwidgetprivate.h b/gtk/gtkwidgetprivate.h
index d06db43250..4b85e88cbc 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -482,6 +482,10 @@ gtk_widget_get_transform (GtkWidget *widget)
   return widget->priv->transform;
 }
 
+void
+gtk_widget_apply_resize_stuff (GtkWidget *widget);
+
+
 G_END_DECLS
 
 #endif /* __GTK_WIDGET_PRIVATE_H__ */


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