[gtk/popup-shadow-width] wip: Allow shadows on popovers
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/popup-shadow-width] wip: Allow shadows on popovers
- Date: Mon, 1 Feb 2021 00:27:29 +0000 (UTC)
commit c54ee2023b8b78c9cf66fbc9a908306ba00d0ffd
Author: Matthias Clasen <mclasen redhat com>
Date: Sun Jan 31 19:26:33 2021 -0500
wip: Allow shadows on popovers
Use gdk_popup_layout_set_shadow_width to take shadows into
account when positioning popovers. This doesn't quite work
yet.
gtk/gtkpopover.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++----------
1 file changed, 71 insertions(+), 14 deletions(-)
---
diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c
index c087f58dc5..5c627f39f7 100644
--- a/gtk/gtkpopover.c
+++ b/gtk/gtkpopover.c
@@ -126,6 +126,7 @@
#include "gtkstylecontextprivate.h"
#include "gtkroundedboxprivate.h"
#include "gsk/gskroundedrectprivate.h"
+#include "gtkcssshadowvalueprivate.h"
#define MNEMONICS_DELAY 300 /* ms */
@@ -432,6 +433,9 @@ create_popup_layout (GtkPopover *popover)
GdkAnchorHints anchor_hints;
GdkPopupLayout *layout;
GtkWidget *parent;
+ GtkCssStyle *style;
+ GtkBorder shadow_width;
+ 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,9 +447,17 @@ create_popup_layout (GtkPopover *popover)
rect.height = priv->pointing_to.height;
}
+ 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);
+
+ g_print ("popover shadow %d %d %d %d\n",
+ shadow_width.left, shadow_width.right,
+ shadow_width.top, shadow_width.bottom);
+
switch (priv->position)
{
case GTK_POS_LEFT:
+ shadow_width.right = MAX (0, shadow_width.right - tail_height);
switch (gtk_widget_get_valign (GTK_WIDGET (popover)))
{
case GTK_ALIGN_START:
@@ -470,6 +482,7 @@ create_popup_layout (GtkPopover *popover)
break;
case GTK_POS_RIGHT:
+ shadow_width.left = MAX (0, shadow_width.left - tail_height);
switch (gtk_widget_get_valign (GTK_WIDGET (popover)))
{
case GTK_ALIGN_START:
@@ -494,6 +507,7 @@ create_popup_layout (GtkPopover *popover)
break;
case GTK_POS_TOP:
+ shadow_width.bottom = MAX (0, shadow_width.bottom - tail_height);
switch (gtk_widget_get_halign (GTK_WIDGET (popover)))
{
case GTK_ALIGN_START:
@@ -518,6 +532,7 @@ create_popup_layout (GtkPopover *popover)
break;
case GTK_POS_BOTTOM:
+ shadow_width.top = MAX (0, shadow_width.top - tail_height);
switch (gtk_widget_get_halign (GTK_WIDGET (popover)))
{
case GTK_ALIGN_START:
@@ -549,6 +564,14 @@ create_popup_layout (GtkPopover *popover)
parent_anchor,
surface_anchor);
gdk_popup_layout_set_anchor_hints (layout, anchor_hints);
+ gdk_popup_layout_set_shadow_width (layout,
+ shadow_width.left,
+ shadow_width.right,
+ shadow_width.top,
+ shadow_width.bottom);
+ g_print ("popup shadow %d %d %d %d\n",
+ shadow_width.left, shadow_width.right,
+ shadow_width.top, shadow_width.bottom);
if (priv->x_offset || priv->y_offset)
gdk_popup_layout_set_offset (layout, priv->x_offset, priv->y_offset);
@@ -1302,14 +1325,22 @@ get_minimal_size (GtkPopover *popover,
GtkPositionType pos;
int minimal_size;
int tail_gap_width = priv->has_arrow ? TAIL_GAP_WIDTH : 0;
+ int min_width, min_height;
- 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)) ||
(orientation == GTK_ORIENTATION_VERTICAL && !POS_IS_VERTICAL (pos)))
minimal_size += tail_gap_width;
+ gtk_widget_get_size_request (GTK_WIDGET (popover), &min_width, &min_height);
+
+ if (orientation == GTK_ORIENTATION_HORIZONTAL)
+ minimal_size = MAX (minimal_size, min_width);
+ else
+ minimal_size = MAX (minimal_size, min_height);
+
return minimal_size;
}
@@ -1326,10 +1357,16 @@ 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;
+ GtkCssStyle *style;
+ GtkBorder shadow_width;
+ int extra;
if (for_size >= 0)
for_size -= tail_height;
+ 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);
+
gtk_widget_measure (priv->contents_widget,
orientation, for_size,
minimum, natural,
@@ -1339,8 +1376,18 @@ 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)
+ {
+ extra = MAX (0, tail_height - MIN (shadow_width.left, shadow_width.right));
+ *minimum += shadow_width.left + shadow_width.right + extra;
+ *natural += shadow_width.left + shadow_width.right + extra;
+ }
+ else
+ {
+ extra = MAX (0, tail_height - MIN (shadow_width.top, shadow_width.bottom));
+ *minimum += shadow_width.top + shadow_width.bottom + extra;
+ *natural += shadow_width.top + shadow_width.bottom + extra;
+ }
}
static void
@@ -1353,32 +1400,42 @@ gtk_popover_size_allocate (GtkWidget *widget,
GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
GtkAllocation child_alloc;
int tail_height = priv->has_arrow ? TAIL_HEIGHT : 0;
+ GtkCssStyle *style;
+ GtkBorder shadow_width;
+
+ 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:
- child_alloc.x = tail_height / 2;
- child_alloc.y = 0;
+ 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 + MAX (0, shadow_width.bottom - tail_height));
break;
case GTK_POS_BOTTOM:
- child_alloc.x = tail_height / 2;
- child_alloc.y = tail_height;
+ child_alloc.x = shadow_width.left;
+ child_alloc.y = MAX (0, shadow_width.top - tail_height);
+ child_alloc.width = width - (shadow_width.left + shadow_width.right);
+ child_alloc.height = height - (MAX (0, shadow_width.top - tail_height) + shadow_width.bottom);
break;
case GTK_POS_LEFT:
- child_alloc.x = 0;
- child_alloc.y = tail_height / 2;
+ child_alloc.x = shadow_width.left;
+ child_alloc.y = shadow_width.top;
+ child_alloc.width = width - (shadow_width.left + MAX (0, shadow_width.right - tail_height));
+ child_alloc.height = height - (shadow_width.top + shadow_width.bottom);
break;
case GTK_POS_RIGHT:
- child_alloc.x = tail_height;
- child_alloc.y = tail_height / 2;
+ child_alloc.x = MAX (0, shadow_width.left - tail_height);
+ child_alloc.y = shadow_width.top;
+ child_alloc.width = width - (MAX (0, shadow_width.left - tail_height) + shadow_width.right);
+ child_alloc.height = height - (shadow_width.top + shadow_width.bottom);
break;
default:
break;
}
- child_alloc.width = width - tail_height;
- child_alloc.height = height - tail_height;
-
gtk_widget_size_allocate (priv->contents_widget, &child_alloc, baseline);
if (priv->surface)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]