diff --git a/gdk/gdkevents.c b/gdk/gdkevents.c index 127e92e547..2ce9b8b72a 100644 --- a/gdk/gdkevents.c +++ b/gdk/gdkevents.c @@ -597,7 +597,8 @@ _gdk_event_unqueue (GdkDisplay *display) /* * If the last N events in the event queue are smooth scroll events - * for the same surface and device, combine them into one. + * for the same surface, the same device and the same scroll unit, + * combine them into one. * * We give the remaining event a history with N items, and deltas * that are the sum over the history entries. @@ -611,6 +612,8 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display) GdkEvent *last_event = NULL; GList *scrolls = NULL; GArray *history = NULL; + GdkScrollUnit scroll_unit = GDK_SCROLL_UNIT_WHEEL; + gboolean scroll_unit_defined = FALSE; GdkTimeCoord hist; l = g_queue_peek_tail_link (&display->queued_events); @@ -618,6 +621,7 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display) while (l) { GdkEvent *event = l->data; + GdkScrollEvent *scroll_event = (GdkScrollEvent *) event; if (event->flags & GDK_EVENT_PENDING) break; @@ -634,11 +638,17 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display) device != event->device) break; + if (scroll_unit_defined && + scroll_unit != scroll_event->unit) + break; + if (!last_event) last_event = event; surface = event->surface; device = event->device; + scroll_unit = scroll_event->unit; + scroll_unit_defined = TRUE; scrolls = l; l = l->prev; @@ -710,7 +720,8 @@ gdk_event_queue_handle_scroll_compression (GdkDisplay *display) gdk_event_get_modifier_state (old_event), dx, dy, - gdk_scroll_event_is_stop (old_event)); + gdk_scroll_event_is_stop (old_event), + scroll_unit); ((GdkScrollEvent *)event)->history = history; @@ -2334,7 +2345,8 @@ gdk_scroll_event_new (GdkSurface *surface, GdkModifierType state, double delta_x, double delta_y, - gboolean is_stop) + gboolean is_stop, + GdkScrollUnit unit) { GdkScrollEvent *self = gdk_event_alloc (GDK_SCROLL, surface, device, time); @@ -2344,6 +2356,7 @@ gdk_scroll_event_new (GdkSurface *surface, self->delta_x = delta_x; self->delta_y = delta_y; self->is_stop = is_stop; + self->unit = unit; return (GdkEvent *) self; } @@ -2363,6 +2376,7 @@ gdk_scroll_event_new_discrete (GdkSurface *surface, self->state = state; self->direction = direction; self->pointer_emulated = emulated; + self->unit = GDK_SCROLL_UNIT_WHEEL; return (GdkEvent *) self; } @@ -2396,6 +2410,9 @@ gdk_scroll_event_get_direction (GdkEvent *event) * * The deltas will be zero unless the scroll direction * is %GDK_SCROLL_SMOOTH. + * + * For the representation unit of these deltas, see + * [method@Gdk.ScrollEvent.get_unit]. */ void gdk_scroll_event_get_deltas (GdkEvent *event, @@ -2438,6 +2455,31 @@ gdk_scroll_event_is_stop (GdkEvent *event) return self->is_stop; } +/** + * gdk_scroll_event_get_unit: + * @event: (type GdkScrollEvent): a scroll event. + * + * Extracts the scroll delta unit of a scroll event. + * + * The unit will always be %GDK_SCROLL_UNIT_WHEEL if the scroll direction is not + * %GDK_SCROLL_SMOOTH. + * + * Returns: the scroll unit. + * + * Since: 4.8 + */ +GdkScrollUnit +gdk_scroll_event_get_unit (GdkEvent *event) +{ + GdkScrollEvent *self = (GdkScrollEvent *) event; + + g_return_val_if_fail (GDK_IS_EVENT (event), GDK_SCROLL_UNIT_WHEEL); + g_return_val_if_fail (GDK_IS_EVENT_TYPE (event, GDK_SCROLL), + GDK_SCROLL_UNIT_WHEEL); + + return self->unit; +} + /* }}} */ /* {{{ GdkTouchpadEvent */ diff --git a/gdk/gdkevents.h b/gdk/gdkevents.h index 99fecbc689..21259f172d 100644 --- a/gdk/gdkevents.h +++ b/gdk/gdkevents.h @@ -265,6 +265,37 @@ typedef enum GDK_SCROLL_SMOOTH } GdkScrollDirection; +/** + * GdkScrollUnit: + * @GDK_SCROLL_UNIT_WHEEL: The delta is in number of wheel clicks. + * @GDK_SCROLL_UNIT_SURFACE: The delta is in surface pixels to scroll directly + * on screen. + * + * Specifies the unit of scroll deltas. + * + * When you get %GDK_SCROLL_UNIT_WHEEL, a delta of 1.0 means 1 wheel detent + * click in the south direction, 2.0 means 2 wheel detent clicks in the south + * direction... This is the same logic for negative values but in the north + * direction. + * + * If you get %GDK_SCROLL_UNIT_SURFACE, are managing a scrollable view and get a + * value of 123, you have to scroll 123 surface logical pixels right if it's + * @delta_x or down if it's @delta_y. This is the same logic for negative values + * but you have to scroll left instead of right if it's @delta_x and up instead + * of down if it's @delta_y. + * + * 1 surface logical pixel is equal to 1 real screen pixel multiplied by the + * final scale factor of your graphical interface (the product of the desktop + * scale factor and eventually a custom scale factor in your app). + * + * Since: 4.8 + */ +typedef enum +{ + GDK_SCROLL_UNIT_WHEEL, + GDK_SCROLL_UNIT_SURFACE +} GdkScrollUnit; + /** * GdkNotifyType: * @GDK_NOTIFY_ANCESTOR: the surface is entered from an ancestor or @@ -395,6 +426,8 @@ GDK_AVAILABLE_IN_ALL void gdk_scroll_event_get_deltas (GdkEvent *event, double *delta_x, double *delta_y); +GDK_AVAILABLE_IN_4_8 +GdkScrollUnit gdk_scroll_event_get_unit (GdkEvent *event); GDK_AVAILABLE_IN_ALL gboolean gdk_scroll_event_is_stop (GdkEvent *event); diff --git a/gdk/gdkeventsprivate.h b/gdk/gdkeventsprivate.h index a16fc0f654..3b1bcd4b94 100644 --- a/gdk/gdkeventsprivate.h +++ b/gdk/gdkeventsprivate.h @@ -212,6 +212,7 @@ struct _GdkTouchEvent * @history: (element-type GdkTimeCoord): array of times and deltas * for other scroll events that were compressed before delivering the * current event + * @unit: The scroll unit in which delta_x and delta_y are represented. * * Generated from button presses for the buttons 4 to 7. Wheel mice are * usually configured to generate button press events for buttons 4 and 5 @@ -234,6 +235,7 @@ struct _GdkScrollEvent gboolean is_stop; GdkDeviceTool *tool; GArray *history; /* */ + GdkScrollUnit unit; }; /* @@ -486,7 +488,8 @@ GdkEvent * gdk_scroll_event_new (GdkSurface *surface, GdkModifierType state, double delta_x, double delta_y, - gboolean is_stop); + gboolean is_stop, + GdkScrollUnit unit); GdkEvent * gdk_scroll_event_new_discrete (GdkSurface *surface, GdkDevice *device, diff --git a/gdk/macos/gdkmacosdisplay-translate.c b/gdk/macos/gdkmacosdisplay-translate.c index 7a0b84ccdb..9192bb2bd0 100644 --- a/gdk/macos/gdkmacosdisplay-translate.c +++ b/gdk/macos/gdkmacosdisplay-translate.c @@ -665,7 +665,8 @@ fill_scroll_event (GdkMacosDisplay *self, state, -sx, -sy, - FALSE); + FALSE, + GDK_SCROLL_UNIT_SURFACE); /* Fall through for scroll emulation */ } @@ -714,7 +715,8 @@ fill_scroll_event (GdkMacosDisplay *self, NULL, get_time_from_ns_event (nsevent), state, - 0.0, 0.0, TRUE); + 0.0, 0.0, TRUE, + GDK_SCROLL_UNIT_SURFACE); } return g_steal_pointer (&ret); diff --git a/gdk/wayland/gdkdevice-wayland.c b/gdk/wayland/gdkdevice-wayland.c index 9c21a6a989..2446bddab3 100644 --- a/gdk/wayland/gdkdevice-wayland.c +++ b/gdk/wayland/gdkdevice-wayland.c @@ -1416,7 +1416,8 @@ flush_smooth_scroll_event (GdkWaylandSeat *seat, seat->pointer_info.time, device_get_modifiers (seat->logical_pointer), delta_x, delta_y, - is_stop); + is_stop, + GDK_SCROLL_UNIT_SURFACE); _gdk_wayland_display_deliver_event (seat->display, event); } @@ -1755,10 +1756,10 @@ pointer_handle_axis (void *data, switch (axis) { case WL_POINTER_AXIS_VERTICAL_SCROLL: - pointer_frame->delta_y = wl_fixed_to_double (value) / 10.0; + pointer_frame->delta_y = wl_fixed_to_double (value); break; case WL_POINTER_AXIS_HORIZONTAL_SCROLL: - pointer_frame->delta_x = wl_fixed_to_double (value) / 10.0; + pointer_frame->delta_x = wl_fixed_to_double (value); break; default: g_return_if_reached (); @@ -1768,7 +1769,7 @@ pointer_handle_axis (void *data, GDK_SEAT_NOTE (seat, EVENTS, g_message ("scroll, axis %s, value %f, seat %p", - get_axis_name (axis), wl_fixed_to_double (value) / 10.0, + get_axis_name (axis), wl_fixed_to_double (value), seat)); if (display->seat_version < WL_POINTER_HAS_FRAME) @@ -3994,7 +3995,8 @@ tablet_tool_handle_wheel (void *data, tablet->pointer_info.time, device_get_modifiers (tablet->logical_device), 0, clicks, - FALSE); + FALSE, + GDK_SCROLL_UNIT_WHEEL); _gdk_wayland_display_deliver_event (seat->display, event); diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index debc66e5d7..39b16c3319 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -2742,7 +2742,8 @@ gdk_event_translate (MSG *msg, build_pointer_event_state (msg), delta_x, delta_y, - FALSE); + FALSE, + GDK_SCROLL_UNIT_WHEEL); /* Append the discrete version too */ direction = 0; diff --git a/gdk/x11/gdkdevicemanager-xi2.c b/gdk/x11/gdkdevicemanager-xi2.c index 72b99a2f90..214f6b1ea2 100644 --- a/gdk/x11/gdkdevicemanager-xi2.c +++ b/gdk/x11/gdkdevicemanager-xi2.c @@ -1778,7 +1778,8 @@ gdk_x11_device_manager_xi2_translate_event (GdkEventTranslator *translator, state, delta_x, delta_y, - delta_x == 0.0 && delta_y == 0.0); + delta_x == 0.0 && delta_y == 0.0, + GDK_SCROLL_UNIT_WHEEL); } break; }