aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/ChangeLog16
-rw-r--r--lisp/mouse.el143
-rw-r--r--lisp/reveal.el8
-rw-r--r--lisp/xt-mouse.el169
4 files changed, 168 insertions, 168 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 72c6d943710..52c1f0c164a 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,21 @@
12014-05-11 Stefan Monnier <monnier@iro.umontreal.ca> 12014-05-11 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * mouse.el: Use the normal toplevel loop while dragging.
4 (mouse-set-point): Handle multi-clicks.
5 (mouse-set-region): Handle multi-clicks for drags.
6 (mouse-drag-region): Update call accordingly.
7 (mouse-drag-track): Remove `do-mouse-drag-region-post-process' hack.
8 Use the normal event loop instead of a local while/read-event loop.
9 (global-map): Remove redundant bindings for double/triple-mouse-1.
10 * xt-mouse.el (xterm-mouse-translate-1): Only process one event at a time.
11 Generate synthetic down events when the protocol only sends up events.
12 (xterm-mouse-last): Remove.
13 (xterm-mouse--read-event-sequence-1000): Use xterm-mouse-last-down
14 terminal parameter instead.
15 (xterm-mouse--set-click-count): New function.
16 (xterm-mouse-event): Detect/generate double/triple clicks.
17 * reveal.el (reveal-close-old-overlays): Don't close while dragging.
18
3 * info.el (Info-quoted): New face. 19 * info.el (Info-quoted): New face.
4 (Info-mode-font-lock-keywords): New var. 20 (Info-mode-font-lock-keywords): New var.
5 (Info-mode): Use it. 21 (Info-mode): Use it.
diff --git a/lisp/mouse.el b/lisp/mouse.el
index 9b1422f0658..ca94a343c1a 100644
--- a/lisp/mouse.el
+++ b/lisp/mouse.el
@@ -514,14 +514,18 @@ must be one of the symbols `header', `mode', or `vertical'."
514 (interactive "e") 514 (interactive "e")
515 (mouse-drag-line start-event 'vertical)) 515 (mouse-drag-line start-event 'vertical))
516 516
517(defun mouse-set-point (event) 517(defun mouse-set-point (event &optional promote-to-region)
518 "Move point to the position clicked on with the mouse. 518 "Move point to the position clicked on with the mouse.
519This should be bound to a mouse click event type." 519This should be bound to a mouse click event type.
520 (interactive "e") 520If PROMOTE-TO-REGION is non-nil and event is a multiple-click,
521select the corresponding element around point."
522 (interactive "e\np")
521 (mouse-minibuffer-check event) 523 (mouse-minibuffer-check event)
522 ;; Use event-end in case called from mouse-drag-region. 524 (if (and promote-to-region (> (event-click-count event) 1))
523 ;; If EVENT is a click, event-end and event-start give same value. 525 (mouse-set-region event)
524 (posn-set-point (event-end event))) 526 ;; Use event-end in case called from mouse-drag-region.
527 ;; If EVENT is a click, event-end and event-start give same value.
528 (posn-set-point (event-end event))))
525 529
526(defvar mouse-last-region-beg nil) 530(defvar mouse-last-region-beg nil)
527(defvar mouse-last-region-end nil) 531(defvar mouse-last-region-end nil)
@@ -534,6 +538,8 @@ This should be bound to a mouse click event type."
534 (eq mouse-last-region-end (region-end)) 538 (eq mouse-last-region-end (region-end))
535 (eq mouse-last-region-tick (buffer-modified-tick)))) 539 (eq mouse-last-region-tick (buffer-modified-tick))))
536 540
541(defvar mouse--drag-start-event nil)
542
537(defun mouse-set-region (click) 543(defun mouse-set-region (click)
538 "Set the region to the text dragged over, and copy to kill ring. 544 "Set the region to the text dragged over, and copy to kill ring.
539This should be bound to a mouse drag event. 545This should be bound to a mouse drag event.
@@ -543,7 +549,22 @@ command alters the kill ring or not."
543 (mouse-minibuffer-check click) 549 (mouse-minibuffer-check click)
544 (select-window (posn-window (event-start click))) 550 (select-window (posn-window (event-start click)))
545 (let ((beg (posn-point (event-start click))) 551 (let ((beg (posn-point (event-start click)))
546 (end (posn-point (event-end click)))) 552 (end (posn-point (event-end click)))
553 (click-count (event-click-count click)))
554 (let ((drag-start (terminal-parameter nil 'mouse-drag-start)))
555 ;; Drag events don't come with a click count, sadly, so we hack
556 ;; our way around this problem by remembering the start-event in
557 ;; `mouse-drag-start' and fetching the click-count from there.
558 (when drag-start
559 (when (and (<= click-count 1)
560 (equal beg (posn-point (event-start drag-start))))
561 (setq click-count (event-click-count drag-start)))
562 (setf (terminal-parameter nil 'mouse-drag-start) nil)))
563 (when (and (integerp beg) (integerp end))
564 (let ((range (mouse-start-end beg end (1- click-count))))
565 (if (< end beg)
566 (setq end (nth 0 range) beg (nth 1 range))
567 (setq beg (nth 0 range) end (nth 1 range)))))
547 (and mouse-drag-copy-region (integerp beg) (integerp end) 568 (and mouse-drag-copy-region (integerp beg) (integerp end)
548 ;; Don't set this-command to `kill-region', so a following 569 ;; Don't set this-command to `kill-region', so a following
549 ;; C-w won't double the text in the kill ring. Ignore 570 ;; C-w won't double the text in the kill ring. Ignore
@@ -637,13 +658,11 @@ Upon exit, point is at the far edge of the newly visible text."
637Highlight the drag area as you move the mouse. 658Highlight the drag area as you move the mouse.
638This must be bound to a button-down mouse event. 659This must be bound to a button-down mouse event.
639In Transient Mark mode, the highlighting remains as long as the mark 660In Transient Mark mode, the highlighting remains as long as the mark
640remains active. Otherwise, it remains until the next input event. 661remains active. Otherwise, it remains until the next input event."
641
642If the click is in the echo area, display the `*Messages*' buffer."
643 (interactive "e") 662 (interactive "e")
644 ;; Give temporary modes such as isearch a chance to turn off. 663 ;; Give temporary modes such as isearch a chance to turn off.
645 (run-hooks 'mouse-leave-buffer-hook) 664 (run-hooks 'mouse-leave-buffer-hook)
646 (mouse-drag-track start-event t)) 665 (mouse-drag-track start-event))
647 666
648 667
649(defun mouse-posn-property (pos property) 668(defun mouse-posn-property (pos property)
@@ -747,12 +766,9 @@ at the same position."
747 "mouse-1" (substring msg 7))))))) 766 "mouse-1" (substring msg 7)))))))
748 msg) 767 msg)
749 768
750(defun mouse-drag-track (start-event &optional 769(defun mouse-drag-track (start-event)
751 do-mouse-drag-region-post-process)
752 "Track mouse drags by highlighting area between point and cursor. 770 "Track mouse drags by highlighting area between point and cursor.
753The region will be defined with mark and point. 771The region will be defined with mark and point."
754DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by
755`mouse-drag-region'."
756 (mouse-minibuffer-check start-event) 772 (mouse-minibuffer-check start-event)
757 (setq mouse-selection-click-count-buffer (current-buffer)) 773 (setq mouse-selection-click-count-buffer (current-buffer))
758 (deactivate-mark) 774 (deactivate-mark)
@@ -765,8 +781,6 @@ DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by
765 (start-posn (event-start start-event)) 781 (start-posn (event-start start-event))
766 (start-point (posn-point start-posn)) 782 (start-point (posn-point start-posn))
767 (start-window (posn-window start-posn)) 783 (start-window (posn-window start-posn))
768 (start-window-start (window-start start-window))
769 (start-hscroll (window-hscroll start-window))
770 (bounds (window-edges start-window)) 784 (bounds (window-edges start-window))
771 (make-cursor-line-fully-visible nil) 785 (make-cursor-line-fully-visible nil)
772 (top (nth 1 bounds)) 786 (top (nth 1 bounds))
@@ -777,9 +791,7 @@ DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by
777 (click-count (1- (event-click-count start-event))) 791 (click-count (1- (event-click-count start-event)))
778 ;; Suppress automatic hscrolling, because that is a nuisance 792 ;; Suppress automatic hscrolling, because that is a nuisance
779 ;; when setting point near the right fringe (but see below). 793 ;; when setting point near the right fringe (but see below).
780 (auto-hscroll-mode-saved auto-hscroll-mode) 794 (auto-hscroll-mode-saved auto-hscroll-mode))
781 (auto-hscroll-mode nil)
782 moved-off-start event end end-point)
783 795
784 (setq mouse-selection-click-count click-count) 796 (setq mouse-selection-click-count click-count)
785 ;; In case the down click is in the middle of some intangible text, 797 ;; In case the down click is in the middle of some intangible text,
@@ -798,23 +810,21 @@ DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by
798 (push-mark (nth 0 range) t t) 810 (push-mark (nth 0 range) t t)
799 (goto-char (nth 1 range))) 811 (goto-char (nth 1 range)))
800 812
801 ;; Track the mouse until we get a non-movement event. 813 (setf (terminal-parameter nil 'mouse-drag-start) start-event)
802 (track-mouse 814 (setq track-mouse t)
803 (while (progn 815 (setq auto-hscroll-mode nil)
804 (setq event (read-event)) 816
805 (or (mouse-movement-p event) 817 (set-transient-map
806 (memq (car-safe event) '(switch-frame select-window)))) 818 (let ((map (make-sparse-keymap)))
807 (unless (memq (car-safe event) '(switch-frame select-window)) 819 (define-key map [switch-frame] #'ignore)
808 ;; Automatic hscrolling did not occur during the call to 820 (define-key map [select-window] #'ignore)
809 ;; `read-event'; but if the user subsequently drags the 821 (define-key map [mouse-movement]
810 ;; mouse, go ahead and hscroll. 822 (lambda (event) (interactive "e")
811 (let ((auto-hscroll-mode auto-hscroll-mode-saved)) 823 (let* ((end (event-end event))
812 (redisplay)) 824 (end-point (posn-point end)))
813 (setq end (event-end event)
814 end-point (posn-point end))
815 ;; Note whether the mouse has left the starting position.
816 (unless (eq end-point start-point) 825 (unless (eq end-point start-point)
817 (setq moved-off-start t)) 826 ;; As soon as the user moves, we can re-enable auto-hscroll.
827 (setq auto-hscroll-mode auto-hscroll-mode-saved))
818 (if (and (eq (posn-window end) start-window) 828 (if (and (eq (posn-window end) start-window)
819 (integer-or-marker-p end-point)) 829 (integer-or-marker-p end-point))
820 (mouse--drag-set-mark-and-point start-point 830 (mouse--drag-set-mark-and-point start-point
@@ -828,55 +838,12 @@ DO-MOUSE-DRAG-REGION-POST-PROCESS should only be used by
828 ((>= mouse-row bottom) 838 ((>= mouse-row bottom)
829 (mouse-scroll-subr start-window (1+ (- mouse-row bottom)) 839 (mouse-scroll-subr start-window (1+ (- mouse-row bottom))
830 nil start-point)))))))) 840 nil start-point))))))))
831 841 map)
832 ;; Handle the terminating event if possible. 842 t (lambda ()
833 (when (consp event) 843 (setq track-mouse nil)
834 ;; Ensure that point is on the end of the last event. 844 (setq auto-hscroll-mode auto-hscroll-mode-saved)
835 (when (and (setq end-point (posn-point (event-end event)))
836 (eq (posn-window end) start-window)
837 (integer-or-marker-p end-point)
838 (/= start-point end-point))
839 (mouse--drag-set-mark-and-point start-point
840 end-point click-count))
841
842 ;; Find its binding.
843 (let* ((fun (key-binding (vector (car event))))
844 ;; FIXME This doesn't make sense, because
845 ;; event-click-count always returns something >= 1.
846 (do-multi-click (and (> (event-click-count event) 0)
847 (functionp fun)
848 (not (memq fun '(mouse-set-point
849 mouse-set-region))))))
850 (if (and (/= (mark) (point))
851 (not do-multi-click))
852
853 ;; If point has moved, finish the drag.
854 (let* (last-command this-command)
855 (and mouse-drag-copy-region
856 do-mouse-drag-region-post-process
857 (let (deactivate-mark)
858 (copy-region-as-kill (mark) (point)))))
859
860 ;; Otherwise, run binding of terminating up-event.
861 (deactivate-mark) 845 (deactivate-mark)
862 (if do-multi-click 846 (pop-mark)))))
863 (goto-char start-point)
864 (unless moved-off-start
865 (pop-mark)))
866
867 (when (and (functionp fun)
868 (= start-hscroll (window-hscroll start-window))
869 ;; Don't run the up-event handler if the window
870 ;; start changed in a redisplay after the
871 ;; mouse-set-point for the down-mouse event at
872 ;; the beginning of this function. When the
873 ;; window start has changed, the up-mouse event
874 ;; contains a different position due to the new
875 ;; window contents, and point is set again.
876 (or end-point
877 (= (window-start start-window)
878 start-window-start)))
879 (push event unread-command-events)))))))
880 847
881(defun mouse--drag-set-mark-and-point (start click click-count) 848(defun mouse--drag-set-mark-and-point (start click click-count)
882 (let* ((range (mouse-start-end start click click-count)) 849 (let* ((range (mouse-start-end start click click-count))
@@ -1904,14 +1871,10 @@ choose a font."
1904 1871
1905;;; Bindings for mouse commands. 1872;;; Bindings for mouse commands.
1906 1873
1907(define-key global-map [down-mouse-1] 'mouse-drag-region) 1874(global-set-key [down-mouse-1] 'mouse-drag-region)
1908(global-set-key [mouse-1] 'mouse-set-point) 1875(global-set-key [mouse-1] 'mouse-set-point)
1909(global-set-key [drag-mouse-1] 'mouse-set-region) 1876(global-set-key [drag-mouse-1] 'mouse-set-region)
1910 1877
1911;; These are tested for in mouse-drag-region.
1912(global-set-key [double-mouse-1] 'mouse-set-point)
1913(global-set-key [triple-mouse-1] 'mouse-set-point)
1914
1915(defun mouse--strip-first-event (_prompt) 1878(defun mouse--strip-first-event (_prompt)
1916 (substring (this-single-command-raw-keys) 1)) 1879 (substring (this-single-command-raw-keys) 1))
1917 1880
diff --git a/lisp/reveal.el b/lisp/reveal.el
index f251c05f5eb..8d611ea04df 100644
--- a/lisp/reveal.el
+++ b/lisp/reveal.el
@@ -83,7 +83,8 @@ Each element has the form (WINDOW . OVERLAY).")
83 (cond 83 (cond
84 ((eq (car x) (selected-window)) (cdr x)) 84 ((eq (car x) (selected-window)) (cdr x))
85 ((not (and (window-live-p (car x)) 85 ((not (and (window-live-p (car x))
86 (eq (window-buffer (car x)) (current-buffer)))) 86 (eq (window-buffer (car x))
87 (current-buffer))))
87 ;; Adopt this since it's owned by a window that's 88 ;; Adopt this since it's owned by a window that's
88 ;; either not live or at least not showing this 89 ;; either not live or at least not showing this
89 ;; buffer any more. 90 ;; buffer any more.
@@ -135,8 +136,9 @@ Each element has the form (WINDOW . OVERLAY).")
135 old-ols) 136 old-ols)
136 137
137(defun reveal-close-old-overlays (old-ols) 138(defun reveal-close-old-overlays (old-ols)
138 (if (not (eq reveal-last-tick 139 (if (or track-mouse ;Don't close in the middle of a click.
139 (setq reveal-last-tick (buffer-modified-tick)))) 140 (not (eq reveal-last-tick
141 (setq reveal-last-tick (buffer-modified-tick)))))
140 ;; The buffer was modified since last command: let's refrain from 142 ;; The buffer was modified since last command: let's refrain from
141 ;; closing any overlay because it tends to behave poorly when 143 ;; closing any overlay because it tends to behave poorly when
142 ;; inserting text at the end of an overlay (basically the overlay 144 ;; inserting text at the end of an overlay (basically the overlay
diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el
index fc515974036..54fd1a44d5b 100644
--- a/lisp/xt-mouse.el
+++ b/lisp/xt-mouse.el
@@ -42,13 +42,12 @@
42 42
43(defvar xterm-mouse-debug-buffer nil) 43(defvar xterm-mouse-debug-buffer nil)
44 44
45(defvar xterm-mouse-last)
46
47;; Mouse events symbols must have an 'event-kind property with 45;; Mouse events symbols must have an 'event-kind property with
48;; the value 'mouse-click. 46;; the value 'mouse-click.
49(dolist (event-type '(mouse-1 mouse-2 mouse-3 47(dolist (event '(mouse-1 mouse-2 mouse-3 mouse-4 mouse-5))
50 M-down-mouse-1 M-down-mouse-2 M-down-mouse-3)) 48 (let ((M-event (intern (concat "M-" (symbol-name event)))))
51 (put event-type 'event-kind 'mouse-click)) 49 (put event 'event-kind 'mouse-click)
50 (put M-event 'event-kind 'mouse-click)))
52 51
53(defun xterm-mouse-translate (_event) 52(defun xterm-mouse-translate (_event)
54 "Read a click and release event from XTerm." 53 "Read a click and release event from XTerm."
@@ -65,59 +64,47 @@ http://invisible-island.net/xterm/ctlseqs/ctlseqs.html)."
65 (save-excursion 64 (save-excursion
66 (save-window-excursion ;FIXME: Why? 65 (save-window-excursion ;FIXME: Why?
67 (deactivate-mark) ;FIXME: Why? 66 (deactivate-mark) ;FIXME: Why?
68 (let* ((xterm-mouse-last nil) 67 (let* ((event (xterm-mouse-event extension))
69 (down (xterm-mouse-event extension)) 68 (ev-command (nth 0 event))
70 (down-command (nth 0 down)) 69 (ev-data (nth 1 event))
71 (down-data (nth 1 down)) 70 (ev-where (nth 1 ev-data))
72 (down-where (nth 1 down-data)) 71 (vec (if (and (symbolp ev-where) (consp ev-where))
73 (down-binding (key-binding (if (symbolp down-where) 72 ;; FIXME: This condition can *never* be non-nil!?!
74 (vector down-where down-command) 73 (vector (list ev-where ev-data) event)
75 (vector down-command)))) 74 (vector event)))
76 (is-down (string-match "down" (symbol-name (car down))))) 75 (is-down (string-match "down-" (symbol-name ev-command))))
77 76
78 ;; Retrieve the expected preface for the up-event.
79 (unless is-down
80 (unless (cond ((null extension)
81 (and (eq (read-event) ?\e)
82 (eq (read-event) ?\[)
83 (eq (read-event) ?M)))
84 ((eq extension 1006)
85 (and (eq (read-event) ?\e)
86 (eq (read-event) ?\[)
87 (eq (read-event) ?<))))
88 (error "Unexpected escape sequence from XTerm")))
89
90 ;; Process the up-event.
91 (let* ((click (if is-down (xterm-mouse-event extension) down))
92 (click-data (nth 1 click))
93 (click-where (nth 1 click-data)))
94 (cond 77 (cond
95 ((null down) nil) 78 ((null event) nil) ;Unknown/bogus byte sequence!
96 ((memq down-binding '(nil ignore)) 79 (is-down
97 (if (and (symbolp click-where) 80 (setf (terminal-parameter nil 'xterm-mouse-last-down) event)
98 (consp click-where)) 81 vec)
99 (vector (list click-where click-data) click) 82 (t
100 (vector click))) 83 (let* ((down (terminal-parameter nil 'xterm-mouse-last-down))
84 (down-data (nth 1 down))
85 (down-where (nth 1 down-data)))
86 (setf (terminal-parameter nil 'xterm-mouse-last-down) nil)
87 (cond
88 ((null down)
89 ;; This is an "up-only" event. Pretend there was an up-event
90 ;; right before and keep the up-event for later.
91 (push event unread-command-events)
92 (vector (cons (intern (replace-regexp-in-string
93 "\\`\\([ACMHSs]-\\)*" "\\&down-"
94 (symbol-name ev-command) t))
95 (cdr event))))
96 ((equal ev-where down-where) vec)
101 (t 97 (t
102 (setq unread-command-events 98 (let ((drag (if (symbolp ev-where)
103 (append (if (eq down-where click-where) 99 0 ;FIXME: Why?!?
104 (list click) 100 (list (replace-regexp-in-string
105 (list 101 "\\`\\([ACMHSs]-\\)*" "\\&drag-"
106 ;; Cheat `mouse-drag-region' with move event. 102 (symbol-name ev-command) t)
107 (list 'mouse-movement click-data) 103 down-data ev-data))))
108 ;; Generate a drag event. 104 (if (null track-mouse)
109 (if (symbolp down-where) 105 (vector drag)
110 0 106 (push drag unread-command-events)
111 (list (intern (format "drag-mouse-%d" 107 (vector (list 'mouse-movement ev-data)))))))))))))
112 (1+ xterm-mouse-last)))
113 down-data click-data))))
114 unread-command-events))
115 (if xterm-mouse-debug-buffer
116 (print unread-command-events xterm-mouse-debug-buffer))
117 (if (and (symbolp down-where)
118 (consp down-where))
119 (vector (list down-where down-data) down)
120 (vector down)))))))))
121 108
122;; These two variables have been converted to terminal parameters. 109;; These two variables have been converted to terminal parameters.
123;; 110;;
@@ -165,16 +152,14 @@ http://invisible-island.net/xterm/ctlseqs/ctlseqs.html)."
165 (cond ((>= code 64) 152 (cond ((>= code 64)
166 (format "mouse-%d" (- code 60))) 153 (format "mouse-%d" (- code 60)))
167 ((memq code '(8 9 10)) 154 ((memq code '(8 9 10))
168 (setq xterm-mouse-last (- code 8))
169 (format "M-down-mouse-%d" (- code 7))) 155 (format "M-down-mouse-%d" (- code 7)))
170 ((and (= code 11) xterm-mouse-last) 156 ((memq code '(3 11))
171 (format "M-mouse-%d" (1+ xterm-mouse-last))) 157 (let ((down (car (terminal-parameter
172 ((and (= code 3) xterm-mouse-last) 158 nil 'xterm-mouse-last-down))))
173 ;; For buttons > 5 xterm only reports a button-release event. 159 (when (and down (string-match "[0-9]" (symbol-name down)))
174 ;; Drop them since they're not usable and can be spurious. 160 (format (if (eq code 3) "mouse-%s" "M-mouse-%s")
175 (format "mouse-%d" (1+ xterm-mouse-last))) 161 (match-string 0 (symbol-name down))))))
176 ((memq code '(0 1 2)) 162 ((memq code '(0 1 2))
177 (setq xterm-mouse-last code)
178 (format "down-mouse-%d" (+ 1 code)))))) 163 (format "down-mouse-%d" (+ 1 code))))))
179 (x (- (read-event) 33)) 164 (x (- (read-event) 33))
180 (y (- (read-event) 33))) 165 (y (- (read-event) 33)))
@@ -212,10 +197,20 @@ http://invisible-island.net/xterm/ctlseqs/ctlseqs.html)."
212 (if down "down-" "") 197 (if down "down-" "")
213 (if wheel 198 (if wheel
214 (- code 60) 199 (- code 60)
215 (1+ (setq xterm-mouse-last (mod code 4))))))) 200 (1+ (mod code 4))))))
216 (1- (string-to-number (apply 'string (nreverse x-bytes)))) 201 (1- (string-to-number (apply 'string (nreverse x-bytes))))
217 (1- (string-to-number (apply 'string (nreverse y-bytes))))))) 202 (1- (string-to-number (apply 'string (nreverse y-bytes)))))))
218 203
204(defun xterm-mouse--set-click-count (event click-count)
205 (setcdr (cdr event) (list click-count))
206 (let ((name (symbol-name (car event))))
207 (when (string-match "\\(.*?\\)\\(\\(?:down-\\)?mouse-.*\\)" name)
208 (setcar event
209 (intern (concat (match-string 1 name)
210 (if (= click-count 2)
211 "double-" "triple-")
212 (match-string 2 name)))))))
213
219(defun xterm-mouse-event (&optional extension) 214(defun xterm-mouse-event (&optional extension)
220 "Convert XTerm mouse event to Emacs mouse event. 215 "Convert XTerm mouse event to Emacs mouse event.
221EXTENSION, if non-nil, means to use an extension to the usual 216EXTENSION, if non-nil, means to use an extension to the usual
@@ -241,18 +236,42 @@ which is the \"1006\" extension implemented in Xterm >= 277."
241 (w (window-at x y)) 236 (w (window-at x y))
242 (ltrb (window-edges w)) 237 (ltrb (window-edges w))
243 (left (nth 0 ltrb)) 238 (left (nth 0 ltrb))
244 (top (nth 1 ltrb))) 239 (top (nth 1 ltrb))
245 (set-terminal-parameter nil 'xterm-mouse-x x) 240 (posn (if w
246 (set-terminal-parameter nil 'xterm-mouse-y y)
247 (setq
248 last-input-event
249 (list type
250 (let ((event (if w
251 (posn-at-x-y (- x left) (- y top) w t) 241 (posn-at-x-y (- x left) (- y top) w t)
252 (append (list nil 'menu-bar) 242 (append (list nil 'menu-bar)
253 (nthcdr 2 (posn-at-x-y x y)))))) 243 (nthcdr 2 (posn-at-x-y x y)))))
254 (setcar (nthcdr 3 event) timestamp) 244 (event (list type posn)))
255 event))))))) 245 (setcar (nthcdr 3 posn) timestamp)
246
247 ;; Try to handle double/triple clicks.
248 (let* ((last-click (terminal-parameter nil 'xterm-mouse-last-click))
249 (last-type (nth 0 last-click))
250 (last-name (symbol-name last-type))
251 (last-time (nth 1 last-click))
252 (click-count (nth 2 last-click))
253 (this-time (float-time))
254 (name (symbol-name type)))
255 (cond
256 ((not (string-match "down-" name))
257 ;; For up events, make the up side match the down side.
258 (setq this-time last-time)
259 (when (and (> click-count 1)
260 (string-match "down-" last-name)
261 (equal name (replace-match "" t t last-name)))
262 (xterm-mouse--set-click-count event click-count)))
263 ((not last-time) nil)
264 ((and (> double-click-time (* 1000 (- this-time last-time)))
265 (equal last-name (replace-match "" t t name)))
266 (setq click-count (1+ click-count))
267 (xterm-mouse--set-click-count event click-count))
268 (t (setq click-count 1)))
269 (set-terminal-parameter nil 'xterm-mouse-last-click
270 (list type this-time click-count)))
271
272 (set-terminal-parameter nil 'xterm-mouse-x x)
273 (set-terminal-parameter nil 'xterm-mouse-y y)
274 (setq last-input-event event)))))
256 275
257;;;###autoload 276;;;###autoload
258(define-minor-mode xterm-mouse-mode 277(define-minor-mode xterm-mouse-mode