gtk/root: Validate css node after update

It should happen before layout, but after the animation tick, thus after
the update.
This commit is contained in:
Jonas Ådahl 2020-11-24 18:33:05 +01:00
parent 8d4f8f0cfc
commit 0c8d97e3f7
2 changed files with 77 additions and 21 deletions

View File

@ -78,6 +78,7 @@
enum { enum {
POPUP_LAYOUT_CHANGED, POPUP_LAYOUT_CHANGED,
SIZE_CHANGED, SIZE_CHANGED,
LAYOUT,
RENDER, RENDER,
EVENT, EVENT,
ENTER_MONITOR, ENTER_MONITOR,
@ -571,6 +572,31 @@ gdk_surface_class_init (GdkSurfaceClass *klass)
G_TYPE_INT, G_TYPE_INT,
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: * GdkSurface::render:
* @surface: the #GdkSurface * @surface: the #GdkSurface

View File

@ -44,7 +44,8 @@
*/ */
static GQuark quark_restyle_pending; 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_DEFINE_INTERFACE_WITH_CODE (GtkRoot, gtk_root, GTK_TYPE_WIDGET,
g_type_interface_add_prerequisite (g_define_type_id, GTK_TYPE_NATIVE)) 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; iface->set_focus = gtk_root_default_set_focus;
quark_restyle_pending = g_quark_from_static_string ("gtk-root-restyle-pending"); 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 static void
gtk_root_layout_cb (GdkFrameClock *clock, gtk_root_after_update_cb (GdkFrameClock *clock,
GtkRoot *self) GtkRoot *self)
{ {
GtkWidget *widget = GTK_WIDGET (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)) 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)); 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 /* we may be invoked with a container_resize_queue of NULL, because
* queue_resize could have been adding an extra idle function while * 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)) if (gtk_root_needs_layout (self))
gtk_root_stop_layout (self); {
else gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_UPDATE);
gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT); gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
}
} }
void void
gtk_root_start_layout (GtkRoot *self) gtk_root_start_layout (GtkRoot *self)
{ {
GdkFrameClock *clock; GdkFrameClock *clock;
guint resize_handler;
if (g_object_get_qdata (G_OBJECT (self), quark_resize_handler))
return;
if (!gtk_root_needs_layout (self)) if (!gtk_root_needs_layout (self))
return; return;
@ -241,10 +248,25 @@ gtk_root_start_layout (GtkRoot *self)
if (clock == NULL) if (clock == NULL)
return; return;
resize_handler = g_signal_connect (clock, "layout", if (!g_object_get_qdata (G_OBJECT (self), quark_layout_handler))
G_CALLBACK (gtk_root_layout_cb), self); {
g_object_set_qdata (G_OBJECT (self), quark_resize_handler, GINT_TO_POINTER (resize_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); gdk_frame_clock_request_phase (clock, GDK_FRAME_CLOCK_PHASE_LAYOUT);
} }
@ -252,16 +274,24 @@ void
gtk_root_stop_layout (GtkRoot *self) gtk_root_stop_layout (GtkRoot *self)
{ {
GdkFrameClock *clock; 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; return;
clock = gtk_widget_get_frame_clock (GTK_WIDGET (self)); clock = gtk_widget_get_frame_clock (GTK_WIDGET (self));
g_signal_handler_disconnect (clock, resize_handler); g_signal_handler_disconnect (clock, layout_handler);
g_object_set_qdata (G_OBJECT (self), quark_resize_handler, NULL); 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 void