static void gtk_css_node_propagate_pending_changes (GtkCssNode *cssnode, gboolean style_changed) { GtkCssChange change, child_change; GtkCssNode *child; change = _gtk_css_change_for_child (cssnode->pending_changes); if (style_changed) change |= GTK_CSS_CHANGE_PARENT_STYLE; if (!cssnode->needs_propagation && change == 0) return; for (child = gtk_css_node_get_first_child (cssnode); child; child = gtk_css_node_get_next_sibling (child)) { child_change = child->pending_changes; gtk_css_node_invalidate (child, change); if (child->visible) change |= _gtk_css_change_for_sibling (child_change); } cssnode->needs_propagation = FALSE; }
static void store_in_global_parent_cache (GtkCssNode *node, GtkCssStyle *parent, const GtkCssNodeDeclaration *decl, GtkCssStyle *style) { GHashTable *cache; g_assert (GTK_IS_CSS_STATIC_STYLE (style)); if (parent == NULL || !may_use_global_parent_cache (node)) return; if (!may_be_stored_in_parent_cache (style)) return; cache = g_object_get_data (G_OBJECT (parent), "gtk-global-cache"); if (cache == NULL) { cache = g_hash_table_new_full (gtk_global_parent_cache_hash, gtk_global_parent_cache_equal, gtk_global_parent_cache_free, g_object_unref); g_object_set_data_full (G_OBJECT (parent), "gtk-global-cache", cache, (GDestroyNotify) g_hash_table_destroy); } g_hash_table_insert (cache, PACK (gtk_css_node_declaration_ref ((GtkCssNodeDeclaration *) decl), gtk_css_node_get_previous_sibling (node) == NULL, gtk_css_node_get_next_sibling (node) == NULL), g_object_ref (style)); }
static GtkCssNode * get_next_visible_sibling (GtkCssNode *node) { do { node = gtk_css_node_get_next_sibling (node); } while (node && !gtk_css_node_get_visible (node)); return node; }
void gtk_css_node_validate_internal (GtkCssNode *cssnode, gint64 timestamp) { GtkCssNode *child; /* If you run your application with * GTK_DEBUG=no-css-cache * every invalidation will purge the cache and completely query * everything anew form the cache. This is slow (in particular * when animating), but useful for figuring out bugs. * * We achieve that by pretending that everything that could have * changed has and so we of course totally need to redo everything. * * Note that this also completely revalidates child widgets all * the time. */ #ifdef G_ENABLE_DEBUG if (GTK_DEBUG_CHECK (NO_CSS_CACHE)) cssnode->pending_changes |= GTK_CSS_CHANGE_ANY; #endif if (!cssnode->invalid) return; gtk_css_node_ensure_style (cssnode, timestamp); /* need to set to FALSE then to TRUE here to make it chain up */ gtk_css_node_set_invalid (cssnode, FALSE); if (!gtk_css_style_is_static (cssnode->style)) gtk_css_node_set_invalid (cssnode, TRUE); GTK_CSS_NODE_GET_CLASS (cssnode)->validate (cssnode); for (child = gtk_css_node_get_first_child (cssnode); child; child = gtk_css_node_get_next_sibling (child)) { if (child->visible) gtk_css_node_validate_internal (child, timestamp); } }
static GtkCssStyle * lookup_in_global_parent_cache (GtkCssNode *node, GtkCssStyle *parent, const GtkCssNodeDeclaration *decl) { GHashTable *cache; GtkCssStyle *style; if (parent == NULL || !may_use_global_parent_cache (node)) return NULL; cache = g_object_get_qdata (G_OBJECT (parent), quark_global_cache); if (cache == NULL) return NULL; style = g_hash_table_lookup (cache, PACK (decl, gtk_css_node_get_previous_sibling (node) == NULL, gtk_css_node_get_next_sibling (node) == NULL)); return style; }