unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Smoother macOS touchpad scrolling
@ 2017-09-08 18:46 Alan Third
  2017-09-08 22:21 ` Tak Kunihiro
  0 siblings, 1 reply; 17+ messages in thread
From: Alan Third @ 2017-09-08 18:46 UTC (permalink / raw)
  To: Emacs-Devel devel

[-- Attachment #1: Type: text/plain, Size: 657 bytes --]

Attached is a patch to provide smoother scrolling with the touchpad on
macOS. It adds up the scrolling deltas and only sends a scroll event
when the total exceeds the frame’s default line‐height.

Scrolling quickly sometimes results in the screen stuttering a little.
I’m not sure if that’s just a result of scrolling quickly, or because
my code sends one scroll event for each line it wants to scroll and it
overloads Emacs redisplay or something.

Does anyone know if there’s a way, in C, to detect if we’re at the top
or bottom of the buffer? I’d rather not send momentum scroll events if
the buffer isn’t going to scroll.
-- 
Alan Third

[-- Attachment #2: 0001-Provide-smoother-touchpad-scrolling-on-macOS.patch --]
[-- Type: text/plain, Size: 5268 bytes --]

From 1c9ca5b5d38274eb1a2eb2aa28ef43ac4670d3a6 Mon Sep 17 00:00:00 2001
From: Alan Third <alan@idiocy.org>
Date: Fri, 8 Sep 2017 19:26:47 +0100
Subject: [PATCH] Provide smoother touchpad scrolling on macOS

* lisp/term/ns-win.el (mouse-wheel-scroll-amount,
mouse-wheel-progressive-speed): Set to smarter values for touchpads.
* src/nsterm.m (emacsView::mouseDown): Use precise scrolling deltas to
calculate scrolling for touchpads.
---
 lisp/term/ns-win.el |  9 ++++++
 src/nsterm.m        | 91 ++++++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 88 insertions(+), 12 deletions(-)

diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index cfce83f892..488ea9cf0b 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -736,6 +736,15 @@ ns-paste-secondary
 (global-unset-key [horizontal-scroll-bar drag-mouse-1])
 
 
+;;;; Sane defaults for trackpad scrolling.
+
+;; These aren't so good for mousewheel scrolling, but we can't
+;; differentiate between the two.
+
+(setq mouse-wheel-scroll-amount '(1 ((shift) . 5)))
+(setq mouse-wheel-progressive-speed nil)
+
+
 ;;;; Color support.
 
 ;; Functions for color panel + drag
diff --git a/src/nsterm.m b/src/nsterm.m
index be97e94dd5..432e4ada86 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -6498,24 +6498,91 @@ - (void)mouseDown: (NSEvent *)theEvent
 
   if ([theEvent type] == NSEventTypeScrollWheel)
     {
-      CGFloat delta = [theEvent deltaY];
-      /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */
-      if (delta == 0)
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+      /* If the input device is a touchpad or similar, use precise
+       * scrolling deltas.  These are measured in pixels, so we have
+       * to add them up until they exceed one line height, then we can
+       * send one, or more, scroll wheel events.
+       *
+       * If the device only has coarse scrolling deltas, like a real
+       * mousewheel, use the old method which sends one scroll event
+       * per mousewheel `click'.  We could use precise deltas here
+       * too, but they can result in as little as one pixel change per
+       * `click', which would make it appear to the user as though
+       * nothing was happening.
+       */
+
+      if ([theEvent hasPreciseScrollingDeltas])
         {
-          delta = [theEvent deltaX];
-          if (delta == 0)
+          static int totalDeltaX, totalDeltaY;
+          bool horizontal;
+          int lines = 0;
+          int lineHeight = default_line_pixel_height(XWINDOW (FRAME_SELECTED_WINDOW (emacsframe)));
+
+          if ([theEvent phase] == NSEventPhaseBegan)
+            {
+              totalDeltaX = 0;
+              totalDeltaY = 0;
+            }
+
+          totalDeltaX += [theEvent scrollingDeltaX];
+          totalDeltaY += [theEvent scrollingDeltaY];
+
+          /* Calculate the number of lines, if any, to scroll, and
+           * reset the total delta for the direction we're NOT
+           * scrolling so that small movements don't add up.  */
+          if (abs (totalDeltaX) > abs (totalDeltaY)
+              && abs (totalDeltaX) > lineHeight)
+            {
+              horizontal = YES;
+              lines = totalDeltaX / lineHeight;
+              totalDeltaX = totalDeltaX % lineHeight;
+              totalDeltaY = 0;
+            }
+          else if (abs (totalDeltaY) >= abs (totalDeltaX)
+                   && abs (totalDeltaY) > lineHeight)
+            {
+              horizontal = NO;
+              lines = totalDeltaY / lineHeight;
+              totalDeltaY = totalDeltaY % lineHeight;
+              totalDeltaX = 0;
+            }
+
+          for (int i = 0 ; i < abs (lines) ; i++)
             {
-              NSTRACE_MSG ("deltaIsZero");
-              return;
+              emacs_event->kind = horizontal ? HORIZ_WHEEL_EVENT : WHEEL_EVENT;
+
+              emacs_event->code = 0;
+              emacs_event->modifiers = EV_MODIFIERS (theEvent) |
+                ((lines > 0) ? up_modifier : down_modifier);
+              XSETINT (emacs_event->x, lrint (p.x));
+              XSETINT (emacs_event->y, lrint (p.y));
+              EV_TRAILER (theEvent);
             }
-          emacs_event->kind = HORIZ_WHEEL_EVENT;
+          return;
         }
       else
-        emacs_event->kind = WHEEL_EVENT;
+#endif /* defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */
+        {
+          CGFloat delta = [theEvent deltaY];
+          /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */
+          if (delta == 0)
+            {
+              delta = [theEvent deltaX];
+              if (delta == 0)
+                {
+                  NSTRACE_MSG ("deltaIsZero");
+                  return;
+                }
+              emacs_event->kind = HORIZ_WHEEL_EVENT;
+            }
+          else
+            emacs_event->kind = WHEEL_EVENT;
 
-      emacs_event->code = 0;
-      emacs_event->modifiers = EV_MODIFIERS (theEvent) |
-        ((delta > 0) ? up_modifier : down_modifier);
+          emacs_event->code = 0;
+          emacs_event->modifiers = EV_MODIFIERS (theEvent) |
+            ((delta > 0) ? up_modifier : down_modifier);
+        }
     }
   else
     {
-- 
2.12.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-08 18:46 Smoother macOS touchpad scrolling Alan Third
@ 2017-09-08 22:21 ` Tak Kunihiro
  2017-09-09  8:18   ` Alan Third
  0 siblings, 1 reply; 17+ messages in thread
From: Tak Kunihiro @ 2017-09-08 22:21 UTC (permalink / raw)
  To: Alan Third; +Cc: Emacs-Devel devel

> +(setq mouse-wheel-scroll-amount '(1 ((shift) . 5)))
> +(setq mouse-wheel-progressive-speed nil)

I thought one of good things about your patch is to make scrolling smooth
without changing default.  No?

  http://lists.gnu.org/archive/html/emacs-devel/2017-08/msg00624.html

> +          int lineHeight = default_line_pixel_height(XWINDOW (FRAME_SELECTED_WINDOW (emacsframe)));

A buffer with images has lines with different height.
I think lineHeight should be
 - height of 1 line (or sum of 5 lines) at the top on a screen
   when scrolling up
 - height of unseen 1 line (or sum of unseen 5 lines) above the
   top out of screen when scrolling down.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-08 22:21 ` Tak Kunihiro
