From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Alan Third Newsgroups: gmane.emacs.devel Subject: Smoother macOS touchpad scrolling Date: Fri, 8 Sep 2017 19:46:34 +0100 Message-ID: <20170908184634.GA20058@breton.holly.idiocy.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="xHFwDpU9dbj6ez1V" Content-Transfer-Encoding: 8bit X-Trace: blaine.gmane.org 1504896455 2549 195.159.176.226 (8 Sep 2017 18:47:35 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 8 Sep 2017 18:47:35 +0000 (UTC) User-Agent: Mutt/1.7.2 (2016-11-26) To: Emacs-Devel devel Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Sep 08 20:47:30 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dqOJF-0008SO-Sy for ged-emacs-devel@m.gmane.org; Fri, 08 Sep 2017 20:47:22 +0200 Original-Received: from localhost ([::1]:46898 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dqOJN-0001b1-5S for ged-emacs-devel@m.gmane.org; Fri, 08 Sep 2017 14:47:29 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:50676) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dqOIb-0001am-TL for emacs-devel@gnu.org; Fri, 08 Sep 2017 14:46:43 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dqOIa-0005Qw-EG for emacs-devel@gnu.org; Fri, 08 Sep 2017 14:46:41 -0400 Original-Received: from mail-wr0-x235.google.com ([2a00:1450:400c:c0c::235]:34684) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dqOIa-0005P6-34 for emacs-devel@gnu.org; Fri, 08 Sep 2017 14:46:40 -0400 Original-Received: by mail-wr0-x235.google.com with SMTP id v109so6107205wrc.1 for ; Fri, 08 Sep 2017 11:46:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=20161025; h=sender:date:from:to:subject:message-id:mime-version :content-disposition:content-transfer-encoding:user-agent; bh=yBb8JqTR6TgpEoeuTArUJk2u+UgioyykCpOrFki7AHY=; b=EXFg1lXjF5WPnDM68L0ku1sobOgHmNsV1K6t//RJ1uHHY5vlPDNICWhcTc9uVRPG7N YJluvL3JtfNZOcbr/4OfGgMS+7mgKaQXDuIN5QzP7WdA+Xf+vOxszB/x0g1jwZNu8eSH 5bcV3Iv/Q0fv3EfiAWlstq8OIGotmzAV4Dka0zi0nYcjMIoB1PQ/xKXBzu0tYBLiuise TipiZLmpVLoZ9/k6/sjHHRtXvUB8tDMBlWL75kopgRy1uWyeWGxoMySW5PaoIf9EBZem +0he8wSWaJ9yBSnH8H+EVhSirOIbiHjFwxeRGVCJ8LJSYK7ftLJn02WP9jQV9hz40Mui FfbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:date:from:to:subject:message-id :mime-version:content-disposition:content-transfer-encoding :user-agent; bh=yBb8JqTR6TgpEoeuTArUJk2u+UgioyykCpOrFki7AHY=; b=l+nC8YEpsEGh3fUBgH3DcoMHKKFlFwXdILgSCy2MaqiL69x4eUbUx8fe5uIV5/sXca l/qbZRaZ3IX/s5KgaVqq4y3GahDxBhfZ+l9PEqIimhEWAgVMjBqSxQBnqX44Se4NuhEP tPQSRvvveZ8AH/B6bGvjsCgmmvjwOkgPyAoPnCQKjc5Mjsq2pHRlFTpi1xT36c1yqw21 4qCufduFKjqQVo92bZWuOYM0TRsbAg4o85HwmqYMnM44EfrKGNXvIm3kwld0coifnyj+ Jt1O9zyCnN3J8tVgmI1+J7l8tGE+JmZXAS5AaE3mU/0V/djHZNDGZIk0fQtLsS0TqccK pPuA== X-Gm-Message-State: AHPjjUj3RFgeJhhMWKNyhO6Te+i2Nz5qqoiXTxivcRrE3zJ83GQPLdhF 6gW9LMUYxeCtLHlTVvU= X-Google-Smtp-Source: ADKCNb6Dsdz33TmI4akbTnTCfhkw/7+3XTsIqIaMZGXwqfSWO6VPh1CfRUFxKjD9CqGAH+3MGm0gKA== X-Received: by 10.223.170.155 with SMTP id h27mr2647685wrc.95.1504896397376; Fri, 08 Sep 2017 11:46:37 -0700 (PDT) Original-Received: from breton.holly.idiocy.org (ip6-2001-08b0-03f8-8129-d5ca-64a5-495a-0a85.holly.idiocy.org. [2001:8b0:3f8:8129:d5ca:64a5:495a:a85]) by smtp.gmail.com with ESMTPSA id x15sm2329810wma.32.2017.09.08.11.46.35 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 08 Sep 2017 11:46:36 -0700 (PDT) Content-Disposition: inline X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:400c:c0c::235 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:218027 Archived-At: --xHFwDpU9dbj6ez1V Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit 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 --xHFwDpU9dbj6ez1V Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="0001-Provide-smoother-touchpad-scrolling-on-macOS.patch" >From 1c9ca5b5d38274eb1a2eb2aa28ef43ac4670d3a6 Mon Sep 17 00:00:00 2001 From: Alan Third 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 --xHFwDpU9dbj6ez1V--