summaryrefslogtreecommitdiff
path: root/gtk/gtkwidget.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtk/gtkwidget.c')
-rw-r--r--gtk/gtkwidget.c70
1 files changed, 50 insertions, 20 deletions
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index e03535fd7c..504daf8a64 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -6369,6 +6369,18 @@ gtk_cairo_set_marked_for_draw (cairo_t *cr,
cairo_set_user_data (cr, &mark_for_draw_key, NULL, NULL);
}
+static GskRenderer *
+gtk_widget_get_renderer (GtkWidget *widget)
+{
+ GtkWidget *toplevel;
+
+ toplevel = _gtk_widget_get_toplevel (widget);
+ if (_gtk_widget_is_toplevel (toplevel))
+ return gtk_window_get_renderer (GTK_WINDOW (toplevel));
+
+ return NULL;
+}
+
/**
* gtk_cairo_should_draw_window:
* @cr: a cairo context
@@ -6436,6 +6448,7 @@ gtk_widget_draw_internal (GtkWidget *widget,
if (gdk_cairo_get_clip_rectangle (cr, NULL))
{
+ GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS (widget);
GdkWindow *event_window = NULL;
gboolean result;
gboolean push_group;
@@ -6468,17 +6481,46 @@ gtk_widget_draw_internal (GtkWidget *widget,
g_warning ("%s %p is drawn without a current allocation. This should not happen.", G_OBJECT_TYPE_NAME (widget), widget);
#endif
- if (g_signal_has_handler_pending (widget, widget_signals[DRAW], 0, FALSE))
+ /* If the widget uses GSK render nodes then we need a fallback path to
+ * render on the Cairo context; otherwise we just go through the old
+ * GtkWidget::draw path
+ */
+ if (widget_class->get_render_node != NULL)
{
- g_signal_emit (widget, widget_signals[DRAW],
- 0, cr,
- &result);
+ GskRenderer *renderer = gtk_widget_get_renderer (widget);
+ GskRenderer *fallback;
+ graphene_rect_t viewport;
+ GskRenderNode *node;
+
+ graphene_rect_init (&viewport,
+ widget->priv->clip.x,
+ widget->priv->clip.y,
+ widget->priv->clip.width,
+ widget->priv->clip.height);
+ fallback = gsk_renderer_create_fallback (renderer, &viewport, cr);
+ node = gtk_widget_get_render_node (widget, fallback);
+ if (node != NULL)
+ {
+ gsk_renderer_render (fallback, node, NULL);
+ gsk_render_node_unref (node);
+ }
+
+ g_object_unref (fallback);
}
- else if (GTK_WIDGET_GET_CLASS (widget)->draw)
+ else
{
- cairo_save (cr);
- GTK_WIDGET_GET_CLASS (widget)->draw (widget, cr);
- cairo_restore (cr);
+ if (g_signal_has_handler_pending (widget, widget_signals[DRAW], 0, FALSE))
+ {
+ g_signal_emit (widget, widget_signals[DRAW],
+ 0, cr,
+ &result);
+ }
+ else if (GTK_WIDGET_GET_CLASS (widget)->draw)
+ {
+ cairo_save (cr);
+ GTK_WIDGET_GET_CLASS (widget)->draw (widget, cr);
+ cairo_restore (cr);
+ }
}
#ifdef G_ENABLE_DEBUG
@@ -16052,18 +16094,6 @@ gtk_widget_reset_controllers (GtkWidget *widget)
}
}
-GskRenderer *
-gtk_widget_get_renderer (GtkWidget *widget)
-{
- GtkWidget *toplevel;
-
- toplevel = _gtk_widget_get_toplevel (widget);
- if (_gtk_widget_is_toplevel (toplevel))
- return gtk_window_get_renderer (GTK_WINDOW (toplevel));
-
- return NULL;
-}
-
GskRenderNode *
gtk_widget_create_render_node (GtkWidget *widget,
GskRenderer *renderer,