[gtk/wip/exalm/popover-shadow] popover: Reserve space for box-shadow
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/exalm/popover-shadow] popover: Reserve space for box-shadow
- Date: Sun, 3 Jan 2021 14:21:34 +0000 (UTC)
commit 09efd3596c9a128d1134b84f8defb3f043767a9e
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Sun Jan 3 19:19:23 2021 +0500
popover: Reserve space for box-shadow
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/1987
gtk/gtkpopover.c | 104 +++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 75 insertions(+), 29 deletions(-)
---
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
index c087f58dc5..5863ed8a00 100644
--- a/gtk/gtkpopover.c
+++ b/gtk/gtkpopover.c
@@ -97,6 +97,7 @@
#include "config.h"
+#include "gtkcssshadowvalueprivate.h"
#include "gtkpopoverprivate.h"
#include "gtkpopovermenuprivate.h"
#include "gtknative.h"
@@ -219,19 +220,54 @@ gtk_popover_native_get_renderer (GtkNative *native)
return priv->renderer;
}
+static void
+get_shadow_width (GtkPopover *popover,
+ GtkBorder *shadow_width)
+{
+ GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
+ GtkCssStyle *style;
+ int tail_height = priv->has_arrow ? TAIL_HEIGHT : 0;
+
+ style = gtk_css_node_get_style (gtk_widget_get_css_node (GTK_WIDGET (priv->contents_widget)));
+
+ gtk_css_shadow_value_get_extents (style->background->box_shadow, shadow_width);
+
+ switch (priv->final_position)
+ {
+ case GTK_POS_TOP:
+ shadow_width->bottom = MAX (shadow_width->bottom, tail_height);
+ break;
+ case GTK_POS_BOTTOM:
+ shadow_width->top = MAX (shadow_width->top, tail_height);
+ break;
+ case GTK_POS_LEFT:
+ shadow_width->right = MAX (shadow_width->right, tail_height);
+ break;
+ case GTK_POS_RIGHT:
+ shadow_width->left = MAX (shadow_width->left, tail_height);
+ break;
+ default:
+ break;
+ }
+}
+
static void
gtk_popover_native_get_surface_transform (GtkNative *native,
double *x,
double *y)
{
+ GtkBorder shadow_width;
GtkCssBoxes css_boxes;
const graphene_rect_t *margin_rect;
+ get_shadow_width (GTK_POPOVER (native), &shadow_width);
gtk_css_boxes_init (&css_boxes, GTK_WIDGET (native));
margin_rect = gtk_css_boxes_get_margin_rect (&css_boxes);
*x = - margin_rect->origin.x;
*y = - margin_rect->origin.y;
+
+ g_print ("WTF %lf %lf\n", *x, *y);
}
static gboolean
@@ -432,6 +468,9 @@ create_popup_layout (GtkPopover *popover)
GdkAnchorHints anchor_hints;
GdkPopupLayout *layout;
GtkWidget *parent;
+ GtkBorder shadow_width;
+ int x_offset, y_offset;
+ int tail_height = priv->has_arrow ? TAIL_HEIGHT : 0;
parent = gtk_widget_get_parent (GTK_WIDGET (popover));
gtk_widget_get_surface_allocation (parent, &rect);
@@ -443,6 +482,11 @@ create_popup_layout (GtkPopover *popover)
rect.height = priv->pointing_to.height;
}
+ x_offset = priv->x_offset;
+ y_offset = priv->y_offset;
+
+ get_shadow_width (popover, &shadow_width);
+
switch (priv->position)
{
case GTK_POS_LEFT:
@@ -451,11 +495,13 @@ create_popup_layout (GtkPopover *popover)
case GTK_ALIGN_START:
parent_anchor = GDK_GRAVITY_NORTH_WEST;
surface_anchor = GDK_GRAVITY_NORTH_EAST;
+ y_offset -= shadow_width.top;
break;
case GTK_ALIGN_END:
parent_anchor = GDK_GRAVITY_SOUTH_WEST;
surface_anchor = GDK_GRAVITY_SOUTH_EAST;
+ y_offset += shadow_width.bottom;
break;
case GTK_ALIGN_FILL:
@@ -466,6 +512,7 @@ create_popup_layout (GtkPopover *popover)
surface_anchor = GDK_GRAVITY_EAST;
break;
}
+ x_offset += shadow_width.right - tail_height;
anchor_hints = GDK_ANCHOR_FLIP_X | GDK_ANCHOR_SLIDE_Y;
break;
@@ -475,11 +522,13 @@ create_popup_layout (GtkPopover *popover)
case GTK_ALIGN_START:
parent_anchor = GDK_GRAVITY_NORTH_EAST;
surface_anchor = GDK_GRAVITY_NORTH_WEST;
+ y_offset -= shadow_width.top;
break;
case GTK_ALIGN_END:
parent_anchor = GDK_GRAVITY_SOUTH_EAST;
surface_anchor = GDK_GRAVITY_SOUTH_WEST;
+ y_offset += shadow_width.bottom;
break;
case GTK_ALIGN_FILL:
@@ -490,6 +539,7 @@ create_popup_layout (GtkPopover *popover)
surface_anchor = GDK_GRAVITY_WEST;
break;
}
+ x_offset -= shadow_width.left - tail_height;
anchor_hints = GDK_ANCHOR_FLIP_X | GDK_ANCHOR_SLIDE_Y;
break;
@@ -499,11 +549,13 @@ create_popup_layout (GtkPopover *popover)
case GTK_ALIGN_START:
parent_anchor = GDK_GRAVITY_NORTH_WEST;
surface_anchor = GDK_GRAVITY_SOUTH_WEST;
+ x_offset -= shadow_width.left;
break;
case GTK_ALIGN_END:
parent_anchor = GDK_GRAVITY_NORTH_EAST;
surface_anchor = GDK_GRAVITY_SOUTH_EAST;
+ x_offset += shadow_width.right;
break;
case GTK_ALIGN_FILL:
@@ -514,6 +566,7 @@ create_popup_layout (GtkPopover *popover)
surface_anchor = GDK_GRAVITY_SOUTH;
break;
}
+ y_offset += shadow_width.bottom - tail_height;
anchor_hints = GDK_ANCHOR_FLIP_Y | GDK_ANCHOR_SLIDE_X;
break;
@@ -523,11 +576,13 @@ create_popup_layout (GtkPopover *popover)
case GTK_ALIGN_START:
parent_anchor = GDK_GRAVITY_SOUTH_WEST;
surface_anchor = GDK_GRAVITY_NORTH_WEST;
+ x_offset -= shadow_width.left;
break;
case GTK_ALIGN_END:
parent_anchor = GDK_GRAVITY_SOUTH_EAST;
surface_anchor = GDK_GRAVITY_NORTH_EAST;
+ x_offset += shadow_width.right;
break;
case GTK_ALIGN_FILL:
@@ -538,6 +593,7 @@ create_popup_layout (GtkPopover *popover)
surface_anchor = GDK_GRAVITY_NORTH;
break;
}
+ y_offset -= shadow_width.top - tail_height;
anchor_hints = GDK_ANCHOR_FLIP_Y | GDK_ANCHOR_SLIDE_X;
break;
@@ -550,8 +606,8 @@ create_popup_layout (GtkPopover *popover)
surface_anchor);
gdk_popup_layout_set_anchor_hints (layout, anchor_hints);
- if (priv->x_offset || priv->y_offset)
- gdk_popup_layout_set_offset (layout, priv->x_offset, priv->y_offset);
+ if (x_offset || y_offset)
+ gdk_popup_layout_set_offset (layout, x_offset, y_offset);
return layout;
}
@@ -1303,7 +1359,7 @@ get_minimal_size (GtkPopover *popover,
int minimal_size;
int tail_gap_width = priv->has_arrow ? TAIL_GAP_WIDTH : 0;
- minimal_size = 2 * get_border_radius (GTK_WIDGET (popover));
+ minimal_size = 2 * get_border_radius (GTK_WIDGET (priv->contents_widget));
pos = priv->position;
if ((orientation == GTK_ORIENTATION_HORIZONTAL && POS_IS_VERTICAL (pos)) ||
@@ -1326,10 +1382,13 @@ gtk_popover_measure (GtkWidget *widget,
GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
int minimal_size;
int tail_height = priv->has_arrow ? TAIL_HEIGHT : 0;
+ GtkBorder shadow_width;
if (for_size >= 0)
for_size -= tail_height;
+ get_shadow_width (popover, &shadow_width);
+
gtk_widget_measure (priv->contents_widget,
orientation, for_size,
minimum, natural,
@@ -1339,8 +1398,13 @@ gtk_popover_measure (GtkWidget *widget,
*minimum = MAX (*minimum, minimal_size);
*natural = MAX (*natural, minimal_size);
- *minimum += tail_height;
- *natural += tail_height;
+ if (orientation == GTK_ORIENTATION_HORIZONTAL) {
+ *minimum += shadow_width.left + shadow_width.right;
+ *natural += shadow_width.left + shadow_width.right;
+ } else {
+ *minimum += shadow_width.top + shadow_width.bottom;
+ *natural += shadow_width.top + shadow_width.bottom;
+ }
}
static void
@@ -1352,32 +1416,14 @@ gtk_popover_size_allocate (GtkWidget *widget,
GtkPopover *popover = GTK_POPOVER (widget);
GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
GtkAllocation child_alloc;
- int tail_height = priv->has_arrow ? TAIL_HEIGHT : 0;
+ GtkBorder shadow_width;
- switch (priv->final_position)
- {
- case GTK_POS_TOP:
- child_alloc.x = tail_height / 2;
- child_alloc.y = 0;
- break;
- case GTK_POS_BOTTOM:
- child_alloc.x = tail_height / 2;
- child_alloc.y = tail_height;
- break;
- case GTK_POS_LEFT:
- child_alloc.x = 0;
- child_alloc.y = tail_height / 2;
- break;
- case GTK_POS_RIGHT:
- child_alloc.x = tail_height;
- child_alloc.y = tail_height / 2;
- break;
- default:
- break;
- }
+ get_shadow_width (popover, &shadow_width);
- child_alloc.width = width - tail_height;
- child_alloc.height = height - tail_height;
+ child_alloc.x = shadow_width.left;
+ child_alloc.y = shadow_width.top;
+ child_alloc.width = width - shadow_width.left - shadow_width.right;
+ child_alloc.height = height - shadow_width.top - shadow_width.bottom;
gtk_widget_size_allocate (priv->contents_widget, &child_alloc, baseline);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]