diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2018-06-27 14:18:50 +0200 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2018-07-30 13:14:12 +0200 |
commit | 71762d3b28b510ca29fd58113264585f7dfc37b9 (patch) | |
tree | 98d833e06b96e18e11f2dc92d8a461d5bf54ec5e | |
parent | f15224926a83d5877b4256ff3595baa23155e3ab (diff) | |
download | gtk+-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.c | 141 |
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++) { |