From 56e018b91ca7bb671c2fb511360684d29c389c9f Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Mon, 2 Apr 2018 08:34:08 +0200 Subject: [PATCH] widget: Remove GtkWidget.draw vfunc Widgets are exclusively snapshot now. The draw signal still exists. --- gtk/gtkwidget.c | 260 ++++++++---------------------------------------- gtk/gtkwidget.h | 3 - 2 files changed, 40 insertions(+), 223 deletions(-) diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index d3d60fa51a..4ea1838e3c 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -963,7 +963,6 @@ gtk_widget_class_init (GtkWidgetClass *klass) klass->direction_changed = gtk_widget_real_direction_changed; klass->grab_notify = NULL; klass->child_notify = NULL; - klass->draw = NULL; klass->snapshot = gtk_widget_real_snapshot; klass->mnemonic_activate = gtk_widget_real_mnemonic_activate; klass->grab_focus = gtk_widget_real_grab_focus; @@ -1688,7 +1687,7 @@ gtk_widget_class_init (GtkWidgetClass *klass) g_signal_new (I_("draw"), G_TYPE_FROM_CLASS (gobject_class), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GtkWidgetClass, draw), + 0, _gtk_boolean_handled_accumulator, NULL, gtk_widget_draw_marshaller, G_TYPE_BOOLEAN, 1, @@ -5232,153 +5231,6 @@ gtk_widget_get_renderer (GtkWidget *widget) return NULL; } -typedef enum { - RENDER_SNAPSHOT, - RENDER_DRAW -} RenderMode; - -static RenderMode -get_render_mode (GtkWidgetClass *klass) -{ - GtkWidgetClass *parent_class; - - for (parent_class = g_type_class_peek_parent (klass); - parent_class != gtk_widget_parent_class; - parent_class = g_type_class_peek_parent (klass)) - { - if (klass->snapshot != parent_class->snapshot) - return RENDER_SNAPSHOT; - else if (klass->draw != parent_class->draw) - return RENDER_DRAW; - - klass = parent_class; - } - - return RENDER_SNAPSHOT; -} - -static void -gtk_widget_draw_internal (GtkWidget *widget, - cairo_t *cr) -{ - if (!_gtk_widget_is_drawable (widget)) - return; - - cairo_rectangle (cr, - 0, 0, - widget->priv->allocation.width, - widget->priv->allocation.height); - cairo_clip (cr); - - if (gdk_cairo_get_clip_rectangle (cr, NULL)) - { - GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS (widget); - GdkSurface *event_surface = NULL; - gboolean result; - RenderMode mode; - -#ifdef G_ENABLE_CONSISTENCY_CHECKS - if (_gtk_widget_get_alloc_needed (widget)) - g_warning ("%s %p is drawn without a current allocation. This should not happen.", G_OBJECT_TYPE_NAME (widget), widget); -#endif - - /* 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 - */ - mode = get_render_mode (widget_class); - - if (mode == RENDER_SNAPSHOT) - { - GtkSnapshot *snapshot; - GskRenderNode *node; - - snapshot = gtk_snapshot_new (FALSE, "Fallback<%s>", G_OBJECT_TYPE_NAME (widget)); - gtk_widget_snapshot (widget, snapshot); - node = gtk_snapshot_free_to_node (snapshot); - if (node != NULL) - { - gsk_render_node_draw (node, cr); - gsk_render_node_unref (node); - } - } - else - { - gboolean push_group = - widget->priv->alpha != 255 && !_gtk_widget_is_toplevel (widget); - - if (push_group) - cairo_push_group (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); - } - - if (push_group) - { - cairo_pop_group_to_source (cr); - cairo_set_operator (cr, CAIRO_OPERATOR_OVER); - cairo_paint_with_alpha (cr, widget->priv->alpha / 255.0); - } - } - -#ifdef G_ENABLE_DEBUG - if (GTK_DISPLAY_DEBUG_CHECK (gtk_widget_get_display (widget), BASELINES)) - { - gint baseline = gtk_widget_get_allocated_baseline (widget); - gint width = gtk_widget_get_allocated_width (widget); - - if (baseline != -1) - { - cairo_save (cr); - cairo_new_path (cr); - cairo_move_to (cr, 0, baseline+0.5); - cairo_line_to (cr, width, baseline+0.5); - cairo_set_line_width (cr, 1.0); - cairo_set_source_rgba (cr, 1.0, 0, 0, 0.25); - cairo_stroke (cr); - cairo_restore (cr); - } - } - if (widget->priv->highlight_resize) - { - GtkAllocation alloc; - gtk_widget_get_allocation (widget, &alloc); - - cairo_rectangle (cr, 0, 0, alloc.width, alloc.height); - cairo_set_source_rgba (cr, 1, 0, 0, 0.2); - cairo_fill (cr); - - gtk_widget_queue_draw (widget); - - widget->priv->highlight_resize = FALSE; - } -#endif - - if (cairo_status (cr) && - event_surface != NULL) - { - /* We check the event so we only warn about internal GTK+ calls. - * Errors might come from PDF streams having write failures and - * we don't want to spam stderr in that case. - * We do want to catch errors from - */ - g_warning ("drawing failure for widget '%s': %s", - G_OBJECT_TYPE_NAME (widget), - cairo_status_to_string (cairo_status (cr))); - } - } -} - static gboolean gtk_widget_real_key_press_event (GtkWidget *widget, GdkEventKey *event) @@ -13483,7 +13335,6 @@ gtk_widget_create_render_node (GtkWidget *widget, GtkWidgetClass *klass = GTK_WIDGET_GET_CLASS (widget); GtkWidgetPrivate *priv = widget->priv; GtkCssValue *filter_value; - RenderMode mode; double opacity; GtkCssStyle *style; GtkAllocation allocation; @@ -13492,11 +13343,6 @@ gtk_widget_create_render_node (GtkWidget *widget, snapshot = gtk_snapshot_new_child (parent_snapshot, "%s<%p>", gtk_widget_get_name (widget), widget); - /* Compatibility mode: if the widget does not have a render node, we draw - * using gtk_widget_draw() on a temporary node - */ - mode = get_render_mode (klass); - filter_value = _gtk_style_context_peek_property (_gtk_widget_get_style_context (widget), GTK_CSS_PROPERTY_FILTER); gtk_css_filter_value_push_snapshot (filter_value, snapshot); @@ -13508,8 +13354,35 @@ gtk_widget_create_render_node (GtkWidget *widget, _gtk_widget_get_allocation (widget, &allocation); - if (mode == RENDER_DRAW) + if (opacity < 1.0) + gtk_snapshot_push_opacity (snapshot, opacity, "Opacity<%s,%f>", G_OBJECT_TYPE_NAME (widget), opacity); + + if (!GTK_IS_WINDOW (widget)) { + gtk_snapshot_offset (snapshot, margin.left, margin.top); + gtk_css_style_snapshot_background (style, + snapshot, + allocation.width - margin.left - margin.right, + allocation.height - margin.top - margin.bottom); + gtk_css_style_snapshot_border (style, + snapshot, + allocation.width - margin.left - margin.right, + allocation.height - margin.top - margin.bottom); + gtk_snapshot_offset (snapshot, - margin.left, - margin.top); + } + + /* Offset to content allocation */ + gtk_snapshot_offset (snapshot, margin.left + padding.left + border.left, margin.top + border.top + padding.top); + if (gtk_widget_get_width (widget) > 0 && gtk_widget_get_height (widget) > 0) + klass->snapshot (widget, snapshot); + gtk_snapshot_offset (snapshot, - (margin.left + padding.left + border.left), -(margin.top + border.top + padding.top)); + + if (g_signal_has_handler_pending (widget, widget_signals[DRAW], 0, FALSE)) + { + /* Compatibility mode: if there's a ::draw signal handler, we add a + * child node with the contents of the handler + */ + gboolean result; cairo_t *cr; graphene_rect_t bounds; cairo_rectangle_int_t offset_clip; @@ -13526,74 +13399,21 @@ gtk_widget_create_render_node (GtkWidget *widget, offset_clip.height); cr = gtk_snapshot_append_cairo (snapshot, - &bounds, "Fallback<%s>", - G_OBJECT_TYPE_NAME (widget)); - gtk_widget_draw_internal (widget, cr); + &bounds, + "DrawSignalContents<%s>", G_OBJECT_TYPE_NAME (widget)); + g_signal_emit (widget, widget_signals[DRAW], 0, cr, &result); cairo_destroy (cr); } - else - { - if (opacity < 1.0) - gtk_snapshot_push_opacity (snapshot, opacity, "Opacity<%s,%f>", G_OBJECT_TYPE_NAME (widget), opacity); - if (!GTK_IS_WINDOW (widget)) - { - gtk_snapshot_offset (snapshot, margin.left, margin.top); - gtk_css_style_snapshot_background (style, - snapshot, - allocation.width - margin.left - margin.right, - allocation.height - margin.top - margin.bottom); - gtk_css_style_snapshot_border (style, - snapshot, - allocation.width - margin.left - margin.right, - allocation.height - margin.top - margin.bottom); - gtk_snapshot_offset (snapshot, - margin.left, - margin.top); - } + gtk_snapshot_offset (snapshot, margin.left, margin.top); + gtk_css_style_snapshot_outline (style, + snapshot, + allocation.width - margin.left - margin.right, + allocation.height - margin.top - margin.bottom); + gtk_snapshot_offset (snapshot, - margin.left, - margin.top); - /* Offset to content allocation */ - gtk_snapshot_offset (snapshot, margin.left + padding.left + border.left, margin.top + border.top + padding.top); - if (gtk_widget_get_width (widget) > 0 && gtk_widget_get_height (widget) > 0) - klass->snapshot (widget, snapshot); - gtk_snapshot_offset (snapshot, - (margin.left + padding.left + border.left), -(margin.top + border.top + padding.top)); - - if (g_signal_has_handler_pending (widget, widget_signals[DRAW], 0, FALSE)) - { - /* Compatibility mode: if there's a ::draw signal handler, we add a - * child node with the contents of the handler - */ - gboolean result; - cairo_t *cr; - graphene_rect_t bounds; - cairo_rectangle_int_t offset_clip; - - offset_clip.x = 0; - offset_clip.y = 0; - offset_clip.width = priv->allocation.width; - offset_clip.height = priv->allocation.height; - - graphene_rect_init (&bounds, - offset_clip.x, - offset_clip.y, - offset_clip.width, - offset_clip.height); - - cr = gtk_snapshot_append_cairo (snapshot, - &bounds, - "DrawSignalContents<%s>", G_OBJECT_TYPE_NAME (widget)); - g_signal_emit (widget, widget_signals[DRAW], 0, cr, &result); - cairo_destroy (cr); - } - - gtk_snapshot_offset (snapshot, margin.left, margin.top); - gtk_css_style_snapshot_outline (style, - snapshot, - allocation.width - margin.left - margin.right, - allocation.height - margin.top - margin.bottom); - gtk_snapshot_offset (snapshot, - margin.left, - margin.top); - - if (opacity < 1.0) - gtk_snapshot_pop (snapshot); - } + if (opacity < 1.0) + gtk_snapshot_pop (snapshot); gtk_css_filter_value_pop_snapshot (filter_value, snapshot); diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index bac9e4d8c3..2892bc8eaa 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -164,7 +164,6 @@ struct _GtkWidget * when it becomes unshadowed due to a grab being removed. * @child_notify: Signal emitted for each child property that has * changed on an object. - * @draw: Signal emitted when a widget is supposed to render itself. * @get_request_mode: This allows a widget to tell its parent container whether * it prefers to be allocated in %GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH or * %GTK_SIZE_REQUEST_WIDTH_FOR_HEIGHT mode. @@ -268,8 +267,6 @@ struct _GtkWidgetClass gboolean was_grabbed); void (* child_notify) (GtkWidget *widget, GParamSpec *child_property); - gboolean (* draw) (GtkWidget *widget, - cairo_t *cr); /* size requests */ GtkSizeRequestMode (* get_request_mode) (GtkWidget *widget);