123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- (require 'custom)
- (require 'timer)
- (defvar mouse-wheel-mode)
- (defun mouse-wheel-change-button (var button)
- (set-default var button)
-
- (when (bound-and-true-p mouse-wheel-mode) (mouse-wheel-mode 1)))
- (defvar mouse-wheel-down-button 4)
- (make-obsolete-variable 'mouse-wheel-down-button
- 'mouse-wheel-down-event
- "22.1")
- (defcustom mouse-wheel-down-event
- (if (or (featurep 'w32-win) (featurep 'ns-win))
- 'wheel-up
- (intern (format "mouse-%s" mouse-wheel-down-button)))
- "Event used for scrolling down."
- :group 'mouse
- :type 'symbol
- :set 'mouse-wheel-change-button)
- (defvar mouse-wheel-up-button 5)
- (make-obsolete-variable 'mouse-wheel-up-button
- 'mouse-wheel-up-event
- "22.1")
- (defcustom mouse-wheel-up-event
- (if (or (featurep 'w32-win) (featurep 'ns-win))
- 'wheel-down
- (intern (format "mouse-%s" mouse-wheel-up-button)))
- "Event used for scrolling up."
- :group 'mouse
- :type 'symbol
- :set 'mouse-wheel-change-button)
- (defvar mouse-wheel-click-button 2)
- (make-obsolete-variable 'mouse-wheel-click-button
- 'mouse-wheel-click-event
- "22.1")
- (defcustom mouse-wheel-click-event
- (intern (format "mouse-%s" mouse-wheel-click-button))
- "Event that should be temporarily inhibited after mouse scrolling.
- The mouse wheel is typically on the mouse-2 button, so it may easily
- happen that text is accidentally yanked into the buffer when
- scrolling with the mouse wheel. To prevent that, this variable can be
- set to the event sent when clicking on the mouse wheel button."
- :group 'mouse
- :type 'symbol
- :set 'mouse-wheel-change-button)
- (defcustom mouse-wheel-inhibit-click-time 0.35
- "Time in seconds to inhibit clicking on mouse wheel button after scroll."
- :group 'mouse
- :type 'number)
- (defcustom mouse-wheel-scroll-amount '(5 ((shift) . 1) ((control) . nil))
- "Amount to scroll windows by when spinning the mouse wheel.
- This is an alist mapping the modifier key to the amount to scroll when
- the wheel is moved with the modifier key depressed.
- Elements of the list have the form (MODIFIERS . AMOUNT) or just AMOUNT if
- MODIFIERS is nil.
- AMOUNT should be the number of lines to scroll, or nil for near full
- screen. It can also be a floating point number, specifying the fraction of
- a full screen to scroll. A near full screen is `next-screen-context-lines'
- less than a full screen."
- :group 'mouse
- :type '(cons
- (choice :tag "Normal"
- (const :tag "Full screen" :value nil)
- (integer :tag "Specific # of lines")
- (float :tag "Fraction of window")
- (cons
- (repeat (choice :tag "modifier"
- (const alt) (const control) (const hyper)
- (const meta) (const shift) (const super)))
- (choice :tag "scroll amount"
- (const :tag "Full screen" :value nil)
- (integer :tag "Specific # of lines")
- (float :tag "Fraction of window"))))
- (repeat
- (cons
- (repeat (choice :tag "modifier"
- (const alt) (const control) (const hyper)
- (const meta) (const shift) (const super)))
- (choice :tag "scroll amount"
- (const :tag "Full screen" :value nil)
- (integer :tag "Specific # of lines")
- (float :tag "Fraction of window")))))
- :set 'mouse-wheel-change-button)
- (defcustom mouse-wheel-progressive-speed t
- "If non-nil, the faster the user moves the wheel, the faster the scrolling.
- Note that this has no effect when `mouse-wheel-scroll-amount' specifies
- a \"near full screen\" scroll or when the mouse wheel sends key instead
- of button events."
- :group 'mouse
- :type 'boolean)
- (defcustom mouse-wheel-follow-mouse t
- "Whether the mouse wheel should scroll the window that the mouse is over.
- This can be slightly disconcerting, but some people prefer it."
- :group 'mouse
- :type 'boolean)
- (eval-and-compile
- (if (fboundp 'event-button)
- (fset 'mwheel-event-button 'event-button)
- (defun mwheel-event-button (event)
- (let ((x (event-basic-type event)))
-
- (if (eq 'mouse-wheel x)
- (let ((amount (car (cdr (cdr (cdr event))))))
- (if (< amount 0)
- mouse-wheel-up-event
- mouse-wheel-down-event))
- x))))
- (if (fboundp 'event-window)
- (fset 'mwheel-event-window 'event-window)
- (defun mwheel-event-window (event)
- (posn-window (event-start event)))))
- (defvar mwheel-inhibit-click-event-timer nil
- "Timer running while mouse wheel click event is inhibited.")
- (defun mwheel-inhibit-click-timeout ()
- "Handler for `mwheel-inhibit-click-event-timer'."
- (setq mwheel-inhibit-click-event-timer nil)
- (remove-hook 'pre-command-hook 'mwheel-filter-click-events))
- (defun mwheel-filter-click-events ()
- "Discard `mouse-wheel-click-event' while scrolling the mouse."
- (if (eq (event-basic-type last-input-event) mouse-wheel-click-event)
- (setq this-command 'ignore)))
- (defvar mwheel-scroll-up-function 'scroll-up
- "Function that does the job of scrolling upward.")
- (defvar mwheel-scroll-down-function 'scroll-down
- "Function that does the job of scrolling downward.")
- (defun mwheel-scroll (event)
- "Scroll up or down according to the EVENT.
- This should only be bound to mouse buttons 4 and 5."
- (interactive (list last-input-event))
- (let* ((curwin (if mouse-wheel-follow-mouse
- (prog1
- (selected-window)
- (select-window (mwheel-event-window event)))))
- (buffer (window-buffer curwin))
- (opoint (with-current-buffer buffer
- (when (eq (car-safe transient-mark-mode) 'only)
- (point))))
- (mods
- (delq 'click (delq 'double (delq 'triple (event-modifiers event)))))
- (amt (assoc mods mouse-wheel-scroll-amount)))
-
- (if amt (setq amt (cdr amt))
- (let ((list-elt mouse-wheel-scroll-amount))
- (while (consp (setq amt (pop list-elt))))))
- (if (floatp amt) (setq amt (1+ (truncate (* amt (window-height))))))
- (when (and mouse-wheel-progressive-speed (numberp amt))
-
-
- (setq amt (* amt (event-click-count event))))
- (unwind-protect
- (let ((button (mwheel-event-button event)))
- (cond ((eq button mouse-wheel-down-event)
- (condition-case nil (funcall mwheel-scroll-down-function amt)
-
-
- (beginning-of-buffer
- (unwind-protect
- (funcall mwheel-scroll-down-function)
-
-
-
-
-
-
-
- (set-window-start (selected-window) (point-min))))))
- ((eq button mouse-wheel-up-event)
- (condition-case nil (funcall mwheel-scroll-up-function amt)
-
- (end-of-buffer (while t (funcall mwheel-scroll-up-function)))))
- (t (error "Bad binding in mwheel-scroll"))))
- (if curwin (select-window curwin)))
-
-
- (when opoint
- (with-current-buffer buffer
- (when (/= opoint (point))
-
-
- (let ((newpoint (point)))
- (goto-char opoint)
- (deactivate-mark)
- (goto-char newpoint))))))
- (when (and mouse-wheel-click-event mouse-wheel-inhibit-click-time)
- (if mwheel-inhibit-click-event-timer
- (cancel-timer mwheel-inhibit-click-event-timer)
- (add-hook 'pre-command-hook 'mwheel-filter-click-events))
- (setq mwheel-inhibit-click-event-timer
- (run-with-timer mouse-wheel-inhibit-click-time nil
- 'mwheel-inhibit-click-timeout))))
- (put 'mwheel-scroll 'scroll-command t)
- (defvar mwheel-installed-bindings nil)
- (define-minor-mode mouse-wheel-mode
- "Toggle mouse wheel support (Mouse Wheel mode).
- With a prefix argument ARG, enable Mouse Wheel mode if ARG is
- positive, and disable it otherwise. If called from Lisp, enable
- the mode if ARG is omitted or nil."
- :init-value t
-
-
-
-
- :initialize 'custom-initialize-delay
- :global t
- :group 'mouse
-
- (while mwheel-installed-bindings
- (let ((key (pop mwheel-installed-bindings)))
- (when (eq (lookup-key (current-global-map) key) 'mwheel-scroll)
- (global-unset-key key))))
-
- (when mouse-wheel-mode
- (dolist (event (list mouse-wheel-down-event mouse-wheel-up-event))
- (dolist (key (mapcar (lambda (amt) `[(,@(if (consp amt) (car amt)) ,event)])
- mouse-wheel-scroll-amount))
- (global-set-key key 'mwheel-scroll)
- (push key mwheel-installed-bindings)))))
- (defun mwheel-install (&optional uninstall)
- "Enable mouse wheel support."
- (mouse-wheel-mode (if uninstall -1 1)))
- (provide 'mwheel)
|