GtkPopover: Honor widget margins when calculating tail position

If there are widget margins set, the whole popover will be displaced.
However the calculation of the tail position doesn't have this into
account, ending up with the tail being detached from the popover if
the margin grew too big.

We should not render the arrows invariably next to the GdkWindow edge,
but optionally displaced inside it depending on the widget margins.
Fixes the gtk3-demo "Popovers" demo case, whose GtkEntry popovers set
widget margins for some reason.

https://bugzilla.gnome.org/show_bug.cgi?id=767851
This commit is contained in:
Carlos Garnacho 2016-06-21 12:24:05 +02:00
parent 3724592efb
commit ed227f9e7b

View File

@ -683,7 +683,7 @@ gtk_popover_get_gap_coords (GtkPopover *popover,
GtkAllocation allocation; GtkAllocation allocation;
gint border_radius; gint border_radius;
GtkStyleContext *context; GtkStyleContext *context;
GtkBorder margin, border; GtkBorder margin, border, widget_margin;
GtkStateFlags state; GtkStateFlags state;
gtk_popover_get_pointing_to (popover, &rect); gtk_popover_get_pointing_to (popover, &rect);
@ -709,11 +709,18 @@ gtk_popover_get_gap_coords (GtkPopover *popover,
get_margin (widget, &margin); get_margin (widget, &margin);
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
rect.x += gtk_widget_get_margin_start (widget); {
widget_margin.left = gtk_widget_get_margin_start (widget);
widget_margin.right = gtk_widget_get_margin_end (widget);
}
else else
rect.x += gtk_widget_get_margin_end (widget); {
widget_margin.left = gtk_widget_get_margin_end (widget);
widget_margin.right = gtk_widget_get_margin_start (widget);
}
rect.y += gtk_widget_get_margin_top (widget); widget_margin.top = gtk_widget_get_margin_top (widget);
widget_margin.bottom = gtk_widget_get_margin_bottom (widget);
context = gtk_widget_get_style_context (widget); context = gtk_widget_get_style_context (widget);
state = gtk_style_context_get_state (context); state = gtk_style_context_get_state (context);
@ -727,20 +734,20 @@ gtk_popover_get_gap_coords (GtkPopover *popover,
if (pos == GTK_POS_BOTTOM || pos == GTK_POS_RIGHT) if (pos == GTK_POS_BOTTOM || pos == GTK_POS_RIGHT)
{ {
base = TAIL_HEIGHT + ((pos == GTK_POS_BOTTOM) ? border.top : border.left); tip = ((pos == GTK_POS_BOTTOM) ? border.top + widget_margin.top : border.left + widget_margin.left);
tip = 0; base = tip + TAIL_HEIGHT;
gap_side = (priv->final_position == GTK_POS_BOTTOM) ? GTK_POS_TOP : GTK_POS_LEFT; gap_side = (priv->final_position == GTK_POS_BOTTOM) ? GTK_POS_TOP : GTK_POS_LEFT;
} }
else if (pos == GTK_POS_TOP) else if (pos == GTK_POS_TOP)
{ {
base = allocation.height - TAIL_HEIGHT - border.bottom; base = allocation.height - TAIL_HEIGHT - border.bottom - widget_margin.bottom;
tip = allocation.height; tip = base + TAIL_HEIGHT;
gap_side = GTK_POS_BOTTOM; gap_side = GTK_POS_BOTTOM;
} }
else if (pos == GTK_POS_LEFT) else if (pos == GTK_POS_LEFT)
{ {
base = allocation.width - TAIL_HEIGHT - border.right; base = allocation.width - TAIL_HEIGHT - border.right - widget_margin.right;
tip = allocation.width; tip = base + TAIL_HEIGHT;
gap_side = GTK_POS_RIGHT; gap_side = GTK_POS_RIGHT;
} }
else else
@ -748,7 +755,7 @@ gtk_popover_get_gap_coords (GtkPopover *popover,
if (POS_IS_VERTICAL (pos)) if (POS_IS_VERTICAL (pos))
{ {
tip_pos = rect.x + (rect.width / 2); tip_pos = rect.x + (rect.width / 2) + widget_margin.left;
initial_x = CLAMP (tip_pos - TAIL_GAP_WIDTH / 2, initial_x = CLAMP (tip_pos - TAIL_GAP_WIDTH / 2,
border_radius + margin.left + TAIL_HEIGHT, border_radius + margin.left + TAIL_HEIGHT,
allocation.width - TAIL_GAP_WIDTH - margin.right - border_radius - TAIL_HEIGHT); allocation.width - TAIL_GAP_WIDTH - margin.right - border_radius - TAIL_HEIGHT);
@ -764,7 +771,7 @@ gtk_popover_get_gap_coords (GtkPopover *popover,
} }
else else
{ {
tip_pos = rect.y + (rect.height / 2); tip_pos = rect.y + (rect.height / 2) + widget_margin.top;
initial_x = base; initial_x = base;
initial_y = CLAMP (tip_pos - TAIL_GAP_WIDTH / 2, initial_y = CLAMP (tip_pos - TAIL_GAP_WIDTH / 2,