diff --git a/gdk/macos/gdkmacosdisplay-translate.c b/gdk/macos/gdkmacosdisplay-translate.c index 8e3cd90b82..646ba0cd9e 100644 --- a/gdk/macos/gdkmacosdisplay-translate.c +++ b/gdk/macos/gdkmacosdisplay-translate.c @@ -612,6 +612,8 @@ fill_scroll_event (GdkMacosDisplay *self, GdkModifierType state; GdkDevice *pointer; GdkEvent *ret = NULL; + NSEventPhase phase; + NSEventPhase momentumPhase; GdkSeat *seat; double dx; double dy; @@ -619,6 +621,15 @@ fill_scroll_event (GdkMacosDisplay *self, g_assert (GDK_IS_MACOS_SURFACE (surface)); g_assert (nsevent != NULL); + phase = [nsevent phase]; + momentumPhase = [nsevent momentumPhase]; + + /* Ignore kinetic scroll events from the display server as we already + * handle those internally. + */ + if (phase == 0 && momentumPhase != 0) + return NULL; + seat = gdk_display_get_default_seat (GDK_DISPLAY (self)); pointer = gdk_seat_get_pointer (seat); state = _gdk_macos_display_get_current_mouse_modifiers (self) | @@ -684,19 +695,31 @@ fill_scroll_event (GdkMacosDisplay *self, } else { - g_assert (ret == NULL); - - ret = gdk_scroll_event_new (GDK_SURFACE (surface), - pointer, - NULL, - get_time_from_ns_event (nsevent), - state, - -dx * 32, - -dy * 32, - FALSE); + ret = gdk_scroll_event_new_discrete (GDK_SURFACE (surface), + pointer, + NULL, + get_time_from_ns_event (nsevent), + state, + direction, + FALSE); } } + if (phase == NSEventPhaseEnded || phase == NSEventPhaseCancelled) + { + /* The user must have released their fingers in a touchpad + * scroll, so try to send a scroll is_stop event. + */ + if (ret != NULL) + _gdk_event_queue_append (GDK_DISPLAY (self), g_steal_pointer (&ret)); + ret = gdk_scroll_event_new (GDK_SURFACE (surface), + pointer, + NULL, + get_time_from_ns_event (nsevent), + state, + 0.0, 0.0, TRUE); + } + return g_steal_pointer (&ret); } diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index 49be97080c..1842dcd528 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -1225,16 +1225,15 @@ check_update_scrollbar_proximity (GtkScrolledWindow *sw, } static double -get_scroll_unit (GtkScrolledWindow *sw, - GtkOrientation orientation) +get_scroll_unit (GtkScrolledWindow *sw, + GtkOrientation orientation, + GtkEventControllerScroll *scroll) { - double scroll_unit; - -#ifndef GDK_WINDOWING_MACOS GtkScrolledWindowPrivate *priv = gtk_scrolled_window_get_instance_private (sw); GtkScrollbar *scrollbar; GtkAdjustment *adj; double page_size; + double scroll_unit; if (orientation == GTK_ORIENTATION_HORIZONTAL) scrollbar = GTK_SCROLLBAR (priv->hscrollbar); @@ -1247,8 +1246,16 @@ get_scroll_unit (GtkScrolledWindow *sw, adj = gtk_scrollbar_get_adjustment (scrollbar); page_size = gtk_adjustment_get_page_size (adj); scroll_unit = pow (page_size, 2.0 / 3.0); -#else - scroll_unit = 1; + +#ifdef GDK_WINDOWING_MACOS + { + GdkEvent *event = gtk_event_controller_get_current_event (GTK_EVENT_CONTROLLER (scroll)); + + if (event != NULL && + gdk_event_get_event_type (event) == GDK_SCROLL && + gdk_scroll_event_get_direction (event) == GDK_SCROLL_SMOOTH) + scroll_unit = 1; + } #endif return scroll_unit; @@ -1396,7 +1403,7 @@ scrolled_window_scroll (GtkScrolledWindow *scrolled_window, double scroll_unit; adj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->hscrollbar)); - scroll_unit = get_scroll_unit (scrolled_window, GTK_ORIENTATION_HORIZONTAL); + scroll_unit = get_scroll_unit (scrolled_window, GTK_ORIENTATION_HORIZONTAL, scroll); new_value = priv->unclamped_hadj_value + delta_x * scroll_unit; _gtk_scrolled_window_set_adjustment_value (scrolled_window, adj, @@ -1411,7 +1418,7 @@ scrolled_window_scroll (GtkScrolledWindow *scrolled_window, double scroll_unit; adj = gtk_scrollbar_get_adjustment (GTK_SCROLLBAR (priv->vscrollbar)); - scroll_unit = get_scroll_unit (scrolled_window, GTK_ORIENTATION_VERTICAL); + scroll_unit = get_scroll_unit (scrolled_window, GTK_ORIENTATION_VERTICAL, scroll); new_value = priv->unclamped_vadj_value + delta_y * scroll_unit; _gtk_scrolled_window_set_adjustment_value (scrolled_window, adj, @@ -1469,8 +1476,8 @@ scroll_controller_decelerate (GtkEventControllerScroll *scroll, shifted = (state & GDK_SHIFT_MASK) != 0; - unit_x = get_scroll_unit (scrolled_window, GTK_ORIENTATION_HORIZONTAL); - unit_y = get_scroll_unit (scrolled_window, GTK_ORIENTATION_VERTICAL); + unit_x = get_scroll_unit (scrolled_window, GTK_ORIENTATION_HORIZONTAL, scroll); + unit_y = get_scroll_unit (scrolled_window, GTK_ORIENTATION_VERTICAL, scroll); if (shifted) {