@ 2017-09-09  8:18   ` Alan Third
  2017-09-10  1:20     ` Tak Kunihiro
  0 siblings, 1 reply; 17+ messages in thread
From: Alan Third @ 2017-09-09  8:18 UTC (permalink / raw)
  To: Tak Kunihiro; +Cc: Emacs-Devel devel

On Sat, Sep 09, 2017 at 07:21:23AM +0900, Tak Kunihiro wrote:
> > +(setq mouse-wheel-scroll-amount '(1 ((shift) . 5)))
> > +(setq mouse-wheel-progressive-speed nil)
> 
> I thought one of good things about your patch is to make scrolling smooth
> without changing default.  No?
> 
>   http://lists.gnu.org/archive/html/emacs-devel/2017-08/msg00624.html

That was the plan, but I’ve run into some difficulties:

https://lists.gnu.org/archive/html/emacs-devel/2017-09/msg00013.html

This patch is a compromise between trying to improve the experience on
macOS and not adding new features that we don’t have under X.

I think progressive speed needs to be off, however, as macOS adds its
own acceleration. If you leave it on, then you’re doubling up on
progressive scrolling.

Probably the scroll amount change should be removed from this patch,
though.

> > +          int lineHeight = default_line_pixel_height(XWINDOW (FRAME_SELECTED_WINDOW (emacsframe)));
> 
> A buffer with images has lines with different height.
> I think lineHeight should be
>  - height of 1 line (or sum of 5 lines) at the top on a screen
>    when scrolling up
>  - height of unseen 1 line (or sum of unseen 5 lines) above the
>    top out of screen when scrolling down.

I considered this but couldn’t find an easy way to get that
information in C. There probably is, I just couldn’t find it.

I also don’t think it’s too important as we’re not doing real
pixelwise scrolling. I considered just using a constant value, like
10, as I think that would still provide a better experience than we
have currently.

The reason I didn’t use a constant is in cases where the user zooms
out, or otherwise has very small text on the screen, they might expect
the scrolling to move more lines in that case. (Although, with more
experimentation, I don’t think default_line_pixel_height does what I
thought it did, as making the text very small or very big doesn’t seem
to change the scrolling behaviour.)

Additionally, if you do have a *very* large image on a line, then it
could look as though scrolling is not actually doing anything.

If the consensus is that using the actual line heights is preferable,
then I’m happy to make that change.
-- 
Alan Third



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-09  8:18   ` Alan Third
@ 2017-09-10  1:20     ` Tak Kunihiro
  2017-09-10  8:37       ` Alan Third
  0 siblings, 1 reply; 17+ messages in thread
From: Tak Kunihiro @ 2017-09-10  1:20 UTC (permalink / raw)
  To: Alan Third; +Cc: Tak Kunihiro, Emacs-Devel devel

>> > +          int lineHeight = default_line_pixel_height(XWINDOW (FRAME_SELECTED_WINDOW (emacsframe)));
>> 
>> A buffer with images has lines with different height.
>> I think lineHeight should be
>>  - height of 1 line (or sum of 5 lines) at the top on a screen
>>    when scrolling up
>>  - height of unseen 1 line (or sum of unseen 5 lines) above the
>>    top out of screen when scrolling down.
>
> I also don’t think it’s too important as we’re not doing real
> pixelwise scrolling. I considered just using a constant value, like
> 10, as I think that would still provide a better experience than we
> have currently.

Once customization is allowed, touchpad can scroll slow with following
setup.

  (require 'pixel-scroll)
  (pixel-scroll-mode 1)
  (setq pixel-resolution-fine-flag t)

Although this should not be advertised because C-n and C-p after
scrolling redo the scroll less than a line (in other word,
implementation is incomplete), this works as pixelwise scrolling.  Thus
please have an option to let touchpad send each event by each pixel.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-10  1:20     ` Tak Kunihiro
@ 2017-09-10  8:37       ` Alan Third
  2017-09-11 18:09         ` Alan Third
  2017-09-16 22:33         ` Smoother macOS touchpad scrolling Alan Third
  0 siblings, 2 replies; 17+ messages in thread
From: Alan Third @ 2017-09-10  8:37 UTC (permalink / raw)
  To: Tak Kunihiro; +Cc: Emacs-Devel devel

On Sun, Sep 10, 2017 at 10:20:56AM +0900, Tak Kunihiro wrote:
> > I also don’t think it’s too important as we’re not doing real
> > pixelwise scrolling. I considered just using a constant value, like
> > 10, as I think that would still provide a better experience than we
> > have currently.
> 
> Once customization is allowed, touchpad can scroll slow with following
> setup.
> 
>   (require 'pixel-scroll)
>   (pixel-scroll-mode 1)
>   (setq pixel-resolution-fine-flag t)
> 
> Although this should not be advertised because C-n and C-p after
> scrolling redo the scroll less than a line (in other word,
> implementation is incomplete), this works as pixelwise scrolling.  Thus
> please have an option to let touchpad send each event by each pixel.

You mean one event per pixel to be scrolled, or pass the delta in the
event?

I can certainly do the former, although it will potentially result in
a torrent of scroll events.

The latter is, I think, banned as it can’t be replicated on a Free
system, but is the better solution.

How about instead of using the default font height, I provide a
variable that the user can use to set a ‘line height’ of their own
choosing? i.e. ‘(setq ns-touchpad-scroll-line-height 1)’ for one
pixel.

If I work out how to use the real line heights, that can be the
default, overridden by the variable.
-- 
Alan Third



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-10  8:37       ` Alan Third
@ 2017-09-11 18:09         ` Alan Third
  2017-09-12  1:54           ` James Nguyen
  2017-09-12 23:13           ` Tak Kunihiro
  2017-09-16 22:33         ` Smoother macOS touchpad scrolling Alan Third
  1 sibling, 2 replies; 17+ messages in thread
From: Alan Third @ 2017-09-11 18:09 UTC (permalink / raw)
  To: Tak Kunihiro; +Cc: Emacs-Devel devel

[-- Attachment #1: Type: text/plain, Size: 757 bytes --]

On Sun, Sep 10, 2017 at 09:37:58AM +0100, Alan Third wrote:
> How about instead of using the default font height, I provide a
> variable that the user can use to set a ‘line height’ of their own
> choosing? i.e. ‘(setq ns-touchpad-scroll-line-height 1)’ for one
> pixel.

Updated patch attached.

I’ve modified mousewheel scrolling so it also makes use of macOS’s
built‐in mousewheel acceleration. My thinking was that if we turn off
Emacs progressive scrolling for touchpad, then mousewheels can feel
awfully slow. ns-use-system-mwheel-acceleration allows you to turn it
off if you don’t like the new behaviour, but it has no effect on
touchpad scrolling.

If anyone gives the patch a try, please let me know what you think.
-- 
Alan Third

[-- Attachment #2: 0001-Provide-smoother-touchpad-scrolling-on-macOS.patch --]
[-- Type: text/plain, Size: 9583 bytes --]

From 6cca3c21434d63f9be3ee4a45a34eebd6226cada Mon Sep 17 00:00:00 2001
From: Alan Third <alan@idiocy.org>
Date: Fri, 8 Sep 2017 19:26:47 +0100
Subject: [PATCH] Provide smoother touchpad scrolling on macOS

* etc/NEWS: Describe changes.
* lisp/term/ns-win.el (mouse-wheel-scroll-amount,
mouse-wheel-progressive-speed): Set to smarter values for macOS touchpads.
* src/nsterm.m (emacsView::mouseDown): Use precise scrolling deltas to
calculate scrolling for touchpads and mouse wheels.
(syms_of_nsterm): Add variables 'ns-use-system-mwheel-acceleration',
'ns-touchpad-scroll-line-height' and 'ns-touchpad-use-momentum'.
---
 etc/NEWS            |   6 ++
 lisp/term/ns-win.el |   7 +++
 src/nsterm.m        | 165 +++++++++++++++++++++++++++++++++++++++++++++++-----
 3 files changed, 163 insertions(+), 15 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 3f1df23ec3..0f4a3d7884 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1817,6 +1817,12 @@ of frame decorations on macOS 10.9+.
 ---
 ** 'process-attributes' on Darwin systems now returns more information.
 
+---
+** Mousewheel and trackpad scrolling on macOS 10.7+ now behaves more
+like the macOS default.  The new variables
+'ns-use-system-mwheel-acceleration', 'ns-touchpad-scroll-line-height'
+and 'ns-touchpad-use-momentum' can be used to customise the behavior.
+
 \f
 ----------------------------------------------------------------------
 This file is part of GNU Emacs.
diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index cfce83f892..dfdcdfe23e 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -736,6 +736,13 @@ ns-paste-secondary
 (global-unset-key [horizontal-scroll-bar drag-mouse-1])
 
 
+;;;; macOS-like defaults for trackpad and mouse wheel scrolling.
+
+(when (featurep 'cocoa)
+  (setq mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control))))
+  (setq mouse-wheel-progressive-speed nil))
+
+
 ;;;; Color support.
 
 ;; Functions for color panel + drag
diff --git a/src/nsterm.m b/src/nsterm.m
index 001e4576e8..1c3847e6ff 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -6498,24 +6498,142 @@ - (void)mouseDown: (NSEvent *)theEvent
 
   if ([theEvent type] == NSEventTypeScrollWheel)
     {
-      CGFloat delta = [theEvent deltaY];
-      /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */
-      if (delta == 0)
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
+      if ([theEvent respondsToSelector:@(hasPreciseScrollingDeltas)])
         {
-          delta = [theEvent deltaX];
-          if (delta == 0)
+#endif
+          /* If the input device is a touchpad or similar, use precise
+           * scrolling deltas.  These are measured in pixels, so we
+           * have to add them up until they exceed one line height,
+           * then we can send one, or more, scroll wheel events.
+           *
+           * If the device only has coarse scrolling deltas, like a
+           * real mousewheel, the deltas represent a ratio of whole
+           * lines, so round up the number of scroll events sent per
+           * click.  This means we always send at least one scroll
+           * event per click, but can still scroll more than one line
+           * if the OS tells us to.
+           */
+          bool horizontal;
+          int lines = 0;
+          int scrollUp = NO;
+
+          /* FIXME: At the top or bottom of the buffer we should
+           * ignore momentum-phase events.  */
+          if (! ns_touchpad_use_momentum
+              && [theEvent momentumPhase] != NSEventPhaseNone)
+            return;
+
+          if ([theEvent hasPreciseScrollingDeltas])
             {
-              NSTRACE_MSG ("deltaIsZero");
-              return;
+              static int totalDeltaX, totalDeltaY;
+              int lineHeight;
+
+              if (NUMBERP (ns_touchpad_scroll_line_height))
+                lineHeight = XINT (ns_touchpad_scroll_line_height);
+              else
+                {
+                  /* FIXME: Use actual line height instead of the default.  */
+                  lineHeight = default_line_pixel_height
+                    (XWINDOW (FRAME_SELECTED_WINDOW (emacsframe)));
+                }
+
+              if ([theEvent phase] == NSEventPhaseBegan)
+                {
+                  totalDeltaX = 0;
+                  totalDeltaY = 0;
+                }
+
+              totalDeltaX += [theEvent scrollingDeltaX];
+              totalDeltaY += [theEvent scrollingDeltaY];
+
+              /* Calculate the number of lines, if any, to scroll, and
+               * reset the total delta for the direction we're NOT
+               * scrolling so that small movements don't add up.  */
+              if (abs (totalDeltaX) > abs (totalDeltaY)
+                  && abs (totalDeltaX) > lineHeight)
+                {
+                  horizontal = YES;
+                  scrollUp = totalDeltaX > 0;
+
+                  lines = abs (totalDeltaX / lineHeight);
+                  totalDeltaX = totalDeltaX % lineHeight;
+                  totalDeltaY = 0;
+                }
+              else if (abs (totalDeltaY) >= abs (totalDeltaX)
+                       && abs (totalDeltaY) > lineHeight)
+                {
+                  horizontal = NO;
+                  scrollUp = totalDeltaY > 0;
+
+                  lines = abs (totalDeltaY / lineHeight);
+                  totalDeltaY = totalDeltaY % lineHeight;
+                  totalDeltaX = 0;
+                }
             }
-          emacs_event->kind = HORIZ_WHEEL_EVENT;
+          else
+            {
+              CGFloat delta;
+
+              if ([theEvent scrollingDeltaY] == 0)
+                {
+                  horizontal = YES;
+                  delta = [theEvent scrollingDeltaX];
+                }
+              else
+                {
+                  horizontal = NO;
+                  delta = [theEvent scrollingDeltaY];
+                }
+
+              lines = (ns_use_system_mwheel_acceleration)
+                ? ceil (fabs (delta)) : 1;
+
+              scrollUp = delta > 0;
+            }
+
+          for (int i = 0 ; i < lines ; i++)
+            {
+              emacs_event->kind = horizontal ? HORIZ_WHEEL_EVENT : WHEEL_EVENT;
+
+              emacs_event->code = 0;
+              emacs_event->modifiers = EV_MODIFIERS (theEvent) |
+                (scrollUp ? up_modifier : down_modifier);
+              XSETINT (emacs_event->x, lrint (p.x));
+              XSETINT (emacs_event->y, lrint (p.y));
+              EV_TRAILER (theEvent);
+            }
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
         }
       else
-        emacs_event->kind = WHEEL_EVENT;
+#endif
+#endif /* defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */
+#if defined (NS_IMPL_GNUSTEP) || MAC_OS_X_VERSION_MIN_REQUIRED < 1070
+        {
+          CGFloat delta = [theEvent deltaY];
+          /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */
+          if (delta == 0)
+            {
+              delta = [theEvent deltaX];
+              if (delta == 0)
+                {
+                  NSTRACE_MSG ("deltaIsZero");
+                  return;
+                }
+              emacs_event->kind = HORIZ_WHEEL_EVENT;
+            }
+          else
+            emacs_event->kind = WHEEL_EVENT;
 
-      emacs_event->code = 0;
-      emacs_event->modifiers = EV_MODIFIERS (theEvent) |
-        ((delta > 0) ? up_modifier : down_modifier);
+          emacs_event->code = 0;
+          emacs_event->modifiers = EV_MODIFIERS (theEvent) |
+            ((delta > 0) ? up_modifier : down_modifier);
+          XSETINT (emacs_event->x, lrint (p.x));
+          XSETINT (emacs_event->y, lrint (p.y));
+          EV_TRAILER (theEvent);
+        }
+#endif
     }
   else
     {
@@ -6523,10 +6641,10 @@ - (void)mouseDown: (NSEvent *)theEvent
       emacs_event->code = EV_BUTTON (theEvent);
       emacs_event->modifiers = EV_MODIFIERS (theEvent)
                              | EV_UDMODIFIERS (theEvent);
+      XSETINT (emacs_event->x, lrint (p.x));
+      XSETINT (emacs_event->y, lrint (p.y));
+      EV_TRAILER (theEvent);
     }
-  XSETINT (emacs_event->x, lrint (p.x));
-  XSETINT (emacs_event->y, lrint (p.y));
-  EV_TRAILER (theEvent);
 }
 
 
