[gtk/gtk-3-24: 4/5] menu: Adapt scroll offset if arrow is shown
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/gtk-3-24: 4/5] menu: Adapt scroll offset if arrow is shown
- Date: Fri, 18 Jan 2019 22:42:42 +0000 (UTC)
commit c35878ecf1e9ee960b72b213b73c15f92b64afe5
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Thu Jan 17 19:27:51 2019 +0100
menu: Adapt scroll offset if arrow is shown
When a popup is placed using move_to_rect(), it'll get feedback about
the position and size it got assigned. We use this feedback to update
the scroll offset, but while doing so, if the visibility of the arrow
changed, we didn't adapt the offset accordingly.
Fix this by offsetting the provided offset by the height of the arrow,
if it was made visible as a side effect of the scroll offset change
triggered by the feedback.
Related: mutter#105
Closes: #1463
gtk/gtkmenu.c | 74 +++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 52 insertions(+), 22 deletions(-)
---
diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c
index 5b84eab3fa..f079f06e91 100644
--- a/gtk/gtkmenu.c
+++ b/gtk/gtkmenu.c
@@ -213,6 +213,12 @@ enum {
CHILD_PROP_BOTTOM_ATTACH
};
+typedef enum _GtkMenuScrollFlag
+{
+ GTK_MENU_SCROLL_FLAG_NONE = 0,
+ GTK_MENU_SCROLL_FLAG_ADAPT = 1 << 0,
+} GtkMenuScrollFlag;
+
static void gtk_menu_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -255,7 +261,8 @@ static gboolean gtk_menu_enter_notify (GtkWidget *widget,
static gboolean gtk_menu_leave_notify (GtkWidget *widget,
GdkEventCrossing *event);
static void gtk_menu_scroll_to (GtkMenu *menu,
- gint offset);
+ gint offset,
+ GtkMenuScrollFlag flags);
static void gtk_menu_grab_notify (GtkWidget *widget,
gboolean was_grabbed);
static gboolean gtk_menu_captured_event (GtkWidget *widget,
@@ -1977,7 +1984,7 @@ gtk_menu_popup_internal (GtkMenu *menu,
associate_menu_grab_transfer_window (menu);
- gtk_menu_scroll_to (menu, priv->scroll_offset);
+ gtk_menu_scroll_to (menu, priv->scroll_offset, GTK_MENU_SCROLL_FLAG_NONE);
/* if no item is selected, select the first one */
if (!menu_shell->priv->active_menu_item &&
@@ -2479,7 +2486,8 @@ gtk_menu_update_scroll_offset (GtkMenu *menu,
get_arrows_border (menu, &arrows_border);
menu->priv->scroll_offset = arrows_border.top + (final_rect->y - flipped_rect->y);
- gtk_menu_scroll_to (menu, menu->priv->scroll_offset);
+ gtk_menu_scroll_to (menu, menu->priv->scroll_offset,
+ GTK_MENU_SCROLL_FLAG_ADAPT);
}
/**
@@ -2552,7 +2560,8 @@ gtk_menu_popdown (GtkMenu *menu)
* non-tearoff menu was popped down.
*/
if (!priv->tearoff_active)
- gtk_menu_scroll_to (menu, priv->saved_scroll_offset);
+ gtk_menu_scroll_to (menu, priv->saved_scroll_offset,
+ GTK_MENU_SCROLL_FLAG_NONE);
priv->tearoff_active = TRUE;
}
else
@@ -2843,7 +2852,7 @@ gtk_menu_scrollbar_changed (GtkAdjustment *adjustment,
value = gtk_adjustment_get_value (adjustment);
if (menu->priv->scroll_offset != value)
- gtk_menu_scroll_to (menu, value);
+ gtk_menu_scroll_to (menu, value, GTK_MENU_SCROLL_FLAG_NONE);
}
static void
@@ -3036,7 +3045,7 @@ gtk_menu_set_tearoff_state (GtkMenu *menu,
gtk_widget_show (GTK_WIDGET (menu));
gtk_widget_show (priv->tearoff_window);
- gtk_menu_scroll_to (menu, 0);
+ gtk_menu_scroll_to (menu, 0, GTK_MENU_SCROLL_FLAG_NONE);
}
else
@@ -3482,7 +3491,7 @@ gtk_menu_size_allocate (GtkWidget *widget,
height = allocation->height - (2 * border_width) - padding.top - padding.bottom;
if (menu_shell->priv->active)
- gtk_menu_scroll_to (menu, priv->scroll_offset);
+ gtk_menu_scroll_to (menu, priv->scroll_offset, GTK_MENU_SCROLL_FLAG_NONE);
get_arrows_border (menu, &arrow_border);
@@ -3590,7 +3599,7 @@ gtk_menu_size_allocate (GtkWidget *widget,
gtk_widget_hide (priv->tearoff_scrollbar);
gtk_menu_set_tearoff_hints (menu, allocation->width);
- gtk_menu_scroll_to (menu, 0);
+ gtk_menu_scroll_to (menu, 0, GTK_MENU_SCROLL_FLAG_NONE);
}
}
else
@@ -4168,7 +4177,7 @@ gtk_menu_scroll_by (GtkMenu *menu,
offset = priv->requested_height - view_height;
if (offset != priv->scroll_offset)
- gtk_menu_scroll_to (menu, offset);
+ gtk_menu_scroll_to (menu, offset, GTK_MENU_SCROLL_FLAG_NONE);
}
static gboolean
@@ -4678,7 +4687,7 @@ gtk_menu_captured_event (GtkWidget *widget,
MIN (priv->scroll_offset, 0),
MAX (priv->scroll_offset, priv->requested_height - view_height));
- gtk_menu_scroll_to (menu, offset);
+ gtk_menu_scroll_to (menu, offset, GTK_MENU_SCROLL_FLAG_NONE);
retval = TRUE;
}
@@ -5323,11 +5332,26 @@ gtk_menu_stop_scrolling (GtkMenu *menu)
}
static void
-gtk_menu_scroll_to (GtkMenu *menu,
- gint offset)
+sync_arrows_state (GtkMenu *menu)
{
GtkMenuPrivate *priv = menu->priv;
GtkCssNode *top_arrow_node, *bottom_arrow_node;
+
+ top_arrow_node = gtk_css_gadget_get_node (priv->top_arrow_gadget);
+ gtk_css_node_set_visible (top_arrow_node, priv->upper_arrow_visible);
+ gtk_css_node_set_state (top_arrow_node, priv->upper_arrow_state);
+
+ bottom_arrow_node = gtk_css_gadget_get_node (priv->bottom_arrow_gadget);
+ gtk_css_node_set_visible (bottom_arrow_node, priv->lower_arrow_visible);
+ gtk_css_node_set_state (bottom_arrow_node, priv->lower_arrow_state);
+}
+
+static void
+gtk_menu_scroll_to (GtkMenu *menu,
+ gint offset,
+ GtkMenuScrollFlag flags)
+{
+ GtkMenuPrivate *priv = menu->priv;
GtkBorder arrow_border, padding;
GtkWidget *widget;
gint x, y;
@@ -5363,13 +5387,25 @@ gtk_menu_scroll_to (GtkMenu *menu,
{
GtkStateFlags upper_arrow_previous_state = priv->upper_arrow_state;
GtkStateFlags lower_arrow_previous_state = priv->lower_arrow_state;
+ gboolean should_offset_by_arrow;
if (!priv->upper_arrow_visible || !priv->lower_arrow_visible)
gtk_widget_queue_draw (GTK_WIDGET (menu));
+ if (!priv->upper_arrow_visible &
+ flags & GTK_MENU_SCROLL_FLAG_ADAPT)
+ should_offset_by_arrow = TRUE;
+ else
+ should_offset_by_arrow = FALSE;
+
priv->upper_arrow_visible = priv->lower_arrow_visible = TRUE;
+ if (flags & GTK_MENU_SCROLL_FLAG_ADAPT)
+ sync_arrows_state (menu);
+
get_arrows_border (menu, &arrow_border);
+ if (should_offset_by_arrow)
+ offset += arrow_border.top;
y += arrow_border.top;
view_height -= arrow_border.top;
view_height -= arrow_border.bottom;
@@ -5436,13 +5472,7 @@ gtk_menu_scroll_to (GtkMenu *menu,
}
}
- top_arrow_node = gtk_css_gadget_get_node (priv->top_arrow_gadget);
- gtk_css_node_set_visible (top_arrow_node, priv->upper_arrow_visible);
- gtk_css_node_set_state (top_arrow_node, priv->upper_arrow_state);
-
- bottom_arrow_node = gtk_css_gadget_get_node (priv->bottom_arrow_gadget);
- gtk_css_node_set_visible (bottom_arrow_node, priv->lower_arrow_visible);
- gtk_css_node_set_state (bottom_arrow_node, priv->lower_arrow_state);
+ sync_arrows_state (menu);
/* Scroll the menu: */
if (gtk_widget_get_realized (widget))
@@ -5528,7 +5558,7 @@ gtk_menu_scroll_item_visible (GtkMenuShell *menu_shell,
* is on the menu
*/
menu_shell->priv->ignore_enter = TRUE;
- gtk_menu_scroll_to (menu, child_offset);
+ gtk_menu_scroll_to (menu, child_offset, GTK_MENU_SCROLL_FLAG_NONE);
}
else
{
@@ -5549,7 +5579,7 @@ gtk_menu_scroll_item_visible (GtkMenuShell *menu_shell,
* is on the menu
*/
menu_shell->priv->ignore_enter = TRUE;
- gtk_menu_scroll_to (menu, y);
+ gtk_menu_scroll_to (menu, y, GTK_MENU_SCROLL_FLAG_NONE);
}
}
}
@@ -6033,7 +6063,7 @@ gtk_menu_real_move_scroll (GtkMenu *menu,
new_offset = priv->scroll_offset + step;
new_offset = CLAMP (new_offset, 0, end_position - page_size);
- gtk_menu_scroll_to (menu, new_offset);
+ gtk_menu_scroll_to (menu, new_offset, GTK_MENU_SCROLL_FLAG_NONE);
if (menu_shell->priv->active_menu_item)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]