summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2018-06-27 14:18:50 +0200
committerCarlos Garnacho <carlosg@gnome.org>2018-07-30 13:14:12 +0200
commit71762d3b28b510ca29fd58113264585f7dfc37b9 (patch)
tree98d833e06b96e18e11f2dc92d8a461d5bf54ec5e
parentf15224926a83d5877b4256ff3595baa23155e3ab (diff)
downloadgtk+-71762d3b28b510ca29fd58113264585f7dfc37b9.tar.gz
gtkscrolledwindow: Use controller for motion capturing
Perform scrollbar visibility checks through a motion controller, always based on GtkScrolledView-relative coordinates. The captured event handler remains though, for a tiny bit of GDK_SCROLL event handling.
-rw-r--r--gtk/gtkscrolledwindow.c141
1 files changed, 60 insertions, 81 deletions
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 2849042466..90d7b2fdfe 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -1052,17 +1052,16 @@ indicator_set_over (Indicator *indicator,
}
static gboolean
-event_close_to_indicator (GtkScrolledWindow *sw,
- Indicator *indicator,
- GdkEvent *event)
+coords_close_to_indicator (GtkScrolledWindow *sw,
+ Indicator *indicator,
+ gdouble x,
+ gdouble y)
{
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (sw);
graphene_rect_t indicator_bounds;
- gdouble x, y;
gint distance;
gtk_widget_compute_bounds (indicator->scrollbar, GTK_WIDGET (sw), &indicator_bounds);
- gdk_event_get_coords (event, &x, &y);
if (indicator->over)
distance = INDICATOR_FAR_DISTANCE;
@@ -1099,25 +1098,18 @@ enable_over_timeout_cb (gpointer user_data)
static gboolean
check_update_scrollbar_proximity (GtkScrolledWindow *sw,
Indicator *indicator,
- GdkEvent *event)
+ GtkWidget *target,
+ gdouble x,
+ gdouble y)
{
GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (sw);
gboolean indicator_close, on_scrollbar, on_other_scrollbar;
- GtkWidget *event_target;
- GtkWidget *event_target_ancestor;
- GdkEventType event_type;
-
- event_target = gtk_get_event_target (event);
- event_target_ancestor = gtk_widget_get_ancestor (event_target, GTK_TYPE_SCROLLBAR);
- event_type = gdk_event_get_event_type (event);
- indicator_close = event_close_to_indicator (sw, indicator, event);
- on_scrollbar = (event_target_ancestor == indicator->scrollbar &&
- event_type != GDK_LEAVE_NOTIFY);
+ indicator_close = coords_close_to_indicator (sw, indicator, x, y);
+ on_scrollbar = (target == indicator->scrollbar);
on_other_scrollbar = (!on_scrollbar &&
- event_type != GDK_LEAVE_NOTIFY &&
- (event_target_ancestor == priv->hindicator.scrollbar ||
- event_target_ancestor == priv->vindicator.scrollbar));
+ (target == priv->hindicator.scrollbar ||
+ target == priv->vindicator.scrollbar));
if (indicator->over_timeout_id)
{
@@ -1173,83 +1165,64 @@ captured_event_cb (GtkWidget *widget,
GdkEvent *event)
{
GtkScrolledWindow *sw = GTK_SCROLLED_WINDOW (widget);
- GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (sw);
- GdkInputSource input_source;
- GdkDevice *source_device;
- GtkWidget *event_target;
- GtkWidget *event_target_ancestor;
- gboolean on_scrollbar;
- GdkEventType event_type;
- guint state;
- GdkCrossingMode mode;
- source_device = gdk_event_get_source_device (event);
- event_type = gdk_event_get_event_type (event);
+ if (gdk_event_get_event_type (event) == GDK_SCROLL)
+ gtk_scrolled_window_cancel_deceleration (sw);
- if (event_type == GDK_SCROLL)
- {
- gtk_scrolled_window_cancel_deceleration (sw);
- return GDK_EVENT_PROPAGATE;
- }
+ return GDK_EVENT_PROPAGATE;
+}
- if (!priv->use_indicators)
- return GDK_EVENT_PROPAGATE;
+static void
+captured_motion (GtkScrolledWindow *sw,
+ gdouble x,
+ gdouble y)
+{
+ GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (sw);
+ GdkDevice *source_device;
+ GdkInputSource input_source;
+ GdkModifierType state;
+ GdkEvent *event;
- if (event_type != GDK_MOTION_NOTIFY &&
- event_type != GDK_LEAVE_NOTIFY)
- return GDK_EVENT_PROPAGATE;
+ if (!priv->use_indicators)
+ return;
+ event = gtk_get_current_event ();
+ source_device = gdk_event_get_source_device (event);
input_source = gdk_device_get_source (source_device);
- if (input_source == GDK_SOURCE_KEYBOARD ||
- input_source == GDK_SOURCE_TOUCHSCREEN)
- return GDK_EVENT_PROPAGATE;
+ if (priv->hscrollbar_visible)
+ indicator_start_fade (&priv->hindicator, 1.0);
+ if (priv->vscrollbar_visible)
+ indicator_start_fade (&priv->vindicator, 1.0);
- event_target = gtk_get_event_target (event);
- event_target_ancestor = gtk_widget_get_ancestor (event_target, GTK_TYPE_SCROLLBAR);
- on_scrollbar = (event_target_ancestor == priv->hindicator.scrollbar ||
- event_target_ancestor == priv->vindicator.scrollbar);
- gdk_event_get_crossing_mode (event, &mode);
+ gdk_event_get_state (event, &state);
- if (event_type == GDK_MOTION_NOTIFY)
+ if (!gtk_get_event_target_with_type (event, GTK_TYPE_SCROLLBAR) &&
+ (state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) != 0)
+ {
+ indicator_set_over (&priv->hindicator, FALSE);
+ indicator_set_over (&priv->vindicator, FALSE);
+ }
+ else if (input_source == GDK_SOURCE_PEN ||
+ input_source == GDK_SOURCE_ERASER ||
+ input_source == GDK_SOURCE_TRACKPOINT)
{
- if (priv->hscrollbar_visible)
- indicator_start_fade (&priv->hindicator, 1.0);
- if (priv->vscrollbar_visible)
- indicator_start_fade (&priv->vindicator, 1.0);
+ indicator_set_over (&priv->hindicator, TRUE);
+ indicator_set_over (&priv->vindicator, TRUE);
+ }
+ else
+ {
+ GtkWidget *target;
- gdk_event_get_state (event, &state);
+ target = gtk_get_event_target_with_type (event, GTK_TYPE_SCROLLBAR);
- if (!on_scrollbar &&
- (state &
- (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) != 0)
- {
- indicator_set_over (&priv->hindicator, FALSE);
- indicator_set_over (&priv->vindicator, FALSE);
- }
- else if (input_source == GDK_SOURCE_PEN ||
- input_source == GDK_SOURCE_ERASER ||
- input_source == GDK_SOURCE_TRACKPOINT)
- {
- indicator_set_over (&priv->hindicator, TRUE);
- indicator_set_over (&priv->vindicator, TRUE);
- }
+ if (!check_update_scrollbar_proximity (sw, &priv->vindicator, target, x, y))
+ check_update_scrollbar_proximity (sw, &priv->hindicator, target, x, y);
else
- {
- if (!check_update_scrollbar_proximity (sw, &priv->vindicator, event))
- check_update_scrollbar_proximity (sw, &priv->hindicator, event);
- else
- indicator_set_over (&priv->hindicator, FALSE);
- }
- }
- else if (event_type == GDK_LEAVE_NOTIFY && on_scrollbar &&
- mode == GDK_CROSSING_UNGRAB)
- {
- check_update_scrollbar_proximity (sw, &priv->vindicator, event);
- check_update_scrollbar_proximity (sw, &priv->hindicator, event);
+ indicator_set_over (&priv->hindicator, FALSE);
}
- return GDK_EVENT_PROPAGATE;
+ g_object_unref (event);
}
static gboolean
@@ -1978,6 +1951,12 @@ gtk_scrolled_window_init (GtkScrolledWindow *scrolled_window)
_gtk_widget_set_captured_event_handler (widget, captured_event_cb);
+ controller = gtk_event_controller_motion_new ();
+ gtk_event_controller_set_propagation_phase (controller, GTK_PHASE_CAPTURE);
+ g_signal_connect_swapped (controller, "motion",
+ G_CALLBACK (captured_motion), scrolled_window);
+ gtk_widget_add_controller (widget, controller);
+
widget_node = gtk_widget_get_css_node (widget);
for (i = 0; i < 4; i++)
{