[gtk/wip/exalm/nested-scrolling: 2/2] scrolledwindow: Support nested scrolling
- From: Alexander Mikhaylenko <alexm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/exalm/nested-scrolling: 2/2] scrolledwindow: Support nested scrolling
- Date: Mon, 14 Dec 2020 15:59:11 +0000 (UTC)
commit f4ac36a912eafa4d88b51ede458c11d3e859bd27
Author: Alexander Mikhaylenko <alexm gnome org>
Date: Mon Dec 14 19:57:38 2020 +0500
scrolledwindow: Support nested scrolling
Since e9fe270e94d6dbae4655f8a31910f9fb7288d457, GtkScrolledWindow handles
only full scroll sequences, but still accepts any scroll sequence, causing
issues with nested scrolling.
Take another step and keep track of the sequence state, checking the
directioon when a smooth scroll starts and only claiming the sequence if
the scrolleed window can scroll in the direction of the current scrolling,
and otherwise denying it and ignoring any further events until it ends.
gtk/gtkscrolledwindow.c | 43 +++++++++++++++++++++++++++++++------------
1 file changed, 31 insertions(+), 12 deletions(-)
---
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index d27d05c432..84eb64abef 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -271,6 +271,8 @@ typedef struct
guint propagate_natural_height : 1;
guint smooth_scroll : 1;
+ GtkEventSequenceState scroll_state;
+
int min_content_width;
int min_content_height;
int max_content_width;
@@ -408,10 +410,10 @@ static void indicator_set_over (Indicator *indicator,
static void install_scroll_cursor (GtkScrolledWindow *scrolled_window);
static void uninstall_scroll_cursor (GtkScrolledWindow *scrolled_window);
-static void scrolled_window_scroll (GtkScrolledWindow *scrolled_window,
- double delta_x,
- double delta_y,
- GtkEventControllerScroll *scroll);
+static gboolean scrolled_window_scroll (GtkScrolledWindow *scrolled_window,
+ double delta_x,
+ double delta_y,
+ GtkEventControllerScroll *scroll);
static guint signals[LAST_SIGNAL] = {0};
static GParamSpec *properties[NUM_PROPERTIES];
@@ -1230,11 +1232,8 @@ captured_scroll_cb (GtkEventControllerScroll *scroll,
gtk_scrolled_window_cancel_deceleration (scrolled_window);
- if (priv->smooth_scroll)
- {
- scrolled_window_scroll (scrolled_window, delta_x, delta_y, scroll);
- return GDK_EVENT_STOP;
- }
+ if (priv->smooth_scroll && priv->scroll_state != GTK_EVENT_SEQUENCE_DENIED)
+ return scrolled_window_scroll (scrolled_window, delta_x, delta_y, scroll);
return GDK_EVENT_PROPAGATE;
}
@@ -1319,7 +1318,7 @@ scroll_controller_scroll_begin (GtkEventControllerScroll *scroll,
priv->smooth_scroll = TRUE;
}
-static void
+static gboolean
scrolled_window_scroll (GtkScrolledWindow *scrolled_window,
double delta_x,
double delta_y,
@@ -1333,6 +1332,18 @@ scrolled_window_scroll (GtkScrolledWindow *scrolled_window,
state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (scroll));
shifted = (state & GDK_SHIFT_MASK) != 0;
+ if (priv->smooth_scroll && priv->scroll_state == GTK_EVENT_SEQUENCE_NONE)
+ {
+ if ((may_hscroll (scrolled_window) && ABS (delta_x) > ABS (delta_y)) ||
+ (may_vscroll (scrolled_window) && ABS (delta_y) >= ABS (delta_x)))
+ priv->scroll_state = GTK_EVENT_SEQUENCE_CLAIMED;
+ else
+ priv->scroll_state = GTK_EVENT_SEQUENCE_DENIED;
+ }
+
+ if (priv->smooth_scroll && priv->scroll_state == GTK_EVENT_SEQUENCE_DENIED)
+ return GDK_EVENT_PROPAGATE;
+
gtk_scrolled_window_invalidate_overshoot (scrolled_window);
if (shifted)
@@ -1388,6 +1399,8 @@ scrolled_window_scroll (GtkScrolledWindow *scrolled_window,
g_source_set_name_by_id (priv->scroll_events_overshoot_id,
"[gtk] start_scroll_deceleration_cb");
}
+
+ return GDK_EVENT_STOP;
}
static gboolean
@@ -1399,8 +1412,8 @@ scroll_controller_scroll (GtkEventControllerScroll *scroll,
GtkScrolledWindowPrivate *priv =
gtk_scrolled_window_get_instance_private (scrolled_window);
- if (!priv->smooth_scroll)
- scrolled_window_scroll (scrolled_window, delta_x, delta_y, scroll);
+ if (!priv->smooth_scroll || priv->scroll_state == GTK_EVENT_SEQUENCE_NONE)
+ return scrolled_window_scroll (scrolled_window, delta_x, delta_y, scroll);
return GDK_EVENT_STOP;
}
@@ -1412,6 +1425,7 @@ scroll_controller_scroll_end (GtkEventControllerScroll *scroll,
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (scrolled_window);
priv->smooth_scroll = FALSE;
+ priv->scroll_state = GTK_EVENT_SEQUENCE_NONE;
uninstall_scroll_cursor (scrolled_window);
}
@@ -1421,10 +1435,13 @@ scroll_controller_decelerate (GtkEventControllerScroll *scroll,
double initial_vel_y,
GtkScrolledWindow *scrolled_window)
{
+ GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (scrolled_window);
double unit_x, unit_y;
gboolean shifted;
GdkModifierType state;
+ if (priv->scroll_state != GTK_EVENT_SEQUENCE_CLAIMED)
+ return;
state = gtk_event_controller_get_current_event_state (GTK_EVENT_CONTROLLER (scroll));
@@ -2003,6 +2020,8 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
priv->max_content_width = -1;
priv->max_content_height = -1;
+ priv->scroll_state = GTK_EVENT_SEQUENCE_NONE;
+
priv->overlay_scrolling = TRUE;
priv->drag_gesture = gtk_gesture_drag_new ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]