@@ -9166,6 +9284,23 @@ Nil means use fullscreen the old (< 10.7) way.  The old way works better with
 This variable is ignored on Mac OS X < 10.7 and GNUstep.  */);
   ns_use_srgb_colorspace = YES;
 
+  DEFVAR_BOOL ("ns-use-system-mwheel-acceleration",
+               ns_use_system_mwheel_acceleration,
+     doc: /*Non-nil means use macOS's standard mouse wheel acceleration.
+This variable is ignored on macOS < 10.7 and GNUstep.  Default is t.  */);
+  ns_use_system_mwheel_acceleration = YES;
+
+  DEFVAR_LISP ("ns-touchpad-scroll-line-height", ns_touchpad_scroll_line_height,
+               doc: /*The number of pixels touchpad scrolling considers a line.
+Nil or a non-number means use the default frame line height.
+This variable is ignored on macOS < 10.7 and GNUstep.  Default is nil.  */);
+  ns_touchpad_scroll_line_height = Qnil;
+
+  DEFVAR_BOOL ("ns-touchpad-use-momentum", ns_touchpad_use_momentum,
+               doc: /*Non-nil means touchpad scrolling uses momentum.
+This variable is ignored on macOS < 10.7 and GNUstep.  Default is t.  */);
+  ns_touchpad_use_momentum = YES;
+
   /* TODO: move to common code */
   DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
 	       doc: /* Which toolkit scroll bars Emacs uses, if any.
-- 
2.12.0


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-11 18:09         ` Alan Third
@ 2017-09-12  1:54           ` James Nguyen
  2017-09-12 17:03             ` Alan Third
  2017-09-12 23:13           ` Tak Kunihiro
  1 sibling, 1 reply; 17+ messages in thread
From: James Nguyen @ 2017-09-12  1:54 UTC (permalink / raw)
  To: Alan Third; +Cc: Tak Kunihiro, Emacs-Devel devel

It seemed to be laggier than when swiping up or down fast with the touchpad.

These settings work for me (before the patch) more smoothly than the patch (without applying the settings).

(setq scroll-margin 5
        scroll-step 1
        scroll-conservatively 10000
        scroll-preserve-screen-position 1)
  ;; https://superuser.com/questions/1133436/way-too-fast-scrolling-in-emacs-on-osx
  (setq mouse-wheel-scroll-amount (list (if (+desktop-p) 5 1)))
  (setq mouse-wheel-progressive-speed nil)
  (setq mouse-wheel-follow-mouse ’t)

+1 on pixel wise events. It’d be nice to scroll the window by pixel without display lag.



> On Sep 11, 2017, at 11:09 AM, Alan Third <alan@idiocy.org> wrote:
> 
> On Sun, Sep 10, 2017 at 09:37:58AM +0100, Alan Third wrote:
>> How about instead of using the default font height, I provide a
>> variable that the user can use to set a ‘line height’ of their own
>> choosing? i.e. ‘(setq ns-touchpad-scroll-line-height 1)’ for one
>> pixel.
> 
> Updated patch attached.
> 
> I’ve modified mousewheel scrolling so it also makes use of macOS’s
> built‐in mousewheel acceleration. My thinking was that if we turn off
> Emacs progressive scrolling for touchpad, then mousewheels can feel
> awfully slow. ns-use-system-mwheel-acceleration allows you to turn it
> off if you don’t like the new behaviour, but it has no effect on
> touchpad scrolling.
> 
> If anyone gives the patch a try, please let me know what you think.
> -- 
> Alan Third
> <0001-Provide-smoother-touchpad-scrolling-on-macOS.patch>




^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-12  1:54           ` James Nguyen
@ 2017-09-12 17:03             ` Alan Third
  0 siblings, 0 replies; 17+ messages in thread
From: Alan Third @ 2017-09-12 17:03 UTC (permalink / raw)
  To: James Nguyen; +Cc: Tak Kunihiro, Emacs-Devel devel

On Mon, Sep 11, 2017 at 06:54:14PM -0700, James Nguyen wrote:
> It seemed to be laggier than when swiping up or down fast with the
> touchpad.

It is sending more events, so I think that’s probably what’s happening
there. It’s not that different for me, though: I get lag if I try to
scroll quickly with or without this patch.

> These settings work for me (before the patch) more smoothly than the
> patch (without applying the settings).

Smooth may have been the wrong term to use. Really I’m just trying to
make it more like scrolling in other macOS apps, like terminal.app.
One of the benefits, IMHO, is that it makes the out‐of‐the‐box
scrolling nicer, although it is a change from previous behaviour.

-- 
Alan Third



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-11 18:09         ` Alan Third
  2017-09-12  1:54           ` James Nguyen
@ 2017-09-12 23:13           ` Tak Kunihiro
  2017-09-13 16:26             ` Better macOS scrolling (was: Smoother macOS touchpad scrolling) Alan Third
  1 sibling, 1 reply; 17+ messages in thread
From: Tak Kunihiro @ 2017-09-12 23:13 UTC (permalink / raw)
  To: Alan Third; +Cc: Tak Kunihiro, Emacs-Devel devel

> Updated patch attached.
>
> If anyone gives the patch a try, please let me know what you think.

I tried the patch.  I compared experiences with or without the patch on
following setup.

  (setq mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control))))
  (setq mouse-wheel-progressive-speed nil)

The scrolling experience is with more feel of acceleration.  I think
this is good.

I also compared with or without the patch on following setup.

  (setq mouse-wheel-scroll-amount '(5 ((shift) . 1) ((control))))
  (setq mouse-wheel-progressive-speed t)

Both are still too fast.

I think your patch handles two issues.  One improves response of
touchpad and other changes default values.  I think two issues should be
separated out.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Better macOS scrolling (was: Smoother macOS touchpad scrolling)
  2017-09-12 23:13           ` Tak Kunihiro
@ 2017-09-13 16:26             ` Alan Third
  2017-09-13 22:52               ` Better macOS scrolling Tak Kunihiro
  0 siblings, 1 reply; 17+ messages in thread
From: Alan Third @ 2017-09-13 16:26 UTC (permalink / raw)
  To: Tak Kunihiro; +Cc: Emacs-Devel devel

On Wed, Sep 13, 2017 at 08:13:25AM +0900, Tak Kunihiro wrote:
> > Updated patch attached.
> >
> > If anyone gives the patch a try, please let me know what you think.
> 
> I tried the patch.  I compared experiences with or without the patch on
> following setup.
> 
>   (setq mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control))))
>   (setq mouse-wheel-progressive-speed nil)
> 
> The scrolling experience is with more feel of acceleration.  I think
> this is good.

This should match the scrolling behaviour of other macOS applications.

> I also compared with or without the patch on following setup.
> 
>   (setq mouse-wheel-scroll-amount '(5 ((shift) . 1) ((control))))
>   (setq mouse-wheel-progressive-speed t)
> 
> Both are still too fast.

Completely useless, imo.

> I think your patch handles two issues.  One improves response of
> touchpad and other changes default values.  I think two issues should be
> separated out.

I could split it into two, but I don’t see the benefit. The patch,
including setting defaults, results in behaviour that is similar to
other macOS applications. I’ve been over the previous discussions
about changing the defaults for mouse-wheel-progressive-speed, and the
general opinion seemed to be that we should be trying to make the
defaults as close to the operating system’s standard as possible. This
patch does that.

It only changes them for the NS port running on macOS. If the same
needs to be done on X and MS Windows, then that’s fine, and can be
done, but it doesn’t change the fact that we need to set defaults to
match the standard macOS behaviour.

-- 
Alan Third



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Better macOS scrolling
  2017-09-13 16:26             ` Better macOS scrolling (was: Smoother macOS touchpad scrolling) Alan Third
@ 2017-09-13 22:52               ` Tak Kunihiro
  0 siblings, 0 replies; 17+ messages in thread
From: Tak Kunihiro @ 2017-09-13 22:52 UTC (permalink / raw)
  To: Alan Third; +Cc: Tak Kunihiro, Emacs-Devel devel

>> I also compared with or without the patch on following setup.
>> 
>>   (setq mouse-wheel-scroll-amount '(5 ((shift) . 1) ((control))))
>>   (setq mouse-wheel-progressive-speed t)
>> 
>> Both are still too fast.
>
> Completely useless, imo.
>
>> I think your patch handles two issues.  One improves response of
>> touchpad and other changes default values.  I think two issues should be
>> separated out.
>
> I could split it into two, but I don’t see the benefit. The patch,
> including setting defaults, results in behaviour that is similar to
> other macOS applications. I’ve been over the previous discussions
> about changing the defaults for mouse-wheel-progressive-speed, and the
> general opinion seemed to be that we should be trying to make the
> defaults as close to the operating system’s standard as possible. This
> patch does that.
>
> It only changes them for the NS port running on macOS. If the same
> needs to be done on X and MS Windows, then that’s fine, and can be
> done, but it doesn’t change the fact that we need to set defaults to
> match the standard macOS behaviour.

I see.   Now I think it is a good idea.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-10  8:37       ` Alan Third
  2017-09-11 18:09         ` Alan Third
@ 2017-09-16 22:33         ` Alan Third
  2017-09-18 18:10           ` Charles A. Roelli
  1 sibling, 1 reply; 17+ messages in thread
From: Alan Third @ 2017-09-16 22:33 UTC (permalink / raw)
  To: Tak Kunihiro; +Cc: Emacs-Devel devel

[-- Attachment #1: Type: text/plain, Size: 760 bytes --]

On Sun, Sep 10, 2017 at 09:37:58AM +0100, Alan Third wrote:
> 
> You mean one event per pixel to be scrolled, or pass the delta in the
> event?
> 
> I can certainly do the former, although it will potentially result in
> a torrent of scroll events.
> 
> The latter is, I think, banned as it can’t be replicated on a Free
> system, but is the better solution.

I was thinking about this, and it’s not actually a new feature, it’s
an optimization of a feature that already exists (progressive scroll).
The fact the optimization is only available on macOS is irrelevant.

So in that spirit I’ve attached another patch.

Can Eli or John let me know if I’m thinking about this right? And if
this patch *is* ok, is it too late for Emacs 26?
-- 
Alan Third

[-- Attachment #2: 0001-Provide-native-touchpad-scrolling-on-macOS.patch --]
[-- Type: text/plain, Size: 12031 bytes --]

From 9295fbb214b32555b55b0c1c56d0831bf6395c1c Mon Sep 17 00:00:00 2001
From: Alan Third <alan@idiocy.org>
Date: Fri, 8 Sep 2017 19:26:47 +0100
Subject: [PATCH] Provide native touchpad scrolling on macOS

* etc/NEWS: Describe changes.
* lisp/term/ns-win.el (mouse-wheel-scroll-amount,
mouse-wheel-progressive-speed): Set to smarter values for macOS touchpads.
* src/nsterm.m (emacsView::mouseDown): Use precise scrolling deltas to
calculate scrolling for touchpads and mouse wheels.
(syms_of_nsterm): Add variables 'ns-use-system-mwheel-acceleration',
'ns-touchpad-scroll-line-height' and 'ns-touchpad-use-momentum'.
* src/keyboard.c (make_lispy_event): Pass on .arg when relevant.
* src/termhooks.h (event_kind): Update comments re. WHEEL_EVENT.
* lisp/mwheel.el (mwheel-scroll): Use line count.
* lisp/subr.el (event-line-count): New function.
---
 etc/NEWS            |   6 ++
 lisp/mwheel.el      |   1 +
 lisp/subr.el        |   5 ++
 lisp/term/ns-win.el |   7 +++
 src/keyboard.c      |   5 +-
 src/nsterm.m        | 158 ++++++++++++++++++++++++++++++++++++++++++++++++----
 src/termhooks.h     |   4 +-
 7 files changed, 172 insertions(+), 14 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index 371cdf686c..6111738b0f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -49,6 +49,12 @@ When you add a new item, use the appropriate mark if you are sure it applies,
 \f
 * Changes in Emacs 27.1 on Non-Free Operating Systems
 
+---
+** Mousewheel and trackpad scrolling on macOS 10.7+ now behaves more
+like the macOS default.  The new variables
+'ns-use-system-mwheel-acceleration', 'ns-touchpad-scroll-line-height'
+and 'ns-touchpad-use-momentum' can be used to customise the behavior.
+
 \f
 ----------------------------------------------------------------------
 This file is part of GNU Emacs.
diff --git a/lisp/mwheel.el b/lisp/mwheel.el
index 2956ba5516..0c0dcb3beb 100644
--- a/lisp/mwheel.el
+++ b/lisp/mwheel.el
@@ -232,6 +232,7 @@ mwheel-scroll
       ;; When the double-mouse-N comes in, a mouse-N has been executed already,
       ;; So by adding things up we get a squaring up (1, 3, 6, 10, 15, ...).
       (setq amt (* amt (event-click-count event))))
+    (when (numberp amt) (setq amt (* amt (event-line-count event))))
     (unwind-protect
 	(let ((button (mwheel-event-button event)))
 	  (cond ((eq button mouse-wheel-down-event)
diff --git a/lisp/subr.el b/lisp/subr.el
index 79ae1f4830..f0d0b24462 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1270,6 +1270,11 @@ event-click-count
   "Return the multi-click count of EVENT, a click or drag event.
 The return value is a positive integer."
   (if (and (consp event) (integerp (nth 2 event))) (nth 2 event) 1))
+
+(defsubst event-line-count (event)
+  "Return the line count of EVENT, a mousewheel event.
+The return value is a positive integer."
+  (if (and (consp event) (integerp (nth 3 event))) (nth 3 event) 1))
 \f
 ;;;; Extracting fields of the positions in an event.
 
diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index 68b659bf75..6aef27362f 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -736,6 +736,13 @@ ns-paste-secondary
 (global-unset-key [horizontal-scroll-bar drag-mouse-1])
 
 
+;;;; macOS-like defaults for trackpad and mouse wheel scrolling.
+
+(when (featurep 'cocoa)
+  (setq mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control))))
+  (setq mouse-wheel-progressive-speed nil))
+
+
 ;;;; Color support.
 
 ;; Functions for color panel + drag
diff --git a/src/keyboard.c b/src/keyboard.c
index 4db50be855..e8701b8870 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -5925,7 +5925,10 @@ make_lispy_event (struct input_event *event)
 				      ASIZE (wheel_syms));
 	}
 
-	if (event->modifiers & (double_modifier | triple_modifier))
+        if (NUMBERP (event->arg))
+          return list4 (head, position, make_number (double_click_count),
+                        event->arg);
+	else if (event->modifiers & (double_modifier | triple_modifier))
 	  return list3 (head, position, make_number (double_click_count));
 	else
 	  return list2 (head, position);
diff --git a/src/nsterm.m b/src/nsterm.m
index 2751533533..776635980e 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -6498,24 +6498,139 @@ - (void)mouseDown: (NSEvent *)theEvent
 
   if ([theEvent type] == NSEventTypeScrollWheel)
     {
-      CGFloat delta = [theEvent deltaY];
-      /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */
-      if (delta == 0)
+#if defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
+      if ([theEvent respondsToSelector:@selector(hasPreciseScrollingDeltas)])
         {
-          delta = [theEvent deltaX];
-          if (delta == 0)
+#endif
+          /* If the input device is a touchpad or similar, use precise
+           * scrolling deltas.  These are measured in pixels, so we
+           * have to add them up until they exceed one line height,
+           * then we can send a scroll wheel event.
+           *
+           * If the device only has coarse scrolling deltas, like a
+           * real mousewheel, the deltas represent a ratio of whole
+           * lines, so round up the number of lines.  This means we
+           * always send one scroll event per click, but can still
+           * scroll more than one line if the OS tells us to.
+           */
+          bool horizontal;
+          int lines = 0;
+          int scrollUp = NO;
+
+          /* FIXME: At the top or bottom of the buffer we should
+           * ignore momentum-phase events.  */
+          if (! ns_touchpad_use_momentum
+              && [theEvent momentumPhase] != NSEventPhaseNone)
+            return;
+
+          if ([theEvent hasPreciseScrollingDeltas])
             {
-              NSTRACE_MSG ("deltaIsZero");
-              return;
+              static int totalDeltaX, totalDeltaY;
+              int lineHeight;
+
+              if (NUMBERP (ns_touchpad_scroll_line_height))
+                lineHeight = XINT (ns_touchpad_scroll_line_height);
+              else
+                {
+                  /* FIXME: Use actual line height instead of the default.  */
+                  lineHeight = default_line_pixel_height
+                    (XWINDOW (FRAME_SELECTED_WINDOW (emacsframe)));
+                }
+
+              if ([theEvent phase] == NSEventPhaseBegan)
+                {
+                  totalDeltaX = 0;
+                  totalDeltaY = 0;
+                }
+
+              totalDeltaX += [theEvent scrollingDeltaX];
+              totalDeltaY += [theEvent scrollingDeltaY];
+
+              /* Calculate the number of lines, if any, to scroll, and
+               * reset the total delta for the direction we're NOT
+               * scrolling so that small movements don't add up.  */
+              if (abs (totalDeltaX) > abs (totalDeltaY)
+                  && abs (totalDeltaX) > lineHeight)
+                {
+                  horizontal = YES;
+                  scrollUp = totalDeltaX > 0;
+
+                  lines = abs (totalDeltaX / lineHeight);
+                  totalDeltaX = totalDeltaX % lineHeight;
+                  totalDeltaY = 0;
+                }
+              else if (abs (totalDeltaY) >= abs (totalDeltaX)
+                       && abs (totalDeltaY) > lineHeight)
+                {
+                  horizontal = NO;
+                  scrollUp = totalDeltaY > 0;
+
+                  lines = abs (totalDeltaY / lineHeight);
+                  totalDeltaY = totalDeltaY % lineHeight;
+                  totalDeltaX = 0;
+                }
+
+              if (lines > 1 && ! ns_use_system_mwheel_acceleration)
+                lines = 1;
             }
-          emacs_event->kind = HORIZ_WHEEL_EVENT;
+          else
+            {
+              CGFloat delta;
+
+              if ([theEvent scrollingDeltaY] == 0)
+                {
+                  horizontal = YES;
+                  delta = [theEvent scrollingDeltaX];
+                }
+              else
+                {
+                  horizontal = NO;
+                  delta = [theEvent scrollingDeltaY];
+                }
+
+              lines = (ns_use_system_mwheel_acceleration)
+                ? ceil (fabs (delta)) : 1;
+
+              scrollUp = delta > 0;
+            }
+
+          if (lines == 0)
+            return;
+
+          emacs_event->kind = horizontal ? HORIZ_WHEEL_EVENT : WHEEL_EVENT;
+          emacs_event->arg = (make_number (lines));
+
+          emacs_event->code = 0;
+          emacs_event->modifiers = EV_MODIFIERS (theEvent) |
+            (scrollUp ? up_modifier : down_modifier);
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
         }
       else
