[gtk/wip/baedert/resize2: 324/325] Add a list of resize widgets to GtkRoot
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/baedert/resize2: 324/325] Add a list of resize widgets to GtkRoot
- Date: Wed, 3 Jun 2020 06:23:57 +0000 (UTC)
commit faeab008bfc5a706802eeb757f013f34c2d967c0
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 | 81 +++++++++++++++++-----------
gtk/gtkwidgetprivate.h | 4 ++
4 files changed, 189 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 73f223ecd4..81beb126d1 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -2475,6 +2475,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);
@@ -3520,10 +3521,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
@@ -3534,19 +3537,14 @@ 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;
@@ -3555,16 +3553,6 @@ gtk_widget_queue_resize_internal (GtkWidget *widget)
if (priv->resize_func)
priv->resize_func (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,45 @@ 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 (!priv->visible)
+ return;
+
+ if (priv->root)
+ {
+ GSList *l;
+
+ gtk_root_queue_resize (priv->root, widget);
+ gtk_root_start_layout (priv->root);
+
+#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 +4047,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 +10476,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 d4a4003834..d6f6d12f13 100644
--- a/gtk/gtkwidgetprivate.h
+++ b/gtk/gtkwidgetprivate.h
@@ -483,6 +483,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]