diff options
| author | Olaf Rogalsky | 2015-03-24 21:04:00 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2015-03-24 21:04:00 -0400 |
| commit | c2385c6f36d346d6524a4119109f52d4fd975244 (patch) | |
| tree | 70d917cbe59b248222db3ec1d30a9ab51b3d9f61 | |
| parent | b28753b55ce83215b15661d16bfbafe3c8964b2a (diff) | |
| download | emacs-c2385c6f36d346d6524a4119109f52d4fd975244.tar.gz emacs-c2385c6f36d346d6524a4119109f52d4fd975244.zip | |
* lisp/xt-mouse.el: Add mouse-tracking support.
Fixes: debbugs:19416
* lisp/xt-mouse.el: Add mouse-tracking support.
(xterm-mouse-translate-1): Handle mouse-movement events.
(xterm-mouse--read-event-sequence-1000)
(xterm-mouse--read-event-sequence-1006): Delete functions.
(xterm-mouse--read-event-sequence): New function that handles both at
the same time. Handle mouse-movements.
(xterm-mouse--read-utf8-char, xterm-mouse--read-number-from-terminal):
New functions.
(xterm-mouse-event): Simplify.
(xterm-mouse-tracking-enable-sequence)
(xterm-mouse-tracking-disable-sequence): Enable mouse tracking.
* lisp/mouse.el (mouse-drag-line): Also ignore `vertical-line' prefix events.
| -rw-r--r-- | etc/NEWS | 2 | ||||
| -rw-r--r-- | lisp/ChangeLog | 16 | ||||
| -rw-r--r-- | lisp/mouse.el | 3 | ||||
| -rw-r--r-- | lisp/xt-mouse.el | 185 |
4 files changed, 136 insertions, 70 deletions
| @@ -217,6 +217,8 @@ Unicode standards. | |||
| 217 | 217 | ||
| 218 | 218 | ||
| 219 | * Changes in Specialized Modes and Packages in Emacs 25.1 | 219 | * Changes in Specialized Modes and Packages in Emacs 25.1 |
| 220 | ** xterm-mouse-mode now supports mouse-tracking (if your xterm supports it). | ||
| 221 | |||
| 220 | ** package.el | 222 | ** package.el |
| 221 | *** `package-install-from-buffer' and `package-install-file' work on directories. | 223 | *** `package-install-from-buffer' and `package-install-file' work on directories. |
| 222 | This follows the same rules as installing from a .tar file, except the | 224 | This follows the same rules as installing from a .tar file, except the |
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 3b8fa7d66c7..0d2f59227e9 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,19 @@ | |||
| 1 | 2015-03-25 Olaf Rogalsky <olaf.rogalsky@gmail.com> | ||
| 2 | |||
| 3 | * xt-mouse.el: Add mouse-tracking support (bug#19416). | ||
| 4 | (xterm-mouse-translate-1): Handle mouse-movement events. | ||
| 5 | (xterm-mouse--read-event-sequence-1000) | ||
| 6 | (xterm-mouse--read-event-sequence-1006): Delete functions. | ||
| 7 | (xterm-mouse--read-event-sequence): New function that handles both at | ||
| 8 | the same time. Handle mouse-movements. | ||
| 9 | (xterm-mouse--read-utf8-char, xterm-mouse--read-number-from-terminal): | ||
| 10 | New functions. | ||
| 11 | (xterm-mouse-event): Simplify. | ||
| 12 | (xterm-mouse-tracking-enable-sequence) | ||
| 13 | (xterm-mouse-tracking-disable-sequence): Enable mouse tracking. | ||
| 14 | |||
| 15 | * mouse.el (mouse-drag-line): Also ignore `vertical-line' prefix events. | ||
| 16 | |||
| 1 | 2015-03-24 Michael Albinus <michael.albinus@gmx.de> | 17 | 2015-03-24 Michael Albinus <michael.albinus@gmx.de> |
| 2 | 18 | ||
| 3 | * net/tramp-sh.el (tramp-do-file-attributes-with-ls) | 19 | * net/tramp-sh.el (tramp-do-file-attributes-with-ls) |
diff --git a/lisp/mouse.el b/lisp/mouse.el index c50913f4636..5f3fa5d7694 100644 --- a/lisp/mouse.el +++ b/lisp/mouse.el | |||
| @@ -486,9 +486,10 @@ must be one of the symbols `header', `mode', or `vertical'." | |||
| 486 | `(menu-item "" ,(lambda () (interactive) (funcall exitfun)) | 486 | `(menu-item "" ,(lambda () (interactive) (funcall exitfun)) |
| 487 | :filter ,(lambda (cmd) (if dragged cmd))))) | 487 | :filter ,(lambda (cmd) (if dragged cmd))))) |
| 488 | ;; Some of the events will of course end up looked up | 488 | ;; Some of the events will of course end up looked up |
| 489 | ;; with a mode-line or header-line prefix ... | 489 | ;; with a mode-line, header-line or vertical-line prefix ... |
| 490 | (define-key map [mode-line] map) | 490 | (define-key map [mode-line] map) |
| 491 | (define-key map [header-line] map) | 491 | (define-key map [header-line] map) |
| 492 | (define-key map [vertical-line] map) | ||
| 492 | ;; ... and some maybe even with a right- or bottom-divider | 493 | ;; ... and some maybe even with a right- or bottom-divider |
| 493 | ;; prefix. | 494 | ;; prefix. |
| 494 | (define-key map [right-divider] map) | 495 | (define-key map [right-divider] map) |
diff --git a/lisp/xt-mouse.el b/lisp/xt-mouse.el index b87c1a28937..7f1e72260ae 100644 --- a/lisp/xt-mouse.el +++ b/lisp/xt-mouse.el | |||
| @@ -60,6 +60,7 @@ http://invisible-island.net/xterm/ctlseqs/ctlseqs.html)." | |||
| 60 | (ev-data (nth 1 event)) | 60 | (ev-data (nth 1 event)) |
| 61 | (ev-where (nth 1 ev-data)) | 61 | (ev-where (nth 1 ev-data)) |
| 62 | (vec (vector event)) | 62 | (vec (vector event)) |
| 63 | (is-move (eq 'mouse-movement ev-command)) | ||
| 63 | (is-down (string-match "down-" (symbol-name ev-command)))) | 64 | (is-down (string-match "down-" (symbol-name ev-command)))) |
| 64 | 65 | ||
| 65 | ;; Mouse events symbols must have an 'event-kind property with | 66 | ;; Mouse events symbols must have an 'event-kind property with |
| @@ -71,6 +72,7 @@ http://invisible-island.net/xterm/ctlseqs/ctlseqs.html)." | |||
| 71 | (is-down | 72 | (is-down |
| 72 | (setf (terminal-parameter nil 'xterm-mouse-last-down) event) | 73 | (setf (terminal-parameter nil 'xterm-mouse-last-down) event) |
| 73 | vec) | 74 | vec) |
| 75 | (is-move vec) | ||
| 74 | (t | 76 | (t |
| 75 | (let* ((down (terminal-parameter nil 'xterm-mouse-last-down)) | 77 | (let* ((down (terminal-parameter nil 'xterm-mouse-last-down)) |
| 76 | (down-data (nth 1 down)) | 78 | (down-data (nth 1 down)) |
| @@ -132,65 +134,89 @@ http://invisible-island.net/xterm/ctlseqs/ctlseqs.html)." | |||
| 132 | (fdiff (- f (* 1.0 maxwrap dbig)))) | 134 | (fdiff (- f (* 1.0 maxwrap dbig)))) |
| 133 | (+ (truncate fdiff) (* maxwrap dbig)))))) | 135 | (+ (truncate fdiff) (* maxwrap dbig)))))) |
| 134 | 136 | ||
| 135 | ;; Normal terminal mouse click reporting: expect three bytes, of the | 137 | (defun xterm-mouse--read-utf8-char (&optional prompt seconds) |
| 136 | ;; form <BUTTON+32> <X+32> <Y+32>. Return a list (EVENT-TYPE X Y). | 138 | "Read an utf-8 encoded character from the current terminal. |
| 137 | (defun xterm-mouse--read-event-sequence-1000 () | 139 | This function reads and returns an utf-8 encoded character of |
| 138 | (let* ((code (- (read-event) 32)) | 140 | command input. If the user generates an event which is not a |
| 139 | (type | 141 | character (i.e., a mouse click or function key event), read-char |
| 140 | ;; For buttons > 3, the release-event looks differently | 142 | signals an error. |
| 141 | ;; (see xc/programs/xterm/button.c, function EditorButton), | 143 | |
| 142 | ;; and come in a release-event only, no down-event. | 144 | The returned event may come directly from the user, or from a |
| 143 | (cond ((>= code 64) | 145 | keyboard macro. It is not decoded by the keyboard's input coding |
| 144 | (format "mouse-%d" (- code 60))) | 146 | system and always treated with an utf-8 input encoding. |
| 145 | ((memq code '(8 9 10)) | 147 | |
| 146 | (format "M-down-mouse-%d" (- code 7))) | 148 | The optional arguments PROMPT and SECONDS work like in |
| 147 | ((memq code '(3 11)) | 149 | `read-event'." |
| 148 | (let ((down (car (terminal-parameter | 150 | (let ((tmp (keyboard-coding-system))) |
| 149 | nil 'xterm-mouse-last-down)))) | 151 | (set-keyboard-coding-system 'utf-8) |
| 150 | (when (and down (string-match "[0-9]" (symbol-name down))) | 152 | (prog1 (read-event prompt t seconds) |
| 151 | (format (if (eq code 3) "mouse-%s" "M-mouse-%s") | 153 | (set-keyboard-coding-system tmp)))) |
| 152 | (match-string 0 (symbol-name down)))))) | 154 | |
| 153 | ((memq code '(0 1 2)) | 155 | ;; In default mode, each numeric parameter of XTerm's mouse report is |
| 154 | (format "down-mouse-%d" (+ 1 code))))) | 156 | ;; a single char, possibly encoded as utf-8. The actual numeric |
| 155 | (x (- (read-event) 33)) | 157 | ;; parameter then is obtained by subtracting 32 from the character |
| 156 | (y (- (read-event) 33))) | 158 | ;; code. In extendend mode the parameters are returned as decimal |
| 157 | (and type (wholenump x) (wholenump y) | 159 | ;; string delemited either by semicolons or for the last parameter by |
| 158 | (list (intern type) x y)))) | 160 | ;; one of the characters "m" or "M". If the last character is a "m", |
| 159 | 161 | ;; then the mouse event was a button release, else it was a button | |
| 160 | ;; XTerm's 1006-mode terminal mouse click reporting has the form | 162 | ;; press or a mouse motion. Return value is a cons cell with |
| 161 | ;; <BUTTON> ; <X> ; <Y> <M or m>, where the button and ordinates are | 163 | ;; (NEXT-NUMERIC-PARAMETER . LAST-CHAR) |
| 162 | ;; in encoded (decimal) form. Return a list (EVENT-TYPE X Y). | 164 | (defun xterm-mouse--read-number-from-terminal (extension) |
| 163 | (defun xterm-mouse--read-event-sequence-1006 () | 165 | (let (c) |
| 164 | (let (button-bytes x-bytes y-bytes c) | 166 | (if extension |
| 165 | (while (not (eq (setq c (read-event)) ?\;)) | 167 | (let ((n 0)) |
| 166 | (push c button-bytes)) | 168 | (while (progn |
| 167 | (while (not (eq (setq c (read-event)) ?\;)) | 169 | (setq c (read-char)) |
| 168 | (push c x-bytes)) | 170 | (<= ?0 c ?9)) |
| 169 | (while (not (memq (setq c (read-event)) '(?m ?M))) | 171 | (setq n (+ (* 10 n) c (- ?0)))) |
| 170 | (push c y-bytes)) | 172 | (cons n c)) |
| 171 | (list (let* ((code (string-to-number | 173 | (cons (- (setq c (read-utf8-char)) 32) c)))) |
| 172 | (apply 'string (nreverse button-bytes)))) | 174 | |
| 173 | (wheel (>= code 64)) | 175 | ;; XTerm reports mouse events as |
| 174 | (down (and (not wheel) | 176 | ;; <EVENT-CODE> <X> <Y> in default mode, and |
| 175 | (eq c ?M)))) | 177 | ;; <EVENT-CODE> ";" <X> ";" <Y> <"M" or "m"> in extended mode. |
| 176 | (intern (format "%s%smouse-%d" | 178 | ;; The macro read-number-from-terminal takes care of reading |
| 177 | (cond (wheel "") | 179 | ;; the response parameters appropriatly. The EVENT-CODE differs |
| 178 | ((< code 4) "") | 180 | ;; slightly between default and extended mode. |
| 179 | ((< code 8) "S-") | 181 | ;; Return a list (EVENT-TYPE-SYMBOL X Y). |
| 180 | ((< code 12) "M-") | 182 | (defun xterm-mouse--read-event-sequence (&optional extension) |
| 181 | ((< code 16) "M-S-") | 183 | (pcase-let* |
| 182 | ((< code 20) "C-") | 184 | ((`(,code . ,_) (xterm-mouse--read-number-from-terminal extension)) |
| 183 | ((< code 24) "C-S-") | 185 | (`(,x . ,_) (xterm-mouse--read-number-from-terminal extension)) |
| 184 | ((< code 28) "C-M-") | 186 | (`(,y . ,c) (xterm-mouse--read-number-from-terminal extension)) |
| 185 | ((< code 32) "C-M-S-") | 187 | (wheel (/= (logand code 64) 0)) |
| 186 | (t | 188 | (move (/= (logand code 32) 0)) |
| 187 | (error "Unexpected escape sequence from XTerm"))) | 189 | (ctrl (/= (logand code 16) 0)) |
| 188 | (if down "down-" "") | 190 | (meta (/= (logand code 8) 0)) |
| 189 | (if wheel | 191 | (shift (/= (logand code 4) 0)) |
| 190 | (- code 60) | 192 | (down (and (not wheel) |
| 191 | (1+ (mod code 4)))))) | 193 | (not move) |
| 192 | (1- (string-to-number (apply 'string (nreverse x-bytes)))) | 194 | (if extension |
| 193 | (1- (string-to-number (apply 'string (nreverse y-bytes))))))) | 195 | (eq c ?M) |
| 196 | (/= (logand code 3) 3)))) | ||
| 197 | (btn (cond | ||
| 198 | ((or extension down wheel) | ||
| 199 | (+ (logand code 3) (if wheel 4 1))) | ||
| 200 | ;; The default mouse protocol does not report the button | ||
| 201 | ;; number in release events: extract the button number | ||
| 202 | ;; from last button-down event. | ||
| 203 | ((terminal-parameter nil 'xterm-mouse-last-down) | ||
| 204 | (string-to-number | ||
| 205 | (substring | ||
| 206 | (symbol-name | ||
| 207 | (car (terminal-parameter nil 'xterm-mouse-last-down))) | ||
| 208 | -1))) | ||
| 209 | ;; Spurious release event without previous button-down | ||
| 210 | ;; event: assume, that the last button was button 1. | ||
| 211 | (t 1))) | ||
| 212 | (sym (if move 'mouse-movement | ||
| 213 | (intern (concat (if ctrl "C-" "") | ||
| 214 | (if meta "M-" "") | ||
| 215 | (if shift "S-" "") | ||
| 216 | (if down "down-" "") | ||
| 217 | "mouse-" | ||
| 218 | (number-to-string btn)))))) | ||
| 219 | (list sym (1- x) (1- y)))) | ||
| 194 | 220 | ||
| 195 | (defun xterm-mouse--set-click-count (event click-count) | 221 | (defun xterm-mouse--set-click-count (event click-count) |
| 196 | (setcdr (cdr event) (list click-count)) | 222 | (setcdr (cdr event) (list click-count)) |
| @@ -207,12 +233,10 @@ http://invisible-island.net/xterm/ctlseqs/ctlseqs.html)." | |||
| 207 | EXTENSION, if non-nil, means to use an extension to the usual | 233 | EXTENSION, if non-nil, means to use an extension to the usual |
| 208 | terminal mouse protocol; we currently support the value 1006, | 234 | terminal mouse protocol; we currently support the value 1006, |
| 209 | which is the \"1006\" extension implemented in Xterm >= 277." | 235 | which is the \"1006\" extension implemented in Xterm >= 277." |
| 210 | (let* ((click (cond ((null extension) | 236 | (let ((click (cond ((memq extension '(1006 nil)) |
| 211 | (xterm-mouse--read-event-sequence-1000)) | 237 | (xterm-mouse--read-event-sequence extension)) |
| 212 | ((eq extension 1006) | 238 | (t |
| 213 | (xterm-mouse--read-event-sequence-1006)) | 239 | (error "Unsupported XTerm mouse protocol"))))) |
| 214 | (t | ||
| 215 | (error "Unsupported XTerm mouse protocol"))))) | ||
| 216 | (when click | 240 | (when click |
| 217 | (let* ((type (nth 0 click)) | 241 | (let* ((type (nth 0 click)) |
| 218 | (x (nth 1 click)) | 242 | (x (nth 1 click)) |
| @@ -291,13 +315,36 @@ down the SHIFT key while pressing the mouse button." | |||
| 291 | (setq mouse-position-function nil))) | 315 | (setq mouse-position-function nil))) |
| 292 | 316 | ||
| 293 | (defconst xterm-mouse-tracking-enable-sequence | 317 | (defconst xterm-mouse-tracking-enable-sequence |
| 294 | "\e[?1000h\e[?1006h" | 318 | "\e[?1000h\e[?1002h\e[?1005h\e[?1006h" |
| 295 | "Control sequence to enable xterm mouse tracking. | 319 | "Control sequence to enable xterm mouse tracking. |
| 296 | Enables basic tracking, then extended tracking on | 320 | Enables basic mouse tracking, mouse motion events and finally |
| 297 | terminals that support it.") | 321 | extended tracking on terminals that support it. The following |
| 322 | escape sequences are understood by modern xterms: | ||
| 323 | |||
| 324 | \"\\e[?1000h\" `Basic mouse mode´: Enables reports for mouse | ||
| 325 | clicks. There is a limit to the maximum row/column | ||
| 326 | position (<= 223), which can be reported in this | ||
| 327 | basic mode. | ||
| 328 | |||
| 329 | \"\\e[?1002h\" `Mouse motion mode´: Enables reports for mouse | ||
| 330 | motion events during dragging operations. | ||
| 331 | |||
| 332 | \"\\e[?1005h\" `UTF-8 coordinate extension`: Enables an extension | ||
| 333 | to the basic mouse mode, which uses UTF-8 | ||
| 334 | characters to overcome the 223 row/column limit. This | ||
| 335 | extension may conflict with non UTF-8 applications or | ||
| 336 | non UTF-8 locales. | ||
| 337 | |||
| 338 | \"\\e[?1006h\" `SGR coordinate extension´: Enables a newer | ||
| 339 | alternative extension to the basic mouse mode, which | ||
| 340 | overcomes the 223 row/column limit without the | ||
| 341 | drawbacks of the UTF-8 coordinate extension. | ||
| 342 | |||
| 343 | The two extension modes are mutually exclusive, where the last | ||
| 344 | given escape sequence takes precedence over the former.") | ||
| 298 | 345 | ||
| 299 | (defconst xterm-mouse-tracking-disable-sequence | 346 | (defconst xterm-mouse-tracking-disable-sequence |
| 300 | "\e[?1006l\e[?1000l" | 347 | "\e[?1006l\e[?1005l\e[?1002l\e[?1000l" |
| 301 | "Reset the modes set by `xterm-mouse-tracking-enable-sequence'.") | 348 | "Reset the modes set by `xterm-mouse-tracking-enable-sequence'.") |
| 302 | 349 | ||
| 303 | (defun turn-on-xterm-mouse-tracking-on-terminal (&optional terminal) | 350 | (defun turn-on-xterm-mouse-tracking-on-terminal (&optional terminal) |