-        emacs_event->kind = WHEEL_EVENT;
+#endif
+#endif /* defined (NS_IMPL_COCOA) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 */
+#if defined (NS_IMPL_GNUSTEP) || MAC_OS_X_VERSION_MIN_REQUIRED < 1070
+        {
+          CGFloat delta = [theEvent deltaY];
+          /* Mac notebooks send wheel events w/delta =0 when trackpad scrolling */
+          if (delta == 0)
+            {
+              delta = [theEvent deltaX];
+              if (delta == 0)
+                {
+                  NSTRACE_MSG ("deltaIsZero");
+                  return;
+                }
+              emacs_event->kind = HORIZ_WHEEL_EVENT;
+            }
+          else
+            emacs_event->kind = WHEEL_EVENT;
 
-      emacs_event->code = 0;
-      emacs_event->modifiers = EV_MODIFIERS (theEvent) |
-        ((delta > 0) ? up_modifier : down_modifier);
+          emacs_event->code = 0;
+          emacs_event->modifiers = EV_MODIFIERS (theEvent) |
+            ((delta > 0) ? up_modifier : down_modifier);
+        }
+#endif
     }
   else
     {
@@ -6524,9 +6639,11 @@ - (void)mouseDown: (NSEvent *)theEvent
       emacs_event->modifiers = EV_MODIFIERS (theEvent)
                              | EV_UDMODIFIERS (theEvent);
     }
