Make outer shadows work again

Change get_render_node to return nodes that are sized to the clip
area and expect to be placed at the clip position; change
gtk_container_propagate_render_node to place child render nodes
accordingly, and change gtk_css_gadget_get_render_node to return
nodes that are sized accordingly as well.
This commit is contained in:
Matthias Clasen 2016-08-12 17:13:52 -04:00 committed by Emmanuele Bassi
parent e0ab6d5a3c
commit f74dd416d6
3 changed files with 37 additions and 43 deletions

View File

@ -3424,7 +3424,7 @@ propagate_render_node (GtkWidget *child,
/* translate coordinates. Ugly business, that. */ /* translate coordinates. Ugly business, that. */
if (!_gtk_widget_get_has_window (GTK_WIDGET (data->container))) if (!_gtk_widget_get_has_window (GTK_WIDGET (data->container)))
{ {
_gtk_widget_get_allocation (GTK_WIDGET (data->container), &allocation); gtk_widget_get_clip (GTK_WIDGET (data->container), &allocation);
x = -allocation.x; x = -allocation.x;
y = -allocation.y; y = -allocation.y;
} }
@ -3452,7 +3452,7 @@ propagate_render_node (GtkWidget *child,
if (!_gtk_widget_get_has_window (child)) if (!_gtk_widget_get_has_window (child))
{ {
_gtk_widget_get_allocation (child, &allocation); gtk_widget_get_clip (child, &allocation);
x += allocation.x; x += allocation.x;
y += allocation.y; y += allocation.y;
} }

View File

@ -67,6 +67,7 @@ struct _GtkCssGadgetPrivate {
GtkWidget *owner; GtkWidget *owner;
GtkAllocation allocated_size; GtkAllocation allocated_size;
gint allocated_baseline; gint allocated_baseline;
GtkAllocation clip;
}; };
enum { enum {
@ -742,6 +743,7 @@ gtk_css_gadget_allocate (GtkCssGadget *gadget,
out_clip->y = 0; out_clip->y = 0;
out_clip->width = 0; out_clip->width = 0;
out_clip->height = 0; out_clip->height = 0;
priv->clip = *out_clip;
return; return;
} }
@ -806,6 +808,8 @@ gtk_css_gadget_allocate (GtkCssGadget *gadget,
allocation->height - margin.top - margin.bottom, allocation->height - margin.top - margin.bottom,
&tmp_clip)) &tmp_clip))
gdk_rectangle_union (&tmp_clip, out_clip, out_clip); gdk_rectangle_union (&tmp_clip, out_clip, out_clip);
priv->clip = *out_clip;
} }
GskRenderNode * GskRenderNode *
@ -814,27 +818,30 @@ gtk_css_gadget_get_render_node (GtkCssGadget *gadget,
gboolean draw_focus) gboolean draw_focus)
{ {
GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget); GtkCssGadgetPrivate *priv = gtk_css_gadget_get_instance_private (gadget);
GtkBorder margin, border, padding; GtkBorder clip, margin, border, padding;
GtkCssStyle *style; GtkCssStyle *style;
cairo_t *cr; cairo_t *cr;
GskRenderNode *box_node, *bg_node, *border_node; GskRenderNode *box_node, *bg_node, *border_node;
graphene_rect_t bounds; graphene_rect_t bounds;
graphene_point3d_t p; int width, height;
graphene_matrix_t m;
int x, y, width, height;
int contents_x, contents_y, contents_width, contents_height; int contents_x, contents_y, contents_width, contents_height;
GtkAllocation margin_box; GtkAllocation margin_box;
GtkAllocation clip_box;
char *str; char *str;
if (!gtk_css_gadget_get_visible (gadget)) if (!gtk_css_gadget_get_visible (gadget))
return NULL; return NULL;
gtk_css_gadget_get_margin_box (gadget, &margin_box); margin_box = priv->allocated_size;
clip_box = priv->clip;
x = margin_box.x; width = clip_box.width;
y = margin_box.y; height = clip_box.height;
width = margin_box.width;
height = margin_box.height; clip.left = margin_box.x - clip_box.x;
clip.top = margin_box.y - clip_box.y;
clip.right = clip_box.width - margin_box.width - clip.left;
clip.bottom = clip_box.height - margin_box.height - clip.top;
if (width < 0 || height < 0) if (width < 0 || height < 0)
{ {
@ -842,21 +849,16 @@ gtk_css_gadget_get_render_node (GtkCssGadget *gadget,
"Did you forget to allocate a size? (node %s owner %s)", "Did you forget to allocate a size? (node %s owner %s)",
gtk_css_node_get_name (gtk_css_gadget_get_node (gadget)), gtk_css_node_get_name (gtk_css_gadget_get_node (gadget)),
G_OBJECT_TYPE_NAME (gtk_css_gadget_get_owner (gadget))); G_OBJECT_TYPE_NAME (gtk_css_gadget_get_owner (gadget)));
x = 0;
y = 0;
width = gtk_widget_get_allocated_width (priv->owner); width = gtk_widget_get_allocated_width (priv->owner);
height = gtk_widget_get_allocated_height (priv->owner); height = gtk_widget_get_allocated_height (priv->owner);
} }
graphene_rect_init (&bounds, 0, 0, width, height); graphene_rect_init (&bounds, 0, 0, width, height);
graphene_point3d_init (&p, x, y, 0);
graphene_matrix_init_translate (&m, &p);
str = g_strconcat ("Box<", G_OBJECT_TYPE_NAME (gtk_css_gadget_get_owner (gadget)), ">", NULL); str = g_strconcat ("Box<", G_OBJECT_TYPE_NAME (gtk_css_gadget_get_owner (gadget)), ">", NULL);
box_node = gsk_renderer_create_render_node (renderer); box_node = gsk_renderer_create_render_node (renderer);
gsk_render_node_set_name (box_node, str); gsk_render_node_set_name (box_node, str);
gsk_render_node_set_bounds (box_node, &bounds); gsk_render_node_set_bounds (box_node, &bounds);
gsk_render_node_set_transform (box_node, &m);
g_free (str); g_free (str);
style = gtk_css_gadget_get_style (gadget); style = gtk_css_gadget_get_style (gadget);
@ -872,10 +874,10 @@ gtk_css_gadget_get_render_node (GtkCssGadget *gadget,
gtk_css_style_render_background (style, gtk_css_style_render_background (style,
cr, cr,
margin.left, clip.left + margin.left,
margin.top, clip.top + margin.top,
width - margin.left - margin.right, width - clip.left - clip.right - margin.left - margin.right,
height - margin.top - margin.bottom, height - clip.top - clip.bottom - margin.top - margin.bottom,
gtk_css_node_get_junction_sides (priv->node)); gtk_css_node_get_junction_sides (priv->node));
cairo_destroy (cr); cairo_destroy (cr);
@ -892,10 +894,10 @@ gtk_css_gadget_get_render_node (GtkCssGadget *gadget,
gtk_css_style_render_border (style, gtk_css_style_render_border (style,
cr, cr,
margin.left, clip.left + margin.left,
margin.top, clip.top + margin.top,
width - margin.left - margin.right, width - clip.left - clip.right - margin.left - margin.right,
height - margin.top - margin.bottom, height - clip.top - clip.bottom - margin.top - margin.bottom,
0, 0,
gtk_css_node_get_junction_sides (priv->node)); gtk_css_node_get_junction_sides (priv->node));
@ -905,10 +907,10 @@ gtk_css_gadget_get_render_node (GtkCssGadget *gadget,
gsk_render_node_append_child (box_node, border_node); gsk_render_node_append_child (box_node, border_node);
gsk_render_node_unref (border_node); gsk_render_node_unref (border_node);
contents_x = margin.left + border.left + padding.left; contents_x = clip.left + margin.left + border.left + padding.left;
contents_y = margin.top + border.top + padding.top; contents_y = clip.top + margin.top + border.top + padding.top;
contents_width = width - margin.left - margin.right - border.left - border.right - padding.left - padding.right; contents_width = width - clip.left - clip.right - margin.left - margin.right - border.left - border.right - padding.left - padding.right;
contents_height = height - margin.top - margin.bottom - border.top - border.bottom - padding.top - padding.bottom; contents_height = height - clip.top - clip.bottom - margin.top - margin.bottom - border.top - border.bottom - padding.top - padding.bottom;
if (contents_width > 0 && contents_height > 0) if (contents_width > 0 && contents_height > 0)
{ {
@ -958,10 +960,10 @@ gtk_css_gadget_get_render_node (GtkCssGadget *gadget,
cr = gsk_render_node_get_draw_context (focus_node); cr = gsk_render_node_get_draw_context (focus_node);
gtk_css_style_render_outline (style, gtk_css_style_render_outline (style,
cr, cr,
margin.left, clip.left + margin.left,
margin.top, clip.top + margin.top,
width - margin.left - margin.right, width - clip.left - clip.right - margin.left - margin.right,
height - margin.top - margin.bottom); height - clip.top - clip.bottom - margin.top - margin.bottom);
g_free (str); g_free (str);
cairo_destroy (cr); cairo_destroy (cr);

View File

@ -15845,20 +15845,15 @@ gtk_widget_create_render_node (GtkWidget *widget,
const char *name) const char *name)
{ {
GskRenderNode *res = gsk_renderer_create_render_node (renderer); GskRenderNode *res = gsk_renderer_create_render_node (renderer);
GtkAllocation allocation, clip; GtkAllocation clip;
graphene_point3d_t p;
graphene_rect_t bounds; graphene_rect_t bounds;
graphene_matrix_t m;
_gtk_widget_get_allocation (widget, &allocation);
gtk_widget_get_clip (widget, &clip); gtk_widget_get_clip (widget, &clip);
graphene_rect_init (&bounds, 0, 0, clip.width, clip.height); graphene_rect_init (&bounds, 0, 0, clip.width, clip.height);
graphene_matrix_init_translate (&m, graphene_point3d_init (&p, allocation.x, allocation.y, 0));
gsk_render_node_set_name (res, name); gsk_render_node_set_name (res, name);
gsk_render_node_set_bounds (res, &bounds); gsk_render_node_set_bounds (res, &bounds);
gsk_render_node_set_transform (res, &m);
return res; return res;
} }
@ -15881,8 +15876,7 @@ gtk_widget_get_render_node (GtkWidget *widget,
gtk_widget_get_clip (widget, &clip); gtk_widget_get_clip (widget, &clip);
_gtk_widget_get_allocation (widget, &alloc); _gtk_widget_get_allocation (widget, &alloc);
graphene_rect_init (&bounds, 0, 0, clip.width, clip.height); graphene_rect_init (&bounds, 0, 0, clip.width, clip.height);
graphene_matrix_init_translate (&m, graphene_point3d_init (&p, alloc.x, alloc.y, 0.f)); graphene_matrix_init_translate (&m, graphene_point3d_init (&p, clip.x, clip.y, 0.f));
graphene_point3d_init (&p, clip.x - alloc.x, clip.y - alloc.y, 0.f);
/* Compatibility mode: if the widget does not have a render node, we draw /* Compatibility mode: if the widget does not have a render node, we draw
* using gtk_widget_draw() on a temporary node * using gtk_widget_draw() on a temporary node
@ -15899,7 +15893,6 @@ gtk_widget_get_render_node (GtkWidget *widget,
gsk_render_node_set_name (tmp, str); gsk_render_node_set_name (tmp, str);
gsk_render_node_set_bounds (tmp, &bounds); gsk_render_node_set_bounds (tmp, &bounds);
gsk_render_node_set_transform (tmp, &m); gsk_render_node_set_transform (tmp, &m);
gsk_render_node_set_anchor_point (tmp, &p);
cr = gsk_render_node_get_draw_context (tmp); cr = gsk_render_node_get_draw_context (tmp);
cairo_translate (cr, alloc.x - clip.x, alloc.y - clip.y); cairo_translate (cr, alloc.x - clip.x, alloc.y - clip.y);
@ -15929,10 +15922,9 @@ gtk_widget_get_render_node (GtkWidget *widget,
tmp = gsk_renderer_create_render_node (renderer); tmp = gsk_renderer_create_render_node (renderer);
gsk_render_node_set_name (tmp, str); gsk_render_node_set_name (tmp, str);
gsk_render_node_set_bounds (tmp, &bounds); gsk_render_node_set_bounds (tmp, &bounds);
gsk_render_node_set_transform (tmp, &m);
gsk_render_node_set_anchor_point (tmp, &p);
cr = gsk_render_node_get_draw_context (tmp); cr = gsk_render_node_get_draw_context (tmp);
cairo_translate (cr, alloc.x - clip.x, alloc.y - clip.y);
g_signal_emit (widget, widget_signals[DRAW], 0, cr, &result); g_signal_emit (widget, widget_signals[DRAW], 0, cr, &result);
cairo_destroy (cr); cairo_destroy (cr);