Function: mouse-drag-drag
mouse-drag-drag is an autoloaded, interactive and byte-compiled
function defined in mouse-drag.el.gz.
Signature
(mouse-drag-drag START-EVENT)
Documentation
"Drag" the page according to a mouse drag.
Drag scrolling moves the page according to the movement of the mouse. You "grab" the character under the mouse and move it around.
If the mouse is clicked and released in the same place of time we assume that the user didn't want to scroll but wanted to whatever mouse-2 used to do, so we pass it through.
Drag scrolling is identical to the "hand" option in MacPaint, or the middle button in Tk text widgets.
To test this function, evaluate:
(keymap-global-set "<down-mouse-2>" 'mouse-drag-drag)
Probably introduced at or before Emacs version 20.1.
Key Bindings
Source Code
;; Defined in /usr/src/emacs/lisp/mouse-drag.el.gz
;;;###autoload
(defun mouse-drag-drag (start-event)
"\"Drag\" the page according to a mouse drag.
Drag scrolling moves the page according to the movement of the mouse.
You \"grab\" the character under the mouse and move it around.
If the mouse is clicked and released in the same place of time we
assume that the user didn't want to scroll but wanted to whatever
mouse-2 used to do, so we pass it through.
Drag scrolling is identical to the \"hand\" option in MacPaint, or the
middle button in Tk text widgets.
To test this function, evaluate:
(keymap-global-set \"<down-mouse-2>\" \\='mouse-drag-drag)"
(interactive "e")
;; we want to do save-selected-window, but that requires 19.29
(let* ((start-posn (event-start start-event))
(start-window (posn-window start-posn))
(start-row (cdr (posn-col-row start-posn)))
(start-col (car (posn-col-row start-posn)))
(old-selected-window (selected-window))
event end row scroll-delta
have-scrolled
window-last-row
col window-last-col
switch-frame-p
(scroll-col-delta 0)
;; be conservative about allowing horizontal scrolling
(col-scrolling-p (mouse-drag-should-do-col-scrolling)))
(select-window start-window)
(setq window-last-row (- (window-height) 2)
window-last-col (- (window-width) 2))
(track-mouse
;; Set 'track-mouse' to something neither nil nor t (Bug#51794).
(setq track-mouse 'drag-dragging)
(while (progn
(setq event (read--potential-mouse-event)
switch-frame-p (eq (car-safe event) 'switch-frame))
;; We want to skip switch-frame events and treat then
;; as moves over a different window. These events have
;; no position spec, so all the posn-* accessor
;; functions are likely to barf if passed such an
;; event.
(or switch-frame-p
(setq end (event-end event)
row (cdr (posn-col-row end))
col (car (posn-col-row end))))
(or (mouse-movement-p event) switch-frame-p))
;; Scroll if see if we're on the edge.
;; FIXME: should handle mouse-in-other window.
(cond
((or switch-frame-p (not (eq start-window (posn-window end))))
t) ; wait for return to original window
((<= row 0) (mouse-drag-repeatedly-safe-scroll -1 0))
((>= row window-last-row) (mouse-drag-repeatedly-safe-scroll 1 0))
((and col-scrolling-p (<= col 1)) (mouse-drag-repeatedly-safe-scroll 0 -1))
((and col-scrolling-p (>= col window-last-col)) (mouse-drag-repeatedly-safe-scroll 0 1))
(t
(setq scroll-delta (- row start-row)
start-row row)
(if col-scrolling-p
(setq scroll-col-delta (- col start-col)
start-col col))
(if (or (/= 0 scroll-delta)
(/= 0 scroll-col-delta))
(progn
(setq have-scrolled t)
(mouse-drag-safe-scroll scroll-delta scroll-col-delta)))))))
;; If it was a click and not a drag, prepare to pass the event on.
;; Is there a more correct way to reconstruct the event?
(if (and (not have-scrolled)
(mouse-drag-events-are-point-events-p start-posn end))
(push (cons (event-basic-type start-event) (cdr start-event))
unread-command-events))
;; Now restore the old window.
(select-window old-selected-window)))