+
   XSETINT (emacs_event->x, lrint (p.x));
   XSETINT (emacs_event->y, lrint (p.y));
   EV_TRAILER (theEvent);
+  return;
 }
 
 
@@ -9166,6 +9283,23 @@ Nil means use fullscreen the old (< 10.7) way.  The old way works better with
 This variable is ignored on Mac OS X < 10.7 and GNUstep.  */);
   ns_use_srgb_colorspace = YES;
 
+  DEFVAR_BOOL ("ns-use-system-mwheel-acceleration",
+               ns_use_system_mwheel_acceleration,
+     doc: /*Non-nil means use macOS's standard mouse wheel acceleration.
+This variable is ignored on macOS < 10.7 and GNUstep.  Default is t.  */);
+  ns_use_system_mwheel_acceleration = YES;
+
+  DEFVAR_LISP ("ns-touchpad-scroll-line-height", ns_touchpad_scroll_line_height,
+               doc: /*The number of pixels touchpad scrolling considers a line.
+Nil or a non-number means use the default frame line height.
+This variable is ignored on macOS < 10.7 and GNUstep.  Default is nil.  */);
+  ns_touchpad_scroll_line_height = Qnil;
+
+  DEFVAR_BOOL ("ns-touchpad-use-momentum", ns_touchpad_use_momentum,
+               doc: /*Non-nil means touchpad scrolling uses momentum.
+This variable is ignored on macOS < 10.7 and GNUstep.  Default is t.  */);
+  ns_touchpad_use_momentum = YES;
+
   /* TODO: move to common code */
   DEFVAR_LISP ("x-toolkit-scroll-bars", Vx_toolkit_scroll_bars,
 	       doc: /* Which toolkit scroll bars Emacs uses, if any.
diff --git a/src/termhooks.h b/src/termhooks.h
index 97c128ba4e..b5171bf122 100644
--- a/src/termhooks.h
+++ b/src/termhooks.h
@@ -116,7 +116,9 @@ enum event_kind
 				   .frame_or_window gives the frame
 				   the wheel event occurred in.
 				   .timestamp gives a timestamp (in
-				   milliseconds) for the event.  */
+				   milliseconds) for the event.
+                                   .arg may contain the number of
+                                   lines to scroll.  */
   HORIZ_WHEEL_EVENT,            /* A wheel event generated by a second
                                    horizontal wheel that is present on some
                                    mice. See WHEEL_EVENT.  */
