[gtk+] cssnode: Add node-added and node-removed signal
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] cssnode: Add node-added and node-removed signal
- Date: Wed, 18 Mar 2015 15:11:00 +0000 (UTC)
commit 6988f9b818c398511378de5a28cd68b53745110b
Author: Benjamin Otte <otte redhat com>
Date: Sun Mar 1 21:33:54 2015 +0100
cssnode: Add node-added and node-removed signal
This allows monitoring the CSS tree. For now, moving a child to a
different position relative to its siblings while keeping the same
parent will cause a child-added + child-removed emission.
gtk/gtkcssnode.c | 156 ++++++++++++++++++++++++++++++-----------------
gtk/gtkcssnodeprivate.h | 7 ++
2 files changed, 107 insertions(+), 56 deletions(-)
---
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 462d550..e31690a 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -21,6 +21,8 @@
#include "gtkcssanimatedstyleprivate.h"
#include "gtkdebug.h"
+#include "gtkintl.h"
+#include "gtkmarshalers.h"
#include "gtksettingsprivate.h"
/* When these change we do a full restyling. Otherwise we try to figure out
@@ -29,6 +31,14 @@
G_DEFINE_TYPE (GtkCssNode, gtk_css_node, G_TYPE_OBJECT)
+enum {
+ NODE_ADDED,
+ NODE_REMOVED,
+ LAST_SIGNAL
+};
+
+static guint cssnode_signals[LAST_SIGNAL] = { 0 };
+
static GtkStyleProviderPrivate *
gtk_css_node_get_style_provider_or_null (GtkCssNode *cssnode)
{
@@ -333,6 +343,51 @@ gtk_css_node_real_get_frame_clock (GtkCssNode *cssnode)
}
static void
+gtk_css_node_real_node_removed (GtkCssNode *parent,
+ GtkCssNode *node,
+ GtkCssNode *previous)
+{
+ if (node->previous_sibling)
+ node->previous_sibling->next_sibling = node->next_sibling;
+ else
+ node->parent->first_child = node->next_sibling;
+
+ if (node->next_sibling)
+ node->next_sibling->previous_sibling = node->previous_sibling;
+ else
+ node->parent->last_child = node->previous_sibling;
+
+ node->previous_sibling = NULL;
+ node->next_sibling = NULL;
+ node->parent = NULL;
+}
+
+static void
+gtk_css_node_real_node_added (GtkCssNode *parent,
+ GtkCssNode *node,
+ GtkCssNode *new_previous)
+{
+ if (new_previous)
+ {
+ node->previous_sibling = new_previous;
+ node->next_sibling = new_previous->next_sibling;
+ new_previous->next_sibling = node;
+ }
+ else
+ {
+ node->next_sibling = parent->first_child;
+ parent->first_child = node;
+ }
+
+ if (node->next_sibling)
+ node->next_sibling->previous_sibling = node;
+ else
+ parent->last_child = node;
+
+ node->parent = parent;
+}
+
+static void
gtk_css_node_class_init (GtkCssNodeClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -350,6 +405,28 @@ gtk_css_node_class_init (GtkCssNodeClass *klass)
klass->get_widget_path = gtk_css_node_real_get_widget_path;
klass->get_style_provider = gtk_css_node_real_get_style_provider;
klass->get_frame_clock = gtk_css_node_real_get_frame_clock;
+
+ klass->node_added = gtk_css_node_real_node_added;
+ klass->node_removed = gtk_css_node_real_node_removed;
+
+ cssnode_signals[NODE_ADDED] =
+ g_signal_new (I_("node-added"),
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkCssNodeClass, node_added),
+ NULL, NULL,
+ _gtk_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2,
+ GTK_TYPE_CSS_NODE, GTK_TYPE_CSS_NODE);
+ cssnode_signals[NODE_REMOVED] =
+ g_signal_new (I_("node-removed"),
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkCssNodeClass, node_removed),
+ NULL, NULL,
+ _gtk_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2,
+ GTK_TYPE_CSS_NODE, GTK_TYPE_CSS_NODE);
}
static void
@@ -397,44 +474,6 @@ gtk_css_node_parent_will_be_set (GtkCssNode *node)
GTK_CSS_NODE_GET_CLASS (node)->dequeue_validate (node);
}
-static void
-gtk_css_node_unlink_from_siblings (GtkCssNode *node)
-{
- if (node->previous_sibling)
- node->previous_sibling->next_sibling = node->next_sibling;
- else
- node->parent->first_child = node->next_sibling;
-
- if (node->next_sibling)
- node->next_sibling->previous_sibling = node->previous_sibling;
- else
- node->parent->last_child = node->previous_sibling;
-
- node->previous_sibling = NULL;
- node->next_sibling = NULL;
-}
-
-static void
-gtk_css_node_link_to_siblings (GtkCssNode *node,
- GtkCssNode *new_previous)
-{
- if (new_previous)
- {
- node->previous_sibling = new_previous;
- node->next_sibling = new_previous->next_sibling;
- new_previous->next_sibling = node;
- }
- else
- {
- node->next_sibling = node->parent->first_child;
- node->parent->first_child = node;
- }
-
- if (node->next_sibling)
- node->next_sibling->previous_sibling = node;
- else
- node->parent->last_child = node;
-}
static void
gtk_css_node_set_children_changed (GtkCssNode *node)
@@ -464,23 +503,28 @@ gtk_css_node_invalidate_style (GtkCssNode *cssnode)
static void
gtk_css_node_reposition (GtkCssNode *node,
- GtkCssNode *parent,
+ GtkCssNode *new_parent,
GtkCssNode *previous)
{
- g_assert (! (parent == NULL && previous != NULL));
+ GtkCssNode *old_parent;
+ g_assert (! (new_parent == NULL && previous != NULL));
+
+ old_parent = node->parent;
/* Take a reference here so the whole function has a reference */
g_object_ref (node);
if (node->next_sibling)
gtk_css_node_invalidate_style (node->next_sibling);
- if (node->parent != NULL)
- gtk_css_node_unlink_from_siblings (node);
+ if (old_parent != NULL)
+ {
+ g_signal_emit (old_parent, cssnode_signals[NODE_REMOVED], 0, node, node->previous_sibling);
+ }
- if (node->parent != parent)
+ if (old_parent != new_parent)
{
- if (node->parent == NULL)
+ if (old_parent == NULL)
{
gtk_css_node_parent_will_be_set (node);
}
@@ -488,34 +532,34 @@ gtk_css_node_reposition (GtkCssNode *node,
{
g_object_unref (node);
if (node->visible)
- gtk_css_node_set_children_changed (node->parent);
+ gtk_css_node_set_children_changed (old_parent);
}
- node->parent = parent;
+ if (gtk_css_node_get_style_provider_or_null (node) == NULL)
+ gtk_css_node_invalidate_style_provider (node);
+ gtk_css_node_invalidate (node, GTK_CSS_CHANGE_TIMESTAMP | GTK_CSS_CHANGE_ANIMATIONS);
- if (parent)
+ if (new_parent)
{
if (node->visible)
- gtk_css_node_set_children_changed (parent);
+ gtk_css_node_set_children_changed (new_parent);
g_object_ref (node);
if (node->pending_changes)
- parent->needs_propagation = TRUE;
+ new_parent->needs_propagation = TRUE;
if (node->invalid && node->visible)
- gtk_css_node_set_invalid (parent, TRUE);
+ gtk_css_node_set_invalid (new_parent, TRUE);
}
else
{
gtk_css_node_parent_was_unset (node);
}
-
- if (gtk_css_node_get_style_provider_or_null (node) == NULL)
- gtk_css_node_invalidate_style_provider (node);
- gtk_css_node_invalidate (node, GTK_CSS_CHANGE_TIMESTAMP | GTK_CSS_CHANGE_ANIMATIONS);
}
- if (parent)
- gtk_css_node_link_to_siblings (node, previous);
+ if (new_parent)
+ {
+ g_signal_emit (new_parent, cssnode_signals[NODE_ADDED], 0, node, previous);
+ }
if (node->next_sibling)
gtk_css_node_invalidate_style (node->next_sibling);
diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h
index 611bc71..6cc9f72 100644
--- a/gtk/gtkcssnodeprivate.h
+++ b/gtk/gtkcssnodeprivate.h
@@ -65,6 +65,13 @@ struct _GtkCssNodeClass
{
GObjectClass object_class;
+ void (* node_added) (GtkCssNode *cssnode,
+ GtkCssNode *child,
+ GtkCssNode *previous);
+ void (* node_removed) (GtkCssNode *cssnode,
+ GtkCssNode *child,
+ GtkCssNode *previous);
+
gboolean (* init_matcher) (GtkCssNode *cssnode,
GtkCssMatcher *matcher);
GtkWidgetPath * (* create_widget_path) (GtkCssNode *cssnode);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]