unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Po Lu <luangruo@yahoo.com>
To: emacs-devel@gnu.org
Subject: Pixel scrolling support
Date: Fri, 26 Nov 2021 08:35:12 +0800	[thread overview]
Message-ID: <87a6hrzrcv.fsf@yahoo.com> (raw)
In-Reply-To: 87a6hrzrcv.fsf.ref@yahoo.com

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


I would like to install the following file:


[-- Attachment #2: better-pixel-scroll.el --]
[-- Type: text/plain, Size: 4470 bytes --]

;;; better-pixel-scroll.el --- Pixel scrolling support  -*- lexical-binding:t -*-

;; Copyright (C) 2021 Free Software Foundation, Inc.

;; This file is part of GNU Emacs.

;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.

;;; Commentary:

;; This enables the use of smooth scroll events provided by XInput 2
;; or NS to scroll the display according to the user's precise turning
;; of the mouse wheel.

;;; Code:

(require 'mwheel)

(defvar x-coalesce-scroll-events)

(defvar better-pixel-scroll-mode-map (make-sparse-keymap)
  "The key map used by `better-pixel-scroll-mode'.")

(define-key better-pixel-scroll-mode-map [wheel-down] #'better-pixel-scroll)
(define-key better-pixel-scroll-mode-map [wheel-up] #'better-pixel-scroll)

(defun better-pixel-scroll-scroll-down (delta)
  "Scroll the current window down by DELTA pixels.
Note that this function doesn't work if DELTA is larger than
the height of the current window."
  (when-let* ((posn (posn-at-point))
	      (current-y (cdr (posn-x-y posn)))
	      (min-y (+ (window-tab-line-height)
		        (window-header-line-height))))
    (if (> delta 0)
	(while (< (- current-y min-y) delta)
	  (vertical-motion 1)
          (setq current-y (+ current-y
                             (line-pixel-height)))
	  (when (eobp)
	    (error "End of buffer")))))
  (let* ((desired-pos (posn-at-x-y 0 (+ delta
					(window-tab-line-height)
					(window-header-line-height))))
	 (desired-start (posn-point desired-pos))
	 (desired-vscroll (cdr (posn-object-x-y desired-pos))))
    (unless (eq (window-start) desired-start)
      (set-window-start nil desired-start t))
    (set-window-vscroll nil desired-vscroll t)))

(defun better-pixel-scroll-scroll-up (delta)
  "Scroll the current window up by DELTA pixels."
  (let* ((max-y (- (window-text-height nil t)
		   (window-tab-line-height)
		   (window-header-line-height)))
	 (posn (posn-at-point))
	 (current-y (+ (cdr (posn-x-y posn))
		       (cdr (posn-object-width-height posn)))))
    (while (< (- max-y current-y) delta)
      (setq current-y (- current-y (line-pixel-height)))
      (when (zerop (vertical-motion -1))
	(set-window-vscroll nil 0)
	(signal 'beginning-of-buffer nil))))
  (while (> delta 0)
    (set-window-start nil (save-excursion
                            (goto-char (window-start))
                            (when (zerop (vertical-motion -1))
			      (set-window-vscroll nil 0)
			      (signal 'beginning-of-buffer nil))
                            (setq delta (- delta (line-pixel-height)))
                            (point))
		      t))
  (when (< delta 0)
    (better-pixel-scroll-scroll-down (- delta))))

(defun better-pixel-scroll (event &optional arg)
  "Scroll the display according to EVENT.
Take into account any pixel deltas in EVENT to scroll the display
according to the user's turning the mouse wheel.  If EVENT does
not have precise scrolling deltas, call `mwheel-scroll' instead.
ARG is passed to `mwheel-scroll', should that be called."
  (interactive (list last-input-event current-prefix-arg))
  (if (nth 4 event)
      (let ((delta (round (cdr (nth 4 event))))
            (window (mwheel-event-window event)))
        (if (> (abs delta) (window-text-height window t))
            (mwheel-scroll event arg)
          (with-selected-window window
              (if (< delta 0)
	          (better-pixel-scroll-scroll-down (- delta))
                (better-pixel-scroll-scroll-up delta)))))
    (mwheel-scroll event arg)))

;;;###autoload
(define-minor-mode better-pixel-scroll-mode
  "Toggle pixel scrolling.
When enabled, this minor mode allows to scroll the display
precisely, according to the turning of the mouse wheel."
  :global t
  :group 'mouse
  :keymap better-pixel-scroll-mode-map
  (setq x-coalesce-scroll-events
        (not better-pixel-scroll-mode)))

(provide 'better-pixel-scroll)

;;; better-pixel-scroll.el ends herea

[-- Attachment #3: Type: text/plain, Size: 203 bytes --]


on master, with an appropriate entry in NEWS.  It defines a global minor
mode that lets the user scroll the display according to the pixel
information reported by his mouse wheel.

Is that OK?  Thanks.

       reply	other threads:[~2021-11-26  0:35 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <87a6hrzrcv.fsf.ref@yahoo.com>
2021-11-26  0:35 ` Po Lu [this message]
2021-11-26  2:26   ` Pixel scrolling support Stefan Monnier
2021-11-26  3:06     ` Po Lu
2021-11-26  3:12       ` Po Lu
2021-11-26  6:41         ` Eli Zaretskii
2021-11-26  6:40       ` Eli Zaretskii
2021-11-26  6:45         ` Po Lu
2021-11-26  6:58           ` Eli Zaretskii
2021-11-26  7:01             ` Po Lu
2021-11-26  8:35               ` Eli Zaretskii
2021-11-26  9:29                 ` Po Lu
2021-11-26 11:26                   ` Eli Zaretskii
2021-11-26 11:38                     ` Po Lu
2021-11-26 12:00                       ` Eli Zaretskii
2021-11-26 12:09                         ` Po Lu
2021-11-26 12:42                           ` Eli Zaretskii
2021-11-26 12:46                             ` Po Lu
2021-11-26 12:49                               ` Po Lu
2021-11-26 13:00                                 ` Eli Zaretskii
2021-11-26 13:03                                   ` Po Lu
2021-11-26 12:07                       ` Stephen Berman
2021-11-26 13:35       ` Stefan Monnier
2021-11-26 13:41         ` Po Lu
2021-11-26 13:46           ` Eli Zaretskii
2021-11-26 13:50             ` Po Lu
2021-11-26  5:57   ` Aaron Madlon-Kay
2021-11-26  6:00     ` Po Lu
2021-11-26  6:11       ` Aaron Madlon-Kay
2021-11-26  6:22   ` Jim Porter
2021-11-26  6:30     ` Po Lu
2021-11-26  6:33   ` Eli Zaretskii
2022-05-18  2:53   ` Michael Heerdegen
2022-05-18  3:11     ` Po Lu
2022-05-18  3:27       ` pixel scroll vs. osm (was: Pixel scrolling support) Michael Heerdegen
2022-05-18  3:47         ` pixel scroll vs. osm Po Lu
2022-05-19  0:34           ` Michael Heerdegen
2022-05-21  0:18           ` Michael Heerdegen
2022-05-21  1:34             ` Po Lu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87a6hrzrcv.fsf@yahoo.com \
    --to=luangruo@yahoo.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).