-- 
2.14.1


^ permalink raw reply related	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-16 22:33         ` Smoother macOS touchpad scrolling Alan Third
@ 2017-09-18 18:10           ` Charles A. Roelli
  2017-09-18 18:57             ` Charles A. Roelli
  2017-09-18 19:03             ` Alan Third
  0 siblings, 2 replies; 17+ messages in thread
From: Charles A. Roelli @ 2017-09-18 18:10 UTC (permalink / raw)
  To: Alan Third; +Cc: homeros.misasa, emacs-devel

With macOS 10.6, I haven't found Emacs scrolling with the touchpad to
be too unusual, maybe just a bit clunky.  Wouldn't the following code
also affect 10.6?

> +(when (featurep 'cocoa)
> +  (setq mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control))))
> +  (setq mouse-wheel-progressive-speed nil))

Also, won't these variable changes make Customize report that their
values were "changed outside Customize"?

Thanks for working on this improvement.  I wish I could try out the
patch on a newer version of macOS, but I lack the time lately.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-18 18:10           ` Charles A. Roelli
@ 2017-09-18 18:57             ` Charles A. Roelli
  2017-09-18 19:03             ` Alan Third
  1 sibling, 0 replies; 17+ messages in thread
From: Charles A. Roelli @ 2017-09-18 18:57 UTC (permalink / raw)
  To: alan; +Cc: homeros.misasa, emacs-devel

Oh, and could we please make a bug report for this?  Otherwise it
seems the conversations can get lost easily.  Thanks again.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-18 18:10           ` Charles A. Roelli
  2017-09-18 18:57             ` Charles A. Roelli
@ 2017-09-18 19:03             ` Alan Third
  2017-09-18 20:19               ` Charles A. Roelli
  1 sibling, 1 reply; 17+ messages in thread
From: Alan Third @ 2017-09-18 19:03 UTC (permalink / raw)
  To: Charles A. Roelli; +Cc: homeros.misasa, emacs-devel

On Mon, Sep 18, 2017 at 08:10:59PM +0200, Charles A. Roelli wrote:
> With macOS 10.6, I haven't found Emacs scrolling with the touchpad to
> be too unusual, maybe just a bit clunky.  Wouldn't the following code
> also affect 10.6?

You’re right.

Can you confirm that this doesn’t return true on 10.6?

(let ((appkit-version (progn (string-match "^appkit-\\([^\s-]*\\)"
                              ns-version-string)
                             (match-string 1 ns-version-string))))
  (>= (string-to-number appkit-version) 1138))

> > +(when (featurep 'cocoa)
> > +  (setq mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control))))
> > +  (setq mouse-wheel-progressive-speed nil))
> 
> Also, won't these variable changes make Customize report that their
> values were "changed outside Customize"?

I have absolutely no idea...

Customize is something I’ve largely done my best to avoid, so I don’t
know how I should go about setting them in a way that’s friendly to
it.

Something like this?

(let ((appkit-version (progn
                        (string-match "^appkit-\\([^\s-]*\\)" ns-version-string)
                        (match-string 1 ns-version-string))))
  (when (and (featurep 'cocoa) (>= (string-to-number appkit-version) 1138))
    (setq mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control))))
    (put 'mouse-wheel-scroll-amount 'customized-value
         (list (custom-quote (symbol-value 'mouse-wheel-scroll-amount))))
    
    (setq mouse-wheel-progressive-speed nil)
    (put 'mouse-wheel-progressive-speed 'customized-value
         (list (custom-quote (symbol-value 'mouse-wheel-progressive-speed))))))

It looks pretty messy.
-- 
Alan Third



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-18 19:03             ` Alan Third
@ 2017-09-18 20:19               ` Charles A. Roelli
  2017-09-19 19:12                 ` Alan Third
  0 siblings, 1 reply; 17+ messages in thread
