;; This package provides various useful commands (including help
;; system access) through the mouse. All this code assumes that mouse
;; interpretation has been abstracted into Emacs input events.
-;;
-;; The code is rather X-dependent.
;;; Code:
(window (posn-window start))
(frame (window-frame window))
(minibuffer-window (minibuffer-window frame))
- (on-link (and mouse-1-click-follows-link
- (mouse-on-link-p start)))
(side (and (eq line 'vertical)
(or (cdr (assq 'vertical-scroll-bars
(frame-parameters frame)))
(unless (zerop growth)
(setq dragged t)
(adjust-window-trailing-edge
- window (if (eq line 'mode) growth (- growth)) nil t))))))
- ;; Process the terminating event.
- (when (and (mouse-event-p event) on-link (not dragged)
- (mouse--remap-link-click-p start-event event))
- ;; If mouse-2 has never been done by the user, it doesn't have
- ;; the necessary property to be interpreted correctly.
- (put 'mouse-2 'event-kind 'mouse-click)
- (setcar event 'mouse-2)
- (push event unread-command-events))))
+ window (if (eq line 'mode) growth (- growth)) nil t))))))))
(defun mouse-drag-mode-line (start-event)
"Change the height of a window by dragging on the mode line."
(end (posn-point (event-end click)))
(click-count (event-click-count click)))
(let ((drag-start (terminal-parameter nil 'mouse-drag-start)))
- ;; Drag events don't come with a click count, sadly, so we hack
- ;; our way around this problem by remembering the start-event in
- ;; `mouse-drag-start' and fetching the click-count from there.
(when drag-start
+ ;; Drag events don't come with a click count, sadly, so we hack
+ ;; our way around this problem by remembering the start-event in
+ ;; `mouse-drag-start' and fetching the click-count from there.
(when (and (<= click-count 1)
(equal beg (posn-point (event-start drag-start))))
(setq click-count (event-click-count drag-start)))
+ ;; Occasionally we get spurious drag events where the user hasn't
+ ;; dragged his mouse, but instead Emacs has dragged the text under the
+ ;; user's mouse. Try to recover those cases (bug#17562).
+ (when (and (equal (posn-x-y (event-start click))
+ (posn-x-y (event-end click)))
+ (not (eq (car drag-start) 'mouse-movement)))
+ (setq end beg))
(setf (terminal-parameter nil 'mouse-drag-start) nil)))
(when (and (integerp beg) (integerp end))
(let ((range (mouse-start-end beg end (1- click-count))))
(defun mouse-set-region-1 ()
;; Set transient-mark-mode for a little while.
(unless (eq (car-safe transient-mark-mode) 'only)
- (setq transient-mark-mode
- (cons 'only
- (unless (eq transient-mark-mode 'lambda)
- transient-mark-mode))))
+ (setq-local transient-mark-mode
+ (cons 'only
+ (unless (eq transient-mark-mode 'lambda)
+ transient-mark-mode))))
(setq mouse-last-region-beg (region-beginning))
(setq mouse-last-region-end (region-end))
(setq mouse-last-region-tick (buffer-modified-tick)))
(str (posn-string pos)))
(or (and str
(get-text-property (cdr str) property (car str)))
- (and pt
+ ;; Mouse clicks in the fringe come with a position in
+ ;; (nth 5). This is useful but is not exactly where we clicked, so
+ ;; don't look up that position's properties!
+ (and pt (not (memq (posn-area pos) '(left-fringe right-fringe
+ left-margin right-margin)))
(get-char-property pt property w))))
(get-char-property pos property)))
;; Activate the region, using `mouse-start-end' to determine where
;; to put point and mark (e.g., double-click will select a word).
- (setq transient-mark-mode
- (if (eq transient-mark-mode 'lambda)
- '(only)
- (cons 'only transient-mark-mode)))
+ (setq-local transient-mark-mode
+ (if (eq transient-mark-mode 'lambda)
+ '(only)
+ (cons 'only transient-mark-mode)))
(let ((range (mouse-start-end start-point start-point click-count)))
(push-mark (nth 0 range) t t)
(goto-char (nth 1 range)))
(lambda (event) (interactive "e")
(let* ((end (event-end event))
(end-point (posn-point end)))
- (unless (eq end-point start-point)
+ (unless (eq end-point start-point)
;; As soon as the user moves, we can re-enable auto-hscroll.
- (setq auto-hscroll-mode auto-hscroll-mode-saved))
- (if (and (eq (posn-window end) start-window)
- (integer-or-marker-p end-point))
- (mouse--drag-set-mark-and-point start-point
- end-point click-count)
- (let ((mouse-row (cdr (cdr (mouse-position)))))
- (cond
- ((null mouse-row))
- ((< mouse-row top)
- (mouse-scroll-subr start-window (- mouse-row top)
- nil start-point))
- ((>= mouse-row bottom)
- (mouse-scroll-subr start-window (1+ (- mouse-row bottom))
- nil start-point))))))))
+ (setq auto-hscroll-mode auto-hscroll-mode-saved)
+ ;; And remember that we have moved, so mouse-set-region can know
+ ;; its event is really a drag event.
+ (setcar start-event 'mouse-movement))
+ (if (and (eq (posn-window end) start-window)
+ (integer-or-marker-p end-point))
+ (mouse--drag-set-mark-and-point start-point
+ end-point click-count)
+ (let ((mouse-row (cdr (cdr (mouse-position)))))
+ (cond
+ ((null mouse-row))
+ ((< mouse-row top)
+ (mouse-scroll-subr start-window (- mouse-row top)
+ nil start-point))
+ ((>= mouse-row bottom)
+ (mouse-scroll-subr start-window (1+ (- mouse-row bottom))
+ nil start-point))))))))
map)
t (lambda ()
(setq track-mouse nil)