cssnode: Have GtkRoots be a root widget

Nodes are declared as roots on creation when they are owned by a
GtkRoot. All other nodes aren't roots.

When getting the root for a node, we walk the parents until we find a
root node and then return its widget.

This also means that nodes of unrooted widgets will not report a root
widget.
This commit is contained in:
Benjamin Otte
2020-02-09 16:22:08 +01:00
parent 3b23cfa8fb
commit e16b84d6c8
3 changed files with 26 additions and 2 deletions

View File

@@ -717,6 +717,7 @@ gtk_css_node_reposition (GtkCssNode *node,
GtkCssNode *old_parent;
g_assert (! (new_parent == NULL && previous != NULL));
g_assert (!node->is_root);
old_parent = node->parent;
/* Take a reference here so the whole function has a reference */
@@ -1379,9 +1380,16 @@ gtk_css_node_get_style_provider (GtkCssNode *cssnode)
}
GtkWidget *
gtk_css_node_get_root (GtkCssNode *cssnode)
gtk_css_node_get_root (GtkCssNode *self)
{
return NULL;
while (!self->is_root)
{
self = self->parent;
if (self == NULL)
return NULL;
}
return GTK_CSS_NODE_GET_CLASS (self)->get_root (self);
}
void

View File

@@ -53,6 +53,7 @@ struct _GtkCssNode
GtkCssChange pending_changes; /* changes that accumulated since the style was last computed */
guint is_root :1; /* node is the root of a CSS tree and never has parents */
guint visible :1; /* node will be skipped when validating or computing styles */
guint invalid :1; /* node or a child needs to be validated (even if just for animation) */
guint needs_propagation :1; /* children have state changes that need to be propagated to their siblings */
@@ -79,6 +80,8 @@ struct _GtkCssNodeClass
/* get style provider to use or NULL to use parent's */
GtkStyleProvider * (* get_style_provider) (GtkCssNode *cssnode);
/* get the root widget for this node - will only be called if cssnode->is_root == TRUE */
GtkWidget * (* get_root) (GtkCssNode *cssnode);
/* get frame clock or NULL (only relevant for root node) */
GdkFrameClock * (* get_frame_clock) (GtkCssNode *cssnode);
GtkCssStyle * (* update_style) (GtkCssNode *cssnode,

View File

@@ -120,6 +120,16 @@ gtk_css_widget_node_get_style_provider (GtkCssNode *node)
return GTK_STYLE_PROVIDER (cascade);
}
static GtkWidget *
gtk_css_widget_node_get_root (GtkCssNode *node)
{
GtkCssWidgetNode *self = GTK_CSS_WIDGET_NODE (node);
g_assert (self->widget == NULL || GTK_IS_ROOT (self->widget));
return self->widget;
}
static GdkFrameClock *
gtk_css_widget_node_get_frame_clock (GtkCssNode *node)
{
@@ -145,6 +155,7 @@ gtk_css_widget_node_class_init (GtkCssWidgetNodeClass *klass)
node_class->queue_validate = gtk_css_widget_node_queue_validate;
node_class->dequeue_validate = gtk_css_widget_node_dequeue_validate;
node_class->get_style_provider = gtk_css_widget_node_get_style_provider;
node_class->get_root = gtk_css_widget_node_get_root;
node_class->get_frame_clock = gtk_css_widget_node_get_frame_clock;
}
@@ -163,6 +174,8 @@ gtk_css_widget_node_new (GtkWidget *widget)
result = g_object_new (GTK_TYPE_CSS_WIDGET_NODE, NULL);
result->widget = widget;
if (GTK_IS_ROOT (widget))
GTK_CSS_NODE (result)->is_root = TRUE;
gtk_css_node_set_visible (GTK_CSS_NODE (result),
_gtk_widget_get_visible (widget));