summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk/gtkscrolledwindow.c43
1 files 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 ();