From: Charles A. Roelli @ 2017-09-18 20:19 UTC (permalink / raw)
  To: Alan Third; +Cc: homeros.misasa, emacs-devel

> Authentication-Results: sinyavsky.aurox.ch (amavisd-new); 	dkim=pass (2048-bit key) header.d=googlemail.com
> Date: Mon, 18 Sep 2017 20:03:37 +0100
> From: Alan Third <alan@idiocy.org>
> Cc: homeros.misasa@gmail.com, emacs-devel@gnu.org
> Content-Type: text/plain; charset=utf-8
> Content-Disposition: inline
> 
> On Mon, Sep 18, 2017 at 08:10:59PM +0200, Charles A. Roelli wrote:
> > With macOS 10.6, I haven't found Emacs scrolling with the touchpad to
> > be too unusual, maybe just a bit clunky.  Wouldn't the following code
> > also affect 10.6?
> 
> You’re right.
> 
> Can you confirm that this doesn’t return true on 10.6?
> 
> (let ((appkit-version (progn (string-match "^appkit-\\([^\s-]*\\)"
>                               ns-version-string)
>                              (match-string 1 ns-version-string))))
>   (>= (string-to-number appkit-version) 1138))

Yes, it returns nil.  I think this check (or maybe a function that
returns the appkit version as an integer) could be added to ns-win.el.
 
> > > +(when (featurep 'cocoa)
> > > +  (setq mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control))))
> > > +  (setq mouse-wheel-progressive-speed nil))
> > 
> > Also, won't these variable changes make Customize report that their
> > values were "changed outside Customize"?
> 
> I have absolutely no idea...
> 
> Customize is something I’ve largely done my best to avoid, so I don’t
> know how I should go about setting them in a way that’s friendly to
> it.
> 
> Something like this?
> 
> (let ((appkit-version (progn
>                         (string-match "^appkit-\\([^\s-]*\\)" ns-version-string)
>                         (match-string 1 ns-version-string))))
>   (when (and (featurep 'cocoa) (>= (string-to-number appkit-version) 1138))
>     (setq mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control))))
>     (put 'mouse-wheel-scroll-amount 'customized-value
>          (list (custom-quote (symbol-value 'mouse-wheel-scroll-amount))))
>     
>     (setq mouse-wheel-progressive-speed nil)
>     (put 'mouse-wheel-progressive-speed 'customized-value
>          (list (custom-quote (symbol-value 'mouse-wheel-progressive-speed))))))
> 
> It looks pretty messy.

We could also make the defcustoms in mwheel.el look something like
this:

(defcustom mouse-wheel-scroll-amount
  (cond
   ((and (featurep 'cocoa) (>= (ns-appkit-version) 1138))
     '(1 ((shift) . 5) ((control) . nil)))
   (t '(5 ((shift) . 1) ((control) . nil)))) ...

instead of:

(defcustom mouse-wheel-scroll-amount '(5 ((shift) . 1) ((control) . nil)) ...

Then in ns-win.el we could do:

(custom-reevaluate-setting 'mouse-wheel-scroll-amount)

See also, Info node "(elisp) Variable Definitions":

 -- Function: custom-reevaluate-setting symbol
     This function re-evaluates the standard value of SYMBOL, which
     should be a user option declared via ‘defcustom’.  If the variable
     was customized, this function re-evaluates the saved value instead.
     Then it sets the user option to that value (using the option’s
     ‘:set’ property if that is defined).

     This is useful for customizable options that are defined before
     their value could be computed correctly.  For example, during
     startup Emacs calls this function for some user options that were
     defined in pre-loaded Emacs Lisp files, but whose initial values
     depend on information available only at run-time.

I /think/ this is the right thing to do, but if any Customize experts
can weigh in, that would be great.



^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: Smoother macOS touchpad scrolling
  2017-09-18 20:19               ` Charles A. Roelli
@ 2017-09-19 19:12                 ` Alan Third
  0 siblings, 0 replies; 17+ messages in thread
From: Alan Third @ 2017-09-19 19:12 UTC (permalink / raw)
  To: Charles A. Roelli; +Cc: homeros.misasa, emacs-devel

On Mon, Sep 18, 2017 at 10:19:30PM +0200, Charles A. Roelli wrote:
> Yes, it returns nil.  I think this check (or maybe a function that
> returns the appkit version as an integer) could be added to ns-win.el.

I’m leaving it as an inline check at the moment as we only have a
single use of it just now. If you’re aware of other places it could be
useful, please let me know.

> > (let ((appkit-version (progn
> >                         (string-match "^appkit-\\([^\s-]*\\)" ns-version-string)
> >                         (match-string 1 ns-version-string))))
> >   (when (and (featurep 'cocoa) (>= (string-to-number appkit-version) 1138))
> >     (setq mouse-wheel-scroll-amount '(1 ((shift) . 5) ((control))))
> >     (put 'mouse-wheel-scroll-amount 'customized-value
> >          (list (custom-quote (symbol-value 'mouse-wheel-scroll-amount))))
> >     
> >     (setq mouse-wheel-progressive-speed nil)
> >     (put 'mouse-wheel-progressive-speed 'customized-value
> >          (list (custom-quote (symbol-value 'mouse-wheel-progressive-speed))))))

I’ve pushed (roughly) this to Emacs 26. See below.

> We could also make the defcustoms in mwheel.el look something like
> this:
> 
> (defcustom mouse-wheel-scroll-amount
>   (cond
>    ((and (featurep 'cocoa) (>= (ns-appkit-version) 1138))
>      '(1 ((shift) . 5) ((control) . nil)))
>    (t '(5 ((shift) . 1) ((control) . nil)))) ...
> 
> instead of:
> 
> (defcustom mouse-wheel-scroll-amount '(5 ((shift) . 1) ((control) . nil)) ...
> 
> Then in ns-win.el we could do:
> 
> (custom-reevaluate-setting 'mouse-wheel-scroll-amount)

I tried this but it just set mouse-wheel-scroll-amount to nil. It
seems that custom-reevaluate-setting uses the :set function, which is
already in use for mouse-wheel-scroll-amount.

Since I want this in Emacs 26 I figured it’s better to go with an ugly
method that works for now, and figure out a neater solution later.

>      Then it sets the user option to that value (using the option’s
>      ‘:set’ property if that is defined).
        ^^^^

> I /think/ this is the right thing to do, but if any Customize experts
> can weigh in, that would be great.

Please do.
-- 
Alan Third



^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2017-09-19 19:12 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-09-08 18:46 Smoother macOS touchpad scrolling Alan Third
2017-09-08 22:21 ` Tak Kunihiro
2017-09-09  8:18   ` Alan Third
2017-09-10  1:20     ` Tak Kunihiro
2017-09-10  8:37       ` Alan Third
2017-09-11 18:09         ` Alan Third
2017-09-12  1:54           ` James Nguyen
2017-09-12 17:03             ` Alan Third
2017-09-12 23:13           ` Tak Kunihiro
2017-09-13 16:26             ` Better macOS scrolling (was: Smoother macOS touchpad scrolling) Alan Third
2017-09-13 22:52               ` Better macOS scrolling Tak Kunihiro
2017-09-16 22:33         ` Smoother macOS touchpad scrolling Alan Third
2017-09-18 18:10           ` Charles A. Roelli
2017-09-18 18:57             ` Charles A. Roelli
2017-09-18 19:03             ` Alan Third
2017-09-18 20:19               ` Charles A. Roelli
2017-09-19 19:12                 ` Alan Third

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).