wayland: add gdk_event_is_scroll_stop_event()

And use it to handle kinetic scrolling in the GtkScrolledWindow.

However, dropping the delta check causes the X11-based kinetic
scroll to break since we don't have the stop event here. Correct handling of
xf86-input-libinput-based scroll events is still being discussed.

https://bugzilla.gnome.org/show_bug.cgi?id=756729
This commit is contained in:
Peter Hutterer 2015-10-21 10:14:40 +10:00 committed by Carlos Garnacho
parent 3fca36169a
commit 48aa1bb08f
6 changed files with 49 additions and 3 deletions

View File

@ -859,6 +859,7 @@ gdk_event_get_keyval
gdk_event_get_root_coords
gdk_event_get_scroll_direction
gdk_event_get_scroll_deltas
gdk_event_is_scroll_stop_event
gdk_event_get_state
gdk_event_get_time
gdk_event_get_window

View File

@ -562,6 +562,7 @@ gdk_event_new (GdkEventType type)
new_event->scroll.y_root = 0.;
new_event->scroll.delta_x = 0.;
new_event->scroll.delta_y = 0.;
new_event->scroll.is_stop = FALSE;
break;
case GDK_ENTER_NOTIFY:
case GDK_LEAVE_NOTIFY:
@ -1418,6 +1419,28 @@ gdk_event_get_scroll_deltas (const GdkEvent *event,
return fetched;
}
/**
* gdk_event_is_scroll_stop_event
* @event: a #GdkEvent
*
* Check whether a scroll event is a stop scroll event. Scroll sequences
* with smooth scroll information may provide a stop scroll event once the
* interaction with the device finishes, e.g. by lifting a finger. This
* stop scroll event is the signal that a widget may trigger kinetic
* scrolling based on the current velocity.
*
* Stop scroll events always have a a delta of 0/0.
*
* Returns: %TRUE if the event is a scroll stop event
*
* Since: 3.20
*/
gboolean
gdk_event_is_scroll_stop_event (const GdkEvent *event)
{
return event->scroll.is_stop;
}
/**
* gdk_event_get_axis:
* @event: a #GdkEvent

View File

@ -824,6 +824,7 @@ struct _GdkEventScroll
gdouble x_root, y_root;
gdouble delta_x;
gdouble delta_y;
guint is_stop : 1;
};
/**
@ -1377,6 +1378,9 @@ gboolean gdk_event_get_scroll_deltas (const GdkEvent *event,
gdouble *delta_x,
gdouble *delta_y);
GDK_AVAILABLE_IN_3_20
gboolean gdk_event_is_scroll_stop_event (const GdkEvent *event);
GDK_AVAILABLE_IN_ALL
gboolean gdk_event_get_axis (const GdkEvent *event,
GdkAxisUse axis_use,

View File

@ -9328,6 +9328,7 @@ proxy_button_event (GdkEvent *source_event,
event->scroll.device = source_event->scroll.device;
event->scroll.delta_x = source_event->scroll.delta_x;
event->scroll.delta_y = source_event->scroll.delta_y;
event->scroll.is_stop = source_event->scroll.is_stop;
gdk_event_set_source_device (event, source_device);
return TRUE;

View File

@ -62,6 +62,7 @@ struct _GdkWaylandPointerFrameData
/* Specific to the scroll event */
gdouble delta_x, delta_y;
int32_t discrete_x, discrete_y;
gint8 is_scroll_stop;
};
struct _GdkWaylandSeat
@ -972,7 +973,8 @@ flush_discrete_scroll_event (GdkWaylandSeat *seat,
static void
flush_smooth_scroll_event (GdkWaylandSeat *seat,
gdouble delta_x,
gdouble delta_y)
gdouble delta_y,
gboolean is_stop)
{
GdkEvent *event;
@ -980,6 +982,7 @@ flush_smooth_scroll_event (GdkWaylandSeat *seat,
event->scroll.direction = GDK_SCROLL_SMOOTH;
event->scroll.delta_x = delta_x;
event->scroll.delta_y = delta_y;
event->scroll.is_stop = is_stop;
_gdk_wayland_display_deliver_event (seat->display, event);
}
@ -988,6 +991,8 @@ static void
flush_scroll_event (GdkWaylandSeat *seat,
GdkWaylandPointerFrameData *pointer_frame)
{
gboolean is_stop = FALSE;
if (pointer_frame->discrete_x || pointer_frame->discrete_y)
{
GdkScrollDirection direction;
@ -1004,14 +1009,24 @@ flush_scroll_event (GdkWaylandSeat *seat,
flush_discrete_scroll_event (seat, direction);
}
/* Axes can stop independently, if we stop on one axis but have a
* delta on the other, we don't count it as a stop event.
*/
if (pointer_frame->is_scroll_stop &&
pointer_frame->delta_x == 0 &&
pointer_frame->delta_y == 0)
is_stop = TRUE;
flush_smooth_scroll_event (seat,
pointer_frame->delta_x,
pointer_frame->delta_y);
pointer_frame->delta_y,
is_stop);
pointer_frame->delta_x = 0;
pointer_frame->delta_y = 0;
pointer_frame->discrete_x = 0;
pointer_frame->discrete_y = 0;
pointer_frame->is_scroll_stop = FALSE;
}
static void
@ -1369,6 +1384,8 @@ pointer_handle_axis_stop (void *data,
g_return_if_reached ();
}
pointer_frame->is_scroll_stop = TRUE;
GDK_NOTE (EVENTS,
g_message ("axis stop, seat %p", seat));
}

View File

@ -3321,7 +3321,7 @@ gtk_scrolled_window_scroll_event (GtkWidget *widget,
* after scrolling finished, start kinetic scrolling when this
* happens.
*/
if (delta_y == 0 && delta_x == 0)
if (gdk_event_is_scroll_stop_event ((GdkEvent *) event))
{
handled = TRUE;
start_deceleration = TRUE;