2

Is it possible to activate a blocking 'scroll' mode that uses the vertical position of the cursor and a timer?

This is handy because you can move the cursor to a certain Y-delta to maintain a fixed scroll speed (In Firefox it's enabled by the "Use autoscrolling" preference).

Since emacs uses this terminology in a different way, it's hard tell if this feature exists for emacs.

  • Emacs has timers, can scroll and interact with the mouse cursor. That's basically all that's needed if I don't overlook something. I don't know if someone realized and released the functionality you ask for. Possibly you can start the project. – Marco Wahl Jul 8 at 19:29
2

Update: made this into a more comprehensive scroll-on-drag package.


Here is a simple implementation of modal scrolling.

(defvar modal-scroll--timer nil)
(defvar modal-scroll--delay 0.01)

(defun modal-scroll--up-update (y-init)
  (let ((delta (- (cdr (cdr (mouse-position))) y-init)))
    (ignore-errors (scroll-up delta)))
  (setq modal-scroll--timer
    (run-with-timer modal-scroll--delay nil 'modal-scroll--up-update y-init)))
(defun modal-scroll--down-update (y-init)
  (let ((delta (- y-init (cdr (cdr (mouse-position))))))
    (ignore-errors (scroll-down delta)))
  (setq modal-scroll--timer
    (run-with-timer modal-scroll--delay nil 'modal-scroll--down-update y-init)))


(defun modal-scroll-stop--internal ()
  (when modal-scroll--timer
    (cancel-timer modal-scroll--timer)
    (setq modal-scroll--timer nil)
    )
  )

(defun modal-scroll-drag () ""
  (interactive)
  (when modal-scroll--timer
    (modal-scroll-stop--internal))

  (let
    (
      (y-init (cdr (cdr (mouse-position))))
      (delta-prev 0)
      )

    (track-mouse
      (while
        (progn (setq event  (read-event))
          (or
            (mouse-movement-p event)
            (memq (car-safe event) '(switch-frame select-window)))
          )
        (unless (memq (car-safe event) '(switch-frame select-window))
          (let ((delta (- (cdr (cdr (mouse-position))) y-init)))
            (cond
              ((> delta 0)
                (unless (> delta delta-prev 0)
                  (modal-scroll-stop--internal)
                  (setq modal-scroll--timer
                    (run-with-timer 0.0 nil 'modal-scroll--up-update y-init))))
              ((< delta 0)
                (unless (< delta-prev 0)
                  (modal-scroll-stop--internal)
                  (setq modal-scroll--timer
                    (run-with-timer 0.0 nil 'modal-scroll--down-update y-init))))
              ((eq delta 0)
                (modal-scroll-stop--internal))
              )
            (setq delta-prev delta)
            )
          )
        )
      (modal-scroll-stop--internal)
      )
    )
  )

(global-set-key [mouse-2] 'modal-scroll-drag)

Note that I didn't figure out how to make this co-exist with click events (so click events can be triggered as well as drag). See How to handle & differentiate both click & drag mouse button events?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.