[gtk+/wip/cssnode3: 62/81] cssnode: Add API to query the timestamp
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/cssnode3: 62/81] cssnode: Add API to query the timestamp
- Date: Sat, 28 Feb 2015 23:14:56 +0000 (UTC)
commit 86c583e6b3df6d81e40905c6b94882f81a202d1a
Author: Benjamin Otte <otte redhat com>
Date: Thu Feb 19 00:54:14 2015 +0100
cssnode: Add API to query the timestamp
... and pass it to the API that computes new styles.
A special timestamp of 0 means "please don't animate" and is used when
no frame clock is available for a node.
gtk/gtkcssnode.c | 78 +++++++++++++++++++++++++++++++++++++++++-----
gtk/gtkcssnodeprivate.h | 6 +++
gtk/gtkcsstypes.c | 2 -
gtk/gtkcsstypesprivate.h | 5 ++-
gtk/gtkcsswidgetnode.c | 36 ++++++++++++++++++---
gtk/gtkwidget.c | 4 ++
6 files changed, 114 insertions(+), 17 deletions(-)
---
diff --git a/gtk/gtkcssnode.c b/gtk/gtkcssnode.c
index 93d5395..b79da21 100644
--- a/gtk/gtkcssnode.c
+++ b/gtk/gtkcssnode.c
@@ -226,6 +226,7 @@ gtk_css_style_needs_recreation (GtkCssStyle *style,
static GtkCssStyle *
gtk_css_node_real_update_style (GtkCssNode *cssnode,
GtkCssChange pending_change,
+ gint64 timestamp,
GtkCssStyle *old_style)
{
if (!gtk_css_style_needs_recreation (old_style, pending_change))
@@ -285,6 +286,12 @@ gtk_css_node_real_get_style_provider (GtkCssNode *cssnode)
return NULL;
}
+static GdkFrameClock *
+gtk_css_node_real_get_frame_clock (GtkCssNode *cssnode)
+{
+ return NULL;
+}
+
static void
gtk_css_node_class_init (GtkCssNodeClass *klass)
{
@@ -302,6 +309,7 @@ gtk_css_node_class_init (GtkCssNodeClass *klass)
klass->create_widget_path = gtk_css_node_real_create_widget_path;
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;
}
static void
@@ -314,6 +322,27 @@ gtk_css_node_init (GtkCssNode *cssnode)
cssnode->visible = TRUE;
}
+static GdkFrameClock *
+gtk_css_node_get_frame_clock_or_null (GtkCssNode *cssnode)
+{
+ while (cssnode->parent)
+ cssnode = cssnode->parent;
+
+ return GTK_CSS_NODE_GET_CLASS (cssnode)->get_frame_clock (cssnode);
+}
+
+static gint64
+gtk_css_node_get_timestamp (GtkCssNode *cssnode)
+{
+ GdkFrameClock *frameclock;
+
+ frameclock = gtk_css_node_get_frame_clock_or_null (cssnode);
+ if (frameclock == NULL)
+ return 0;
+
+ return gdk_frame_clock_get_frame_time (frameclock);
+}
+
static void
gtk_css_node_parent_was_unset (GtkCssNode *node)
{
@@ -440,6 +469,7 @@ gtk_css_node_reposition (GtkCssNode *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)
@@ -560,22 +590,27 @@ gtk_css_node_propagate_pending_changes (GtkCssNode *cssnode,
}
}
+static gboolean
+gtk_css_node_needs_new_style (GtkCssNode *cssnode)
+{
+ return cssnode->style_is_invalid;
+}
+
static void
-gtk_css_node_ensure_style (GtkCssNode *cssnode)
+gtk_css_node_compute_style (GtkCssNode *cssnode,
+ gint64 timestamp)
{
GtkCssStyle *new_style;
- if (!cssnode->style_is_invalid)
- return;
-
- if (cssnode->parent)
- gtk_css_node_ensure_style (cssnode->parent);
+ if (cssnode->parent && gtk_css_node_needs_new_style (cssnode->parent))
+ gtk_css_node_compute_style (cssnode->parent, timestamp);
- if (cssnode->previous_sibling)
- gtk_css_node_ensure_style (cssnode->previous_sibling);
+ if (cssnode->previous_sibling && gtk_css_node_needs_new_style (cssnode->previous_sibling))
+ gtk_css_node_compute_style (cssnode->previous_sibling, timestamp);
new_style = GTK_CSS_NODE_GET_CLASS (cssnode)->update_style (cssnode,
cssnode->pending_changes,
+ timestamp,
cssnode->style);
gtk_css_node_propagate_pending_changes (cssnode, new_style != NULL);
@@ -590,6 +625,19 @@ gtk_css_node_ensure_style (GtkCssNode *cssnode)
cssnode->style_is_invalid = FALSE;
}
+static void
+gtk_css_node_ensure_style (GtkCssNode *cssnode)
+{
+ gint64 timestamp;
+
+ if (!gtk_css_node_needs_new_style (cssnode))
+ return;
+
+ timestamp = gtk_css_node_get_timestamp (cssnode);
+
+ gtk_css_node_compute_style (cssnode, timestamp);
+}
+
GtkCssStyle *
gtk_css_node_get_style (GtkCssNode *cssnode)
{
@@ -756,6 +804,20 @@ gtk_css_node_invalidate_style_provider (GtkCssNode *cssnode)
}
void
+gtk_css_node_invalidate_frame_clock (GtkCssNode *cssnode,
+ gboolean just_timestamp)
+{
+ /* frame clock is handled by the top level */
+ if (cssnode->parent)
+ return;
+
+ if (just_timestamp)
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_TIMESTAMP);
+ else
+ gtk_css_node_invalidate (cssnode, GTK_CSS_CHANGE_TIMESTAMP | GTK_CSS_CHANGE_ANIMATIONS);
+}
+
+void
gtk_css_node_invalidate (GtkCssNode *cssnode,
GtkCssChange change)
{
diff --git a/gtk/gtkcssnodeprivate.h b/gtk/gtkcssnodeprivate.h
index 944e01f..4101037 100644
--- a/gtk/gtkcssnodeprivate.h
+++ b/gtk/gtkcssnodeprivate.h
@@ -70,8 +70,11 @@ struct _GtkCssNodeClass
const GtkWidgetPath * (* get_widget_path) (GtkCssNode *cssnode);
/* get style provider to use or NULL to use parent's */
GtkStyleProviderPrivate *(* get_style_provider) (GtkCssNode *cssnode);
+ /* get frame clock or NULL (only relevant for root node) */
+ GdkFrameClock * (* get_frame_clock) (GtkCssNode *cssnode);
GtkCssStyle * (* update_style) (GtkCssNode *cssnode,
GtkCssChange pending_changes,
+ gint64 timestamp,
GtkCssStyle *old_style);
void (* invalidate) (GtkCssNode *node);
void (* queue_validate) (GtkCssNode *node);
@@ -140,6 +143,9 @@ GtkCssStyle * gtk_css_node_create_style (GtkCssNode *
void gtk_css_node_invalidate_style_provider
(GtkCssNode *cssnode);
+void gtk_css_node_invalidate_frame_clock
+ (GtkCssNode *cssnode,
+ gboolean just_timestamp);
void gtk_css_node_invalidate (GtkCssNode *cssnode,
GtkCssChange change);
void gtk_css_node_validate (GtkCssNode *cssnode,
diff --git a/gtk/gtkcsstypes.c b/gtk/gtkcsstypes.c
index 46e7c1c..6ab3bc5 100644
--- a/gtk/gtkcsstypes.c
+++ b/gtk/gtkcsstypes.c
@@ -57,7 +57,6 @@ _gtk_css_change_for_sibling (GtkCssChange match)
{ GTK_CSS_CHANGE_POSITION, GTK_CSS_CHANGE_SIBLING_POSITION },
{ GTK_CSS_CHANGE_STATE, GTK_CSS_CHANGE_SIBLING_STATE },
{ GTK_CSS_CHANGE_SOURCE, 0 },
- { GTK_CSS_CHANGE_ANIMATE, 0 },
{ GTK_CSS_CHANGE_PARENT_STYLE, 0 }
};
@@ -77,7 +76,6 @@ _gtk_css_change_for_child (GtkCssChange match)
{ GTK_CSS_CHANGE_SIBLING_POSITION, GTK_CSS_CHANGE_PARENT_SIBLING_POSITION },
{ GTK_CSS_CHANGE_SIBLING_STATE, GTK_CSS_CHANGE_PARENT_SIBLING_STATE },
{ GTK_CSS_CHANGE_SOURCE, 0 },
- { GTK_CSS_CHANGE_ANIMATE, 0 },
{ GTK_CSS_CHANGE_PARENT_STYLE, 0 }
};
diff --git a/gtk/gtkcsstypesprivate.h b/gtk/gtkcsstypesprivate.h
index d2cd6d3..1f68e9c 100644
--- a/gtk/gtkcsstypesprivate.h
+++ b/gtk/gtkcsstypesprivate.h
@@ -51,8 +51,9 @@ typedef enum { /*< skip >*/
GTK_CSS_CHANGE_PARENT_SIBLING_STATE = (1 << 15),
/* add more */
GTK_CSS_CHANGE_SOURCE = (1 << 16),
- GTK_CSS_CHANGE_ANIMATE = (1 << 17),
- GTK_CSS_CHANGE_PARENT_STYLE = (1 << 18),
+ GTK_CSS_CHANGE_PARENT_STYLE = (1 << 17),
+ GTK_CSS_CHANGE_TIMESTAMP = (1 << 18),
+ GTK_CSS_CHANGE_ANIMATIONS = (1 << 19),
GTK_CSS_CHANGE_RESERVED_BIT = (1 << 31) /* Used internally in gtkcssselector.c */
} GtkCssChange;
diff --git a/gtk/gtkcsswidgetnode.c b/gtk/gtkcsswidgetnode.c
index d3ec5a2..1bc2124 100644
--- a/gtk/gtkcsswidgetnode.c
+++ b/gtk/gtkcsswidgetnode.c
@@ -36,14 +36,28 @@ G_DEFINE_TYPE (GtkCssWidgetNode, gtk_css_widget_node, GTK_TYPE_CSS_NODE)
static GtkCssStyle *
gtk_css_widget_node_update_style (GtkCssNode *cssnode,
GtkCssChange pending_change,
+ gint64 timestamp,
GtkCssStyle *old_style)
{
if (old_style == NULL)
- return GTK_CSS_NODE_CLASS (gtk_css_widget_node_parent_class)->update_style (cssnode, pending_change,
old_style);
+ return GTK_CSS_NODE_CLASS (gtk_css_widget_node_parent_class)->update_style (cssnode, pending_change,
timestamp, old_style);
return NULL;
}
+static gboolean
+gtk_css_widget_node_queue_callback (GtkWidget *widget,
+ GdkFrameClock *frame_clock,
+ gpointer user_data)
+{
+ GtkCssNode *node = user_data;
+
+ gtk_css_node_invalidate_frame_clock (node, TRUE);
+ _gtk_container_queue_restyle (GTK_CONTAINER (widget));
+
+ return G_SOURCE_CONTINUE;
+}
+
static void
gtk_css_widget_node_queue_validate (GtkCssNode *node)
{
@@ -52,8 +66,8 @@ gtk_css_widget_node_queue_validate (GtkCssNode *node)
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
if (GTK_IS_RESIZE_CONTAINER (widget_node->widget))
widget_node->validate_cb_id = gtk_widget_add_tick_callback (widget_node->widget,
- (GtkTickCallback)
_gtk_container_queue_restyle,
- NULL,
+ gtk_css_widget_node_queue_callback,
+ node,
NULL);
G_GNUC_END_IGNORE_DEPRECATIONS
}
@@ -128,7 +142,7 @@ gtk_css_widget_node_validate (GtkCssNode *node,
new_static_style = validate_static_style (node, static_style, change);
- if (new_static_style != static_style)
+ if (new_static_style != static_style || (change & GTK_CSS_CHANGE_ANIMATIONS))
{
GtkCssNode *parent = gtk_css_node_get_parent (node);
new_style = gtk_css_animated_style_new (new_static_style,
@@ -139,7 +153,7 @@ gtk_css_widget_node_validate (GtkCssNode *node,
g_object_unref (new_static_style);
}
- else if (GTK_IS_CSS_ANIMATED_STYLE (style))
+ else if (GTK_IS_CSS_ANIMATED_STYLE (style) && (change & GTK_CSS_CHANGE_TIMESTAMP))
{
new_style = gtk_css_animated_style_new_advance (GTK_CSS_ANIMATED_STYLE (style),
static_style,
@@ -264,6 +278,17 @@ gtk_css_widget_node_get_style_provider (GtkCssNode *node)
return gtk_style_context_get_style_provider (gtk_widget_get_style_context (widget_node->widget));
}
+static GdkFrameClock *
+gtk_css_widget_node_get_frame_clock (GtkCssNode *node)
+{
+ GtkCssWidgetNode *widget_node = GTK_CSS_WIDGET_NODE (node);
+
+ if (widget_node->widget == NULL)
+ return NULL;
+
+ return gtk_widget_get_frame_clock (widget_node->widget);
+}
+
static void
gtk_css_widget_node_class_init (GtkCssWidgetNodeClass *klass)
{
@@ -277,6 +302,7 @@ gtk_css_widget_node_class_init (GtkCssWidgetNodeClass *klass)
node_class->create_widget_path = gtk_css_widget_node_create_widget_path;
node_class->get_widget_path = gtk_css_widget_node_get_widget_path;
node_class->get_style_provider = gtk_css_widget_node_get_style_provider;
+ node_class->get_frame_clock = gtk_css_widget_node_get_frame_clock;
}
static void
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index 4800e1e..62b2f59 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -5444,6 +5444,8 @@ gtk_widget_connect_frame_clock (GtkWidget *widget,
gdk_frame_clock_begin_updating (frame_clock);
}
+ gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE);
+
if (priv->context)
gtk_style_context_set_frame_clock (priv->context, frame_clock);
}
@@ -5457,6 +5459,8 @@ gtk_widget_disconnect_frame_clock (GtkWidget *widget,
if (GTK_IS_CONTAINER (widget))
_gtk_container_stop_idle_sizer (GTK_CONTAINER (widget));
+ gtk_css_node_invalidate_frame_clock (priv->cssnode, FALSE);
+
if (priv->clock_tick_id)
{
g_signal_handler_disconnect (frame_clock, priv->clock_tick_id);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]