From 5671709590e778cb3af83b2aa33bd112e1fd66fe Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 8 Dec 2021 10:04:31 +0800 Subject: [PATCH 1/3] Send scroll stop events to xwidgets correctly * src/xterm.c (handle_one_xevent): Record stop events manually. * src/xwidget.h (xwidget_scroll): * src/xwidget.c (xwidget_scroll): New parameter `stop_p'. --- src/xterm.c | 9 +++++++-- src/xwidget.c | 7 +++---- src/xwidget.h | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index 3f7b9560345..ae0daa79f31 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -9851,6 +9851,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XIValuatorState *states; double *values; bool found_valuator = false; + bool any_stop_p = false; /* A fake XMotionEvent for x_note_mouse_movement. */ XMotionEvent ev; @@ -10003,9 +10004,13 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (val->horizontal) xv_total_x += delta; else - xv_total_y += -delta; + xv_total_y += delta; found_valuator = true; + + if (delta == 0.0) + any_stop_p = true; + continue; } #endif @@ -10092,7 +10097,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (found_valuator) xwidget_scroll (xv, xev->event_x, xev->event_y, xv_total_x, xv_total_y, xev->mods.effective, - xev->time); + xev->time, any_stop_p); else xwidget_motion_notify (xv, xev->event_x, xev->event_y, xev->mods.effective, xev->time); diff --git a/src/xwidget.c b/src/xwidget.c index 9b9f364ce40..d8510ef9286 100644 --- a/src/xwidget.c +++ b/src/xwidget.c @@ -1062,7 +1062,8 @@ xwidget_motion_notify (struct xwidget_view *view, void xwidget_scroll (struct xwidget_view *view, double x, double y, - double dx, double dy, uint state, Time time) + double dx, double dy, uint state, Time time, + bool stop_p) { GdkEvent *xg_event; GtkWidget *target; @@ -1097,9 +1098,7 @@ xwidget_scroll (struct xwidget_view *view, double x, double y, xg_event->scroll.delta_x = dx; xg_event->scroll.delta_y = dy; xg_event->scroll.device = find_suitable_pointer (view->frame); - - if (!(fabs (dx) > 0) || !(fabs (dy) > 0)) - xg_event->scroll.is_stop = TRUE; + xg_event->scroll.is_stop = stop_p; g_object_ref (xg_event->any.window); diff --git a/src/xwidget.h b/src/xwidget.h index f2d497c0920..a03006fde9a 100644 --- a/src/xwidget.h +++ b/src/xwidget.h @@ -199,7 +199,7 @@ extern void xwidget_motion_or_crossing (struct xwidget_view *, extern void xwidget_motion_notify (struct xwidget_view *, double, double, uint, Time); extern void xwidget_scroll (struct xwidget_view *, double, double, - double, double, uint, Time); + double, double, uint, Time, bool); #endif #endif #else From c4dab6c179a78ae17d02becf66a098bd72a12233 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 8 Dec 2021 13:02:16 +0800 Subject: [PATCH 2/3] Allow customizing precision scroll interpolation * lisp/pixel-scroll.el (pixel-scroll-precision-interpolation-total-time) (pixel-scroll-precision-interpolation-factor): New user options. (pixel-scroll-precision-interpolate): Use these new options. (pixel-scroll-precision-mode): Set `make-cursor-line-fully-visible' to nil. --- lisp/pixel-scroll.el | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el index 2e09f9af2d4..10736de2ae4 100644 --- a/lisp/pixel-scroll.el +++ b/lisp/pixel-scroll.el @@ -141,6 +141,18 @@ Nil means to not interpolate such scrolls." number) :version "29.1") +(defcustom pixel-scroll-precision-interpolation-total-time 0.01 + "The total time in seconds to spend interpolating a large scroll." + :group 'mouse + :type 'float + :version 29.1) + +(defcustom pixel-scroll-precision-interpolation-factor 2.0 + "A factor to apply to the distance of an interpolated scroll." + :group 'mouse + :type 'float + :version 29.1) + (defun pixel-scroll-in-rush-p () "Return non-nil if next scroll should be non-smooth. When scrolling request is delivered soon after the previous one, @@ -531,7 +543,8 @@ This results in the window being scrolled by DELTA pixels with an animation." (while-no-input (let ((percentage 0) - (total-time 0.01) + (total-time pixel-scroll-precision-interpolation-total-time) + (factor pixel-scroll-precision-interpolation-factor) (time-elapsed 0.0) (between-scroll 0.001)) (while (< percentage 1) @@ -540,10 +553,10 @@ animation." percentage (/ time-elapsed total-time)) (if (< delta 0) (pixel-scroll-precision-scroll-down - (ceiling (abs (* delta + (ceiling (abs (* (* delta factor) (/ between-scroll total-time))))) (pixel-scroll-precision-scroll-up - (ceiling (* delta + (ceiling (* (* delta factor) (/ between-scroll total-time))))) (redisplay t))))) @@ -691,6 +704,8 @@ precisely, according to the turning of the mouse wheel." :group 'mouse :keymap pixel-scroll-precision-mode-map (setq mwheel-coalesce-scroll-events + (not pixel-scroll-precision-mode) + make-cursor-line-fully-visible (not pixel-scroll-precision-mode))) (provide 'pixel-scroll) From bf79dad3f20345ddf095325ce22c0f2a3408d3ba Mon Sep 17 00:00:00 2001 From: Po Lu Date: Wed, 8 Dec 2021 13:40:12 +0800 Subject: [PATCH 3/3] Make interpolated scrolling work better * lisp/pixel-scroll.el (pixel-scroll-precision-interpolate): Stop using `while-no-input'. --- lisp/pixel-scroll.el | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/lisp/pixel-scroll.el b/lisp/pixel-scroll.el index 10736de2ae4..6191c0530c4 100644 --- a/lisp/pixel-scroll.el +++ b/lisp/pixel-scroll.el @@ -541,24 +541,23 @@ the height of the current window." "Interpolate a scroll of DELTA pixels. This results in the window being scrolled by DELTA pixels with an animation." - (while-no-input - (let ((percentage 0) - (total-time pixel-scroll-precision-interpolation-total-time) - (factor pixel-scroll-precision-interpolation-factor) - (time-elapsed 0.0) - (between-scroll 0.001)) - (while (< percentage 1) - (sit-for between-scroll) - (setq time-elapsed (+ time-elapsed between-scroll) - percentage (/ time-elapsed total-time)) - (if (< delta 0) - (pixel-scroll-precision-scroll-down - (ceiling (abs (* (* delta factor) - (/ between-scroll total-time))))) - (pixel-scroll-precision-scroll-up - (ceiling (* (* delta factor) - (/ between-scroll total-time))))) - (redisplay t))))) + (let ((percentage 0) + (total-time pixel-scroll-precision-interpolation-total-time) + (factor pixel-scroll-precision-interpolation-factor) + (time-elapsed 0.0) + (between-scroll 0.001)) + (while (< percentage 1) + (sit-for between-scroll) + (setq time-elapsed (+ time-elapsed between-scroll) + percentage (/ time-elapsed total-time)) + (if (< delta 0) + (pixel-scroll-precision-scroll-down + (ceiling (abs (* (* delta factor) + (/ between-scroll total-time))))) + (pixel-scroll-precision-scroll-up + (ceiling (* (* delta factor) + (/ between-scroll total-time))))) + (redisplay t)))) (defun pixel-scroll-precision-scroll-up (delta) "Scroll the current window up by DELTA pixels."