Merge branch 'wip/chergert/fix-macos-overshoot' into 'main'

macos: fix kinetic scrolling with overshoot

See merge request GNOME/gtk!4517
This commit is contained in:
Matthias Clasen 2022-02-25 14:37:45 +00:00
commit 1b2c11d7f5
2 changed files with 51 additions and 21 deletions

View File

@ -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);
}

View File

@ -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)
{