[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] emacs-26 a5fec62: Provide native touchpad scrolling on mac
From: |
Alan Third |
Subject: |
[Emacs-diffs] emacs-26 a5fec62: Provide native touchpad scrolling on macOS |
Date: |
Tue, 19 Sep 2017 15:09:11 -0400 (EDT) |
branch: emacs-26
commit a5fec62b519ae8c0a6528366ac8b71cd0c7ac52e
Author: Alan Third <address@hidden>
Commit: Alan Third <address@hidden>
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 | 19 +++++++
src/keyboard.c | 5 +-
src/nsterm.m | 158 ++++++++++++++++++++++++++++++++++++++++++++++++----
src/termhooks.h | 4 +-
7 files changed, 184 insertions(+), 14 deletions(-)
diff --git a/etc/NEWS b/etc/NEWS
index 5aa57a7..a814c3e 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1882,6 +1882,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.
+
----------------------------------------------------------------------
This file is part of GNU Emacs.
diff --git a/lisp/mwheel.el b/lisp/mwheel.el
index 2956ba5..0c0dcb3b 100644
--- a/lisp/mwheel.el
+++ b/lisp/mwheel.el
@@ -232,6 +232,7 @@ non-Windows systems."
;; 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 96b1ac1..cf15ec2 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -1270,6 +1270,11 @@ See `event-start' for a description of the value
returned."
"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))
;;;; Extracting fields of the positions in an event.
diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index 68b659b..bc211ea 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -736,6 +736,25 @@ See the documentation of
`create-fontset-from-fontset-spec' for the format.")
(global-unset-key [horizontal-scroll-bar drag-mouse-1])
+;;;; macOS-like defaults for trackpad and mouse wheel scrolling on
+;;;; macOS 10.7+.
+
+;; FIXME: This doesn't look right. Is there a better way to do this
+;; that keeps customize happy?
+(let ((appkit-version (progn
+ (string-match "^appkit-\\([^\s-]*\\)"
ns-version-string)
+ (string-to-number (match-string 1
ns-version-string)))))
+ ;; Appkit 1138 ~= macOS 10.7.
+ (when (and (featurep 'cocoa) (>= 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))))))
+
+
;;;; Color support.
;; Functions for color panel + drag
diff --git a/src/keyboard.c b/src/keyboard.c
index 4db50be..e8701b8 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 2751533..7766359 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -6498,24 +6498,139 @@ not_in_argv (NSString *arg)
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 @@ not_in_argv (NSString *arg)
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 @@ Note that this does not apply to images.
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 97c128b..b5171bf 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. */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] emacs-26 a5fec62: Provide native touchpad scrolling on macOS,
Alan Third <=