[gtk/clipboard-demo-fixes: 1/2] Move the idle sizer to the gtkroot.c
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/clipboard-demo-fixes: 1/2] Move the idle sizer to the gtkroot.c
- Date: Sun, 26 Apr 2020 01:31:48 +0000 (UTC)
commit 637890517b40e060322222101cf4eb1f53fe318c
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Apr 25 21:03:57 2020 -0400
Move the idle sizer to the gtkroot.c
This is needed since we already have a second GtkRoot
implementation with GtkDragIcon, and DND is causing
critical warnings due to this.
gtk/gtkcsswidgetnode.c | 4 +-
gtk/gtkroot.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++
gtk/gtkrootprivate.h | 4 ++
gtk/gtkwidget.c | 4 +-
gtk/gtkwindow.c | 108 +------------------------------------------------
gtk/gtkwindowprivate.h | 4 --
6 files changed, 113 insertions(+), 114 deletions(-)
---
diff --git a/gtk/gtkcsswidgetnode.c b/gtk/gtkcsswidgetnode.c
index b8aaf453024..ec49fbeea7a 100644
--- a/gtk/gtkcsswidgetnode.c
+++ b/gtk/gtkcsswidgetnode.c
@@ -46,7 +46,7 @@ gtk_css_widget_node_queue_callback (GtkWidget *widget,
GtkCssNode *node = user_data;
gtk_css_node_invalidate_frame_clock (node, TRUE);
- gtk_window_queue_restyle (GTK_WINDOW (widget));
+ gtk_root_queue_restyle (GTK_ROOT (widget));
return G_SOURCE_CONTINUE;
}
@@ -56,7 +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))
+ if (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/gtkroot.c b/gtk/gtkroot.c
index 0252b85856a..24d3860b1d7 100644
--- a/gtk/gtkroot.c
+++ b/gtk/gtkroot.c
@@ -43,6 +43,9 @@
* The obvious example of a #GtkRoot is #GtkWindow.
*/
+static GQuark quark_restyle_pending;
+static GQuark quark_resize_handler;
+
G_DEFINE_INTERFACE_WITH_CODE (GtkRoot, gtk_root, GTK_TYPE_WIDGET,
g_type_interface_add_prerequisite (g_define_type_id, GTK_TYPE_NATIVE))
@@ -78,6 +81,9 @@ gtk_root_default_init (GtkRootInterface *iface)
iface->get_constraint_solver = gtk_root_default_get_constraint_solver;
iface->get_focus = gtk_root_default_get_focus;
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");
}
/**
@@ -154,3 +160,100 @@ gtk_root_get_focus (GtkRoot *self)
return GTK_ROOT_GET_IFACE (self)->get_focus (self);
}
+
+static gboolean
+gtk_root_needs_layout (GtkRoot *self)
+{
+ if (g_object_get_qdata (G_OBJECT (self), quark_restyle_pending))
+ return TRUE;
+
+ return gtk_widget_needs_allocate (GTK_WIDGET (self));
+}
+
+static void
+gtk_root_layout_cb (GdkFrameClock *clock,
+ GtkRoot *self)
+{
+ GtkWidget *widget = GTK_WIDGET (self);
+
+ /* 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 (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));
+ }
+
+ /* 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));
+
+ if (!gtk_root_needs_layout (self))
+ gtk_root_stop_layout (self);
+ else
+ 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;
+
+ clock = gtk_widget_get_frame_clock (GTK_WIDGET (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));
+
+ gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
+}
+
+void
+gtk_root_stop_layout (GtkRoot *self)
+{
+ GdkFrameClock *clock;
+ guint resize_handler;
+
+ resize_handler = GPOINTER_TO_INT (g_object_get_qdata (G_OBJECT (self), quark_resize_handler));
+
+ if (resize_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);
+}
+
+void
+gtk_root_queue_restyle (GtkRoot *self)
+{
+ if (g_object_get_qdata (G_OBJECT (self), quark_restyle_pending))
+ return;
+
+ g_object_set_qdata (G_OBJECT (self), quark_restyle_pending, GINT_TO_POINTER (1));
+
+ gtk_root_start_layout (self);
+}
+
diff --git a/gtk/gtkrootprivate.h b/gtk/gtkrootprivate.h
index 57246127a54..d4c3174ae07 100644
--- a/gtk/gtkrootprivate.h
+++ b/gtk/gtkrootprivate.h
@@ -30,6 +30,10 @@ struct _GtkRootInterface
GtkConstraintSolver * gtk_root_get_constraint_solver (GtkRoot *self);
+void gtk_root_start_layout (GtkRoot *self);
+void gtk_root_stop_layout (GtkRoot *self);
+void gtk_root_queue_restyle (GtkRoot *self);
+
G_END_DECLS
#endif /* __GTK_ROOT_PRIVATE_H__ */
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index da4f588f195..cf5499b8d41 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -10429,9 +10429,9 @@ gtk_widget_set_alloc_needed (GtkWidget *widget)
if (!priv->visible)
break;
- if (GTK_IS_WINDOW (widget))
+ if (GTK_IS_ROOT (widget))
{
- gtk_window_start_layout (GTK_WINDOW (widget));
+ gtk_root_start_layout (GTK_ROOT (widget));
break;
}
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 49726ea322d..f35c1c00664 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -241,12 +241,8 @@ 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;
@@ -4016,9 +4012,6 @@ 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);
}
@@ -4830,7 +4823,7 @@ gtk_window_realize (GtkWidget *widget)
GTK_WIDGET_CLASS (gtk_window_parent_class)->realize (widget);
- gtk_window_start_layout (window);
+ gtk_root_start_layout (GTK_ROOT (window));
if (priv->renderer == NULL)
priv->renderer = gsk_renderer_new_for_surface (surface);
@@ -4947,7 +4940,7 @@ 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_root_stop_layout (GTK_ROOT (window));
GTK_WIDGET_CLASS (gtk_window_parent_class)->unrealize (widget);
@@ -8111,100 +8104,3 @@ 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 15a66393276..2392f8668ae 100644
--- a/gtk/gtkwindowprivate.h
+++ b/gtk/gtkwindowprivate.h
@@ -139,10 +139,6 @@ 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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]