[gtk/wip/matthiasc/popup5: 151/152] popover: Don't constantly redraw the beak
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/matthiasc/popup5: 151/152] popover: Don't constantly redraw the beak
- Date: Sun, 26 May 2019 05:32:16 +0000 (UTC)
commit c4c2ce9408edd1d26d80760eeb09753e70d30491
Author: Matthias Clasen <mclasen redhat com>
Date: Sat May 25 23:11:30 2019 +0000
popover: Don't constantly redraw the beak
We don't want to constantly draw the arrow
if we don't have to. Save the render node
to achieve this.
gtk/gtkpopover.c | 113 ++++++++++++++++++++++++++++++++++---------------------
1 file changed, 71 insertions(+), 42 deletions(-)
---
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
index 0a44ec3958..267fad09c8 100644
--- a/gtk/gtkpopover.c
+++ b/gtk/gtkpopover.c
@@ -158,6 +158,7 @@ typedef struct {
GtkWidget *contents_widget;
GtkCssNode *arrow_node;
+ GskRenderNode *arrow_render_node;
GdkRectangle final_rect;
GtkPositionType final_position;
@@ -509,6 +510,9 @@ node_style_changed_cb (GtkCssNode *node,
GtkCssStyleChange *change,
GtkWidget *widget)
{
+ GtkPopoverPrivate *priv = gtk_popover_get_instance_private (GTK_POPOVER (widget));
+ g_clear_pointer (&priv->arrow_render_node, gsk_render_node_unref);
+
if (gtk_css_style_change_affects (change, GTK_CSS_AFFECTS_SIZE))
gtk_widget_queue_resize (widget);
else
@@ -657,7 +661,11 @@ surface_transform_changed_cb (GtkWidget *widget,
const graphene_matrix_t *transform,
gpointer user_data)
{
- move_to_rect (GTK_POPOVER (user_data));
+ GtkPopover *popover = GTK_POPOVER (widget);
+ GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
+
+ move_to_rect (popover);
+ g_clear_pointer (&priv->arrow_render_node, gsk_render_node_unref);
return G_SOURCE_CONTINUE;
}
@@ -735,6 +743,7 @@ gtk_popover_dispose (GObject *object)
}
g_clear_pointer (&priv->contents_widget, gtk_widget_unparent);
+ g_clear_pointer (&priv->arrow_render_node, gsk_render_node_unref);
G_OBJECT_CLASS (gtk_popover_parent_class)->dispose (object);
}
@@ -1111,63 +1120,83 @@ gtk_popover_size_allocate (GtkWidget *widget,
gtk_widget_size_allocate (priv->contents_widget, &child_alloc, baseline);
if (priv->surface)
- gtk_popover_update_shape (popover);
+ {
+ gtk_popover_update_shape (popover);
+ g_clear_pointer (&priv->arrow_render_node, gsk_render_node_unref);
+ }
}
static void
-gtk_popover_snapshot (GtkWidget *widget,
- GtkSnapshot *snapshot)
+create_arrow_render_node (GtkPopover *popover)
{
- GtkPopover *popover = GTK_POPOVER (widget);
GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
+ GtkWidget *widget = GTK_WIDGET (popover);
+ GtkStyleContext *context;
+ GtkBorder border;
+ cairo_t *cr;
+ GtkSnapshot *snapshot;
- gtk_widget_snapshot_child (widget, priv->contents_widget, snapshot);
+ snapshot = gtk_snapshot_new ();
- if (priv->has_arrow)
- {
- GtkStyleContext *context;
- GtkBorder border;
- cairo_t *cr;
+ cr = gtk_snapshot_append_cairo (snapshot,
+ &GRAPHENE_RECT_INIT (
+ 0, 0,
+ gtk_widget_get_width (widget),
+ gtk_widget_get_height (widget)
+ ));
+
+ /* Clip to the arrow shape */
+ cairo_save (cr);
+ gtk_popover_apply_tail_path (popover, cr);
+ cairo_clip (cr);
+
+ context = gtk_widget_get_style_context (widget);
+ gtk_style_context_save_to_node (context, priv->arrow_node);
+ gtk_style_context_get_border (context, &border);
- cr = gtk_snapshot_append_cairo (snapshot,
- &GRAPHENE_RECT_INIT (
- 0, 0,
- gtk_widget_get_width (widget),
- gtk_widget_get_height (widget)
- ));
+ /* Render the arrow background */
+ gtk_render_background (context, cr,
+ 0, 0,
+ gtk_widget_get_width (widget),
+ gtk_widget_get_height (widget));
- /* Clip to the arrow shape */
- cairo_save (cr);
+ /* Render the border of the arrow tip */
+ if (border.bottom > 0)
+ {
+ GdkRGBA *border_color;
+
+ gtk_style_context_get (context, "border-color", &border_color, NULL);
gtk_popover_apply_tail_path (popover, cr);
- cairo_clip (cr);
+ gdk_cairo_set_source_rgba (cr, border_color);
- context = gtk_widget_get_style_context (widget);
- gtk_style_context_save_to_node (context, priv->arrow_node);
- gtk_style_context_get_border (context, &border);
+ cairo_set_line_width (cr, border.bottom + 1);
+ cairo_stroke (cr);
+ gdk_rgba_free (border_color);
+ }
- /* Render the arrow background */
- gtk_render_background (context, cr,
- 0, 0,
- gtk_widget_get_width (widget),
- gtk_widget_get_height (widget));
+ cairo_restore (cr);
+ cairo_destroy (cr);
- /* Render the border of the arrow tip */
- if (border.bottom > 0)
- {
- GdkRGBA *border_color;
+ gtk_style_context_restore (context);
- gtk_style_context_get (context, "border-color", &border_color, NULL);
- gtk_popover_apply_tail_path (popover, cr);
- gdk_cairo_set_source_rgba (cr, border_color);
+ priv->arrow_render_node = gtk_snapshot_free_to_node (snapshot);
+}
- cairo_set_line_width (cr, border.bottom + 1);
- cairo_stroke (cr);
- gdk_rgba_free (border_color);
- }
+static void
+gtk_popover_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
+{
+ GtkPopover *popover = GTK_POPOVER (widget);
+ GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
- cairo_restore (cr);
- cairo_destroy (cr);
- gtk_style_context_restore (context);
+ gtk_widget_snapshot_child (widget, priv->contents_widget, snapshot);
+
+ if (priv->has_arrow)
+ {
+ if (!priv->arrow_render_node)
+ create_arrow_render_node (popover);
+
+ gtk_snapshot_append_node (snapshot, priv->arrow_render_node);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]