diff options
| -rw-r--r-- | lisp/ChangeLog | 16 | ||||
| -rw-r--r-- | lisp/mouse.el | 143 | ||||
| -rw-r--r-- | lisp/reveal.el | 8 | ||||
| -rw-r--r-- | lisp/xt-mouse.el | 169 |
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 @@ | |||
| 1 | 2014-05-11 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2014-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. |
| 519 | This should be bound to a mouse click event type." | 519 | This should be bound to a mouse click event type. |
| 520 | (interactive "e") | 520 | If PROMOTE-TO-REGION is non-nil and event is a multiple-click, |
| 521 | select 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. |
| 539 | This should be bound to a mouse drag event. | 545 | This 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." | |||
| 637 | Highlight the drag area as you move the mouse. | 658 | Highlight the drag area as you move the mouse. |
| 638 | This must be bound to a button-down mouse event. | 659 | This must be bound to a button-down mouse event. |
| 639 | In Transient Mark mode, the highlighting remains as long as the mark | 660 | In Transient Mark mode, the highlighting remains as long as the mark |
| 640 | remains active. Otherwise, it remains until the next input event. | 661 | remains active. Otherwise, it remains until the next input event." |
| 641 | |||
| 642 | If 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. |
| 753 | The region will be defined with mark and point. | 771 | The region will be defined with mark and point." |
| 754 | DO-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. |
| 221 | EXTENSION, if non-nil, means to use an extension to the usual | 216 | EXTENSION, 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 |