aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPo Lu2023-07-16 15:30:01 +0800
committerPo Lu2023-07-16 15:30:01 +0800
commit7b346b92b4c30c634d094e6162b65a22a52b93bb (patch)
treeb6a81b1e8b27c007205280750ff6ebbcf9ac7209
parentd78d7aa78391c84e3d5536514d245d844c08d43d (diff)
downloademacs-7b346b92b4c30c634d094e6162b65a22a52b93bb.tar.gz
emacs-7b346b92b4c30c634d094e6162b65a22a52b93bb.zip
Improve touch-screen support
* doc/emacs/emacs.texi (Top): * doc/emacs/input.texi (Other Input Devices): Correctly capitalize subsection name. (Touchscreens): Document additional translation. * doc/lispref/commands.texi (Touchscreen Events): Document that `touchscreen-end' events now have prefix keys. Also, describe mouse emulation and `touchscreen-scroll' events. * doc/lispref/keymaps.texi (Translation Keymaps): Document `current-key-remap-sequence'. * lisp/touch-screen.el (touch-screen-translate-prompt): New function. (touch-screen-scroll): New command. Bind to `touchscreen-scroll'. (touch-screen-handle-point-update, touch-screen-handle-point-up) (touch-screen-handle-touch): Refactor to actually translate touch screen event sequences, as opposed to looking up commands and executing them. (touch-screen-translate-touch): New function. Bind in function-key-map to all touch screen events. (touch-screen-drag-mode-line-1, touch-screen-drag-mode-line) (touch-screen-tap-header-line): Remove special commands for dragging the mode line and clicking on the header line. * lisp/wid-edit.el (widget-button-click): Adjust accordingly. * src/keyboard.c (access_keymap_keyremap): Bind `current-key-remap-sequence' to the key sequence being remapped. (keyremap_step): Give fkey->start and fkey->end to access_keymap_keyremap. (head_table): Add imaginary prefix to touchscreen-end events as well. (syms_of_keyboard): New variable Vcurrent_key_remap_sequence.
-rw-r--r--doc/emacs/emacs.texi2
-rw-r--r--doc/emacs/input.texi7
-rw-r--r--doc/lispref/commands.texi68
-rw-r--r--doc/lispref/keymaps.texi9
-rw-r--r--lisp/touch-screen.el657
-rw-r--r--lisp/wid-edit.el8
-rw-r--r--src/keyboard.c39
7 files changed, 518 insertions, 272 deletions
diff --git a/doc/emacs/emacs.texi b/doc/emacs/emacs.texi
index 92be9f9b9a9..b255e679d5f 100644
--- a/doc/emacs/emacs.texi
+++ b/doc/emacs/emacs.texi
@@ -1273,7 +1273,7 @@ Emacs and Android
1273* Android Troubleshooting:: Dealing with problems. 1273* Android Troubleshooting:: Dealing with problems.
1274* Android Software:: Getting extra software. 1274* Android Software:: Getting extra software.
1275 1275
1276Emacs and unconventional input devices 1276Emacs and Unconventional Input Devices
1277 1277
1278* Touchscreens:: Using Emacs on touchscreens. 1278* Touchscreens:: Using Emacs on touchscreens.
1279* On-Screen Keyboards:: Using Emacs with virtual keyboards. 1279* On-Screen Keyboards:: Using Emacs with virtual keyboards.
diff --git a/doc/emacs/input.texi b/doc/emacs/input.texi
index 0df3162ce97..66554653def 100644
--- a/doc/emacs/input.texi
+++ b/doc/emacs/input.texi
@@ -2,7 +2,7 @@
2@c Copyright (C) 2023 Free Software Foundation, Inc. 2@c Copyright (C) 2023 Free Software Foundation, Inc.
3@c See file emacs.texi for copying conditions. 3@c See file emacs.texi for copying conditions.
4@node Other Input Devices 4@node Other Input Devices
5@appendix Emacs and unconventional input devices 5@appendix Emacs and Unconventional Input Devices
6@cindex other input devices 6@cindex other input devices
7 7
8 Emacs was originally developed with the assumption that its users 8 Emacs was originally developed with the assumption that its users
@@ -21,7 +21,7 @@ which is detailed here.
21 21
22@node Touchscreens 22@node Touchscreens
23@section Using Emacs on touchscreens 23@section Using Emacs on touchscreens
24@cindex touchscreens 24@cindex touchscreen input
25 25
26 Touchscreen input works by pressing and moving tools (which include 26 Touchscreen input works by pressing and moving tools (which include
27fingers and some pointing devices--styluses, for example) onto a frame 27fingers and some pointing devices--styluses, for example) onto a frame
@@ -40,6 +40,9 @@ executing any command bound to @code{mouse-1} at that location in the
40window. If the tap happened on top of a link (@pxref{Mouse 40window. If the tap happened on top of a link (@pxref{Mouse
41References}), then Emacs will follow the link instead. 41References}), then Emacs will follow the link instead.
42 42
43 If a command bound to @code{down-mouse-1} is bound to the location
44where the tap took place, Emacs will execute that command as well.
45
43@item 46@item
44@cindex scrolling, touchscreens 47@cindex scrolling, touchscreens
45 ``Scrolling'', meaning to place a tool on the display and move it up 48 ``Scrolling'', meaning to place a tool on the display and move it up
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index 7a076406bed..725ca900165 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -2013,10 +2013,7 @@ finger against the touchscreen.
2013 2013
2014These events also have imaginary prefixes keys added by 2014These events also have imaginary prefixes keys added by
2015@code{read-key-sequence} when they originate on top of a special part 2015@code{read-key-sequence} when they originate on top of a special part
2016of a frame or window. @xref{Key Sequence Input}. The reason the 2016of a frame or window. @xref{Key Sequence Input}.
2017other touch screen events do not undergo this treatment is that they
2018are rarely useful without being used in tandem from their
2019corresponding @code{touchscreen-begin} events.
2020 2017
2021@cindex @code{touchscreen-update} event 2018@cindex @code{touchscreen-update} event
2022@item (touchscreen-update @var{points}) 2019@item (touchscreen-update @var{points})
@@ -2029,12 +2026,73 @@ up-to-date positions of each touch point currently on the touchscreen.
2029This event is sent when @var{point} is no longer present on the 2026This event is sent when @var{point} is no longer present on the
2030display, because another program took the grab, or because the user 2027display, because another program took the grab, or because the user
2031raised the finger from the touchscreen. 2028raised the finger from the touchscreen.
2029
2030These events also have imaginary prefixes keys added by
2031@code{read-key-sequence} when they originate on top of a special part
2032of a frame or window.
2032@end table 2033@end table
2033 2034
2034If a touchpoint is pressed against the menu bar, then Emacs will not 2035If a touchpoint is pressed against the menu bar, then Emacs will not
2035generate any corresponding @code{touchscreen-begin} or 2036generate any corresponding @code{touchscreen-begin} or
2036@code{touchscreen-end} events; instead, the menu bar may be displayed 2037@code{touchscreen-end} events; instead, the menu bar may be displayed
2037when @code{touchscreen-end} should have been delivered. 2038after @code{touchscreen-end} would have been delivered under other
2039circumstances.
2040
2041@cindex mouse emulation from touch screen events
2042When no command is bound to @code{touchscreen-begin},
2043@code{touchscreen-end} or @code{touchscreen-update}, Emacs calls a
2044``key translation function'' (@pxref{Translation Keymaps}) to
2045translate key sequences containing touch screen events into ordinary
2046mouse events (@pxref{Mouse Events}.) Since Emacs doesn't support
2047distinguishing events originating from separate mouse devices, it
2048assumes that only one touchpoint is active while translation takes
2049place; breaking this assumption may lead to unexpected behavior.
2050
2051Emacs applies two different strategies for translating touch events
2052into mouse events, contingent on factors such as the commands bound to
2053keymaps that are active at the location of the
2054@code{touchscreen-begin} event. If a command is bound to
2055@code{down-mouse-1} at that location, the initial translation consists
2056of a single @code{down-mouse-1} event, with subsequent
2057@code{touchscreen-update} events translated to mouse motion events
2058(@pxref{Motion Events}), and a final @code{touchscreen-end} event
2059translated to a @code{mouse-1} or @code{drag-mouse-1} event. This is
2060referred to ``simple translation'', and produces a simple
2061correspondence between touchpoint motion and mouse motion.
2062
2063@cindex @code{ignored-mouse-command}, a symbol property
2064However, some commands bound to
2065@code{down-mouse-1}--@code{mouse-drag-region}, for example--either
2066conflict with defined touch screen gestures (such as ``long-press to
2067drag''), or with user expectations for touch input, and shouldn't
2068subject the touch sequence to simple translation. If a command whose
2069name contains the property @code{ignored-mouse-command} is encountered
2070or there is no command bound to @code{down-mouse-1}, a more irregular
2071form of translation takes place: here, Emacs processes touch screen
2072gestures (@pxref{Touchscreens,,, emacs, The GNU Emacs Manual}) first,
2073and finally attempts to translate touch screen events into mouse
2074events if no gesture was detected prior to a closing
2075@code{touchscreen-end} event and a command is bound to @code{mouse-1}
2076at the location of that event. Before generating the @code{mouse-1}
2077event, point is also set to the location of the @code{touchscreen-end}
2078event, and the window containing the position of that event is
2079selected, as a compromise for packages which assume
2080@code{mouse-drag-region} has already set point to the location of any
2081mouse click and selected the window where it took place.
2082
2083@cindex @code{touchscreen-scroll} event
2084If a ``scrolling'' gesture is detected during the translation process,
2085each subsequent @code{touchscreen-update} event is translated to a
2086@code{touchscreen-scroll} event of the form:
2087
2088@example
2089@w{@code{(touchscreen-scroll @var{window} @var{dx} @var{dy})}}
2090@end example
2091
2092where @var{dx} and @var{dy} specify, in pixels, the relative motion of
2093the tool from the position of the @code{touchscreen-begin} event that
2094started the sequence or the last @code{touchscreen-scroll} event,
2095whichever came later.
2038 2096
2039@cindex handling touch screen events 2097@cindex handling touch screen events
2040@cindex tap and drag, touch screen gestures 2098@cindex tap and drag, touch screen gestures
diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi
index 05dc17eb03f..e41dbf9def8 100644
--- a/doc/lispref/keymaps.texi
+++ b/doc/lispref/keymaps.texi
@@ -2044,6 +2044,15 @@ to turn the character that follows into a Hyper character:
2044@end group 2044@end group
2045@end example 2045@end example
2046 2046
2047@cindex accessing events within a key translation function
2048@vindex current-key-remap-sequence
2049A key translation function might want to adjust its behavior based on
2050parameters to events within a key sequence containing non-key events
2051(@pxref{Input Events}.) This information is available from the
2052variable @code{current-key-remap-sequence}, which is bound to the key
2053sub-sequence being translated around calls to key translation
2054functions.
2055
2047@subsection Interaction with normal keymaps 2056@subsection Interaction with normal keymaps
2048 2057
2049The end of a key sequence is detected when that key sequence either is bound 2058The end of a key sequence is detected when that key sequence either is bound
diff --git a/lisp/touch-screen.el b/lisp/touch-screen.el
index 242ea4fcd9b..0f584269931 100644
--- a/lisp/touch-screen.el
+++ b/lisp/touch-screen.el
@@ -49,6 +49,11 @@ keyboard after a mouse command is executed in response to a
49 "Timer used to track long-presses. 49 "Timer used to track long-presses.
50This is always cleared upon any significant state change.") 50This is always cleared upon any significant state change.")
51 51
52(defvar touch-screen-translate-prompt nil
53 "Prompt given to the touch screen translation function.
54If non-nil, the touch screen key event translation machinery
55is being called from `read-sequence' or some similar function.")
56
52(defcustom touch-screen-display-keyboard nil 57(defcustom touch-screen-display-keyboard nil
53 "If non-nil, always display the on screen keyboard. 58 "If non-nil, always display the on screen keyboard.
54A buffer local value means to always display the on screen 59A buffer local value means to always display the on screen
@@ -70,6 +75,14 @@ See `pixel-scroll-precision-mode' for more details."
70 :group 'mouse 75 :group 'mouse
71 :version "30.1") 76 :version "30.1")
72 77
78
79
80;; Touch screen event translation. The code here translates raw touch
81;; screen events into `touchscreen-scroll' events and mouse events in
82;; a ``DWIM'' fashion, consulting the keymaps at the position of the
83;; mouse event to determine the best course of action, while also
84;; recognizing drag-to-select and other gestures.
85
73(defun touch-screen-relative-xy (posn window) 86(defun touch-screen-relative-xy (posn window)
74 "Return the coordinates of POSN, a mouse position list. 87 "Return the coordinates of POSN, a mouse position list.
75However, return the coordinates relative to WINDOW. 88However, return the coordinates relative to WINDOW.
@@ -201,6 +214,26 @@ horizontal scrolling according to the movement in DX."
201 (setcar (nthcdr 8 touch-screen-current-tool) lines-hscrolled) 214 (setcar (nthcdr 8 touch-screen-current-tool) lines-hscrolled)
202 nil))))) 215 nil)))))
203 216
217(defun touch-screen-scroll (event)
218 "Scroll the window within EVENT, a `touchscreen-scroll' event.
219If `touch-screen-precision-scroll', scroll the window vertically
220by the number of pixels specified within that event. Else,
221scroll the window by one line for every
222`window-default-line-height' pixels worth of movement.
223
224If EVENT also specifies horizontal motion and no significant
225amount of vertical scrolling has taken place, also scroll the
226window horizontally in conjunction with the number of pixels in
227the event."
228 (interactive "e")
229 (let ((window (nth 1 event))
230 (dx (nth 2 event))
231 (dy (nth 3 event)))
232 (with-selected-window window
233 (touch-screen-handle-scroll dx dy))))
234
235(global-set-key [touchscreen-scroll] #'touch-screen-scroll)
236
204(defun touch-screen-handle-timeout (arg) 237(defun touch-screen-handle-timeout (arg)
205 "Start the touch screen timeout or handle it depending on ARG. 238 "Start the touch screen timeout or handle it depending on ARG.
206When ARG is nil, start the `touch-screen-current-timer' to go off 239When ARG is nil, start the `touch-screen-current-timer' to go off
@@ -236,19 +269,30 @@ known position of the tool."
236 269
237(defun touch-screen-handle-point-update (point) 270(defun touch-screen-handle-point-update (point)
238 "Notice that the touch point POINT has changed position. 271 "Notice that the touch point POINT has changed position.
272Perform the editing operations or throw to the input translation
273function with an input event tied to any gesture that is
274recognized.
275
239POINT must be the touch point currently being tracked as 276POINT must be the touch point currently being tracked as
240`touch-screen-current-tool'. 277`touch-screen-current-tool'.
241 278
242If the fourth element of `touch-screen-current-tool' is nil, then 279If the fourth element of `touch-screen-current-tool' is nil, then
243the touch has just begun. Determine how much POINT has moved. 280the touch has just begun. Determine how much POINT has moved.
244If POINT has moved upwards or downwards by a significant amount, 281If POINT has moved upwards or downwards by a significant amount,
245then set the fourth element to `scroll'. Then, call 282then set the fourth element to `scroll'. Then, generate a
246`touch-screen-handle-scroll' to scroll the display by that 283`touchscreen-scroll' event with the window that POINT was
247amount. 284initially placed upon, and pixel deltas describing how much point
285has moved relative to its previous position in the X and Y axes.
286
287If the fourth element of `touchscreen-current-tool' is `scroll',
288then generate a `touchscreen-scroll' event with the window that
289qPOINT was initially placed upon, and pixel deltas describing how
290much point has moved relative to its previous position in the X
291and Y axes.
248 292
249If the fourth element of `touch-screen-current-tool' is `scroll', 293If the fourth element of `touch-screen-current-tool' is
250then scroll the display by how much POINT has moved in the Y 294`mouse-drag' and `track-mouse' is non-nil, then generate a
251axis. 295`mouse-movement' event with the position of POINT.
252 296
253If the fourth element of `touch-screen-current-tool' is `held', 297If the fourth element of `touch-screen-current-tool' is `held',
254then the touch has been held down for some time. If motion 298then the touch has been held down for some time. If motion
@@ -275,8 +319,11 @@ then move point to the position of POINT."
275 'scroll) 319 'scroll)
276 (setcar (nthcdr 2 touch-screen-current-tool) 320 (setcar (nthcdr 2 touch-screen-current-tool)
277 relative-xy) 321 relative-xy)
278 (with-selected-window window 322 ;; Generate a `touchscreen-scroll' event with `diff-x'
279 (touch-screen-handle-scroll diff-x diff-y)) 323 ;; and `diff-y'.
324 (throw 'input-event
325 (list 'touchscreen-scroll
326 window diff-x diff-y))
280 ;; Cancel the touch screen long-press timer, if it is 327 ;; Cancel the touch screen long-press timer, if it is
281 ;; still there by any chance. 328 ;; still there by any chance.
282 (when touch-screen-current-timer 329 (when touch-screen-current-timer
@@ -301,8 +348,18 @@ then move point to the position of POINT."
301 (setcar (nthcdr 2 touch-screen-current-tool) 348 (setcar (nthcdr 2 touch-screen-current-tool)
302 relative-xy) 349 relative-xy)
303 (unless (and (zerop diff-x) (zerop diff-y)) 350 (unless (and (zerop diff-x) (zerop diff-y))
304 (with-selected-window window 351 (throw 'input-event
305 (touch-screen-handle-scroll diff-x diff-y))))) 352 ;; Generate a `touchscreen-scroll' event with
353 ;; `diff-x' and `diff-y'.
354 (list 'touchscreen-scroll
355 window diff-x diff-y)))))
356 ((eq what 'mouse-drag)
357 ;; There was a `down-mouse-1' event bound at the starting
358 ;; point of the event. Generate a mouse-motion event if
359 ;; mouse movement is being tracked.
360 (when track-mouse
361 (throw 'input-event (list 'mouse-movement
362 (cdr point)))))
306 ((eq what 'held) 363 ((eq what 'held)
307 (let* ((posn (cdr point)) 364 (let* ((posn (cdr point))
308 (relative-xy 365 (relative-xy
@@ -319,7 +376,6 @@ then move point to the position of POINT."
319 ;; Activate the mark. It should have been set by the 376 ;; Activate the mark. It should have been set by the
320 ;; time `touch-screen-timeout' was called. 377 ;; time `touch-screen-timeout' was called.
321 (activate-mark) 378 (activate-mark)
322
323 ;; Figure out what character to go to. If this posn is 379 ;; Figure out what character to go to. If this posn is
324 ;; in the window, go to (posn-point posn). If not, 380 ;; in the window, go to (posn-point posn). If not,
325 ;; then go to the line before either window start or 381 ;; then go to the line before either window start or
@@ -385,127 +441,357 @@ in response to the minibuffer being closed."
385 (cancel-timer minibuffer-on-screen-keyboard-timer) 441 (cancel-timer minibuffer-on-screen-keyboard-timer)
386 (setq minibuffer-on-screen-keyboard-timer nil))))) 442 (setq minibuffer-on-screen-keyboard-timer nil)))))
387 443
388(defun touch-screen-handle-point-up (point) 444(defun touch-screen-handle-point-up (point prefix)
389 "Notice that POINT has been removed from the screen. 445 "Notice that POINT has been removed from the screen.
390POINT should be the point currently tracked as 446POINT should be the point currently tracked as
391`touch-screen-current-tool'. 447`touch-screen-current-tool'.
448PREFIX should be a virtual function key used to look up key
449bindings.
450
451If the fourth element of `touch-screen-current-tool' is nil, move
452point to the position of POINT, selecting the window under POINT
453as well, and deactivate the mark; if there is a button or link at
454POINT, call the command bound to `mouse-2' there. Otherwise,
455call the command bound to `mouse-1'.
392 456
393If the fourth argument of `touch-screen-current-tool' is nil, 457If the fourth element of `touch-screen-current-tool' is
394move point to the position of POINT, selecting the window under 458`mouse-drag', then generate either a `mouse-1' or a
395POINT as well, and deactivate the mark; if there is a button or 459`drag-mouse-1' event depending on how far the position of POINT
396link at POINT, call the command bound to `mouse-2' there. 460is from the starting point of the touch.
397Otherwise, call the command bound to `mouse-1'.
398 461
399If the command being executed is listed in 462If the command being executed is listed in
400`touch-screen-set-point-commands' also display the on-screen 463`touch-screen-set-point-commands' also display the on-screen
401keyboard if the current buffer and the character at the new point 464keyboard if the current buffer and the character at the new point
402is not read-only." 465is not read-only."
403 (let ((what (nth 3 touch-screen-current-tool))) 466 (let ((what (nth 3 touch-screen-current-tool))
467 (posn (cdr point)) window point)
404 (cond ((null what) 468 (cond ((null what)
405 (when (windowp (posn-window (cdr point))) 469 (when (windowp (posn-window posn))
470 (setq point (posn-point point)
471 window (posn-window posn))
406 ;; Select the window that was tapped. 472 ;; Select the window that was tapped.
407 (select-window (posn-window (cdr point))) 473 (select-window window)
408 ;; Now simulate a mouse click there. If there is a link 474 ;; Now simulate a mouse click there. If there is a link
409 ;; or a button, use mouse-2 to push it. 475 ;; or a button, use mouse-2 to push it.
410 (let ((event (list (if (or (mouse-on-link-p (cdr point)) 476 (let* ((event (list (if (or (mouse-on-link-p posn)
411 (button-at (posn-point (cdr point)))) 477 (and point (button-at point)))
412 'mouse-2 478 'mouse-2
413 'mouse-1) 479 'mouse-1)
414 (cdr point))) 480 posn))
415 ;; Look for an extra keymap to look in. 481 ;; Look for the command bound to this event.
416 (keymap (and (posn-object (cdr point)) 482 (command (key-binding (if prefix
417 (stringp 483 (vector prefix
418 (posn-object (cdr point))) 484 (car event))
419 (get-text-property 485 (vector (car event)))
420 0 'keymap 486 t nil posn)))
421 (posn-object (cdr point)))))
422 command)
423 (save-excursion
424 (when (posn-point (cdr point))
425 (goto-char (posn-point (cdr point))))
426 (if keymap
427 (setq keymap (cons keymap (current-active-maps t)))
428 (setq keymap (current-active-maps t)))
429 (setq command (lookup-key keymap (vector (car event)))))
430 (deactivate-mark) 487 (deactivate-mark)
431 ;; This is necessary for following links. 488 (when point
432 (goto-char (posn-point (cdr point))) 489 ;; This is necessary for following links.
490 (goto-char point))
433 ;; Figure out if the on screen keyboard needs to be 491 ;; Figure out if the on screen keyboard needs to be
434 ;; displayed. 492 ;; displayed.
435 (when command 493 (when command
436 (call-interactively command nil 494 (if (memq command touch-screen-set-point-commands)
437 (vector event)) 495 (if touch-screen-translate-prompt
438 (when (memq command touch-screen-set-point-commands) 496 ;; When a `mouse-set-point' command is
439 (if (and (or (not buffer-read-only) 497 ;; encountered and
440 touch-screen-display-keyboard) 498 ;; `touch-screen-handle-touch' is being
441 ;; Detect the splash screen and avoid 499 ;; called from the keyboard command loop,
442 ;; displaying the on screen keyboard 500 ;; call it immediately so that point is set
443 ;; there. 501 ;; prior to the on screen keyboard being
444 (not (equal (buffer-name) "*GNU Emacs*"))) 502 ;; displayed.
445 ;; Once the on-screen keyboard has been opened, 503 (call-interactively command nil
446 ;; add `touch-screen-window-selection-changed' 504 (vector event))
447 ;; as a window selection change function This 505 (if (and (or (not buffer-read-only)
448 ;; allows the on screen keyboard to be hidden 506 touch-screen-display-keyboard)
449 ;; if the selected window's point becomes read 507 ;; Detect the splash screen and avoid
450 ;; only at some point in the future. 508 ;; displaying the on screen keyboard
451 (progn 509 ;; there.
452 (add-hook 'window-selection-change-functions 510 (not (equal (buffer-name) "*GNU Emacs*")))
453 #'touch-screen-window-selection-changed) 511 ;; Once the on-screen keyboard has been
454 (frame-toggle-on-screen-keyboard (selected-frame) nil)) 512 ;; opened, add
455 ;; Otherwise, hide the on screen keyboard now. 513 ;; `touch-screen-window-selection-changed'
456 (frame-toggle-on-screen-keyboard (selected-frame) t)))))))))) 514 ;; as a window selection change function
457 515 ;; This allows the on screen keyboard to be
458(defun touch-screen-handle-touch (event) 516 ;; hidden if the selected window's point
517 ;; becomes read only at some point in the
518 ;; future.
519 (progn
520 (add-hook 'window-selection-change-functions
521 #'touch-screen-window-selection-changed)
522 (frame-toggle-on-screen-keyboard (selected-frame)
523 nil))
524 ;; Otherwise, hide the on screen keyboard
525 ;; now.
526 (frame-toggle-on-screen-keyboard (selected-frame) t))
527 ;; But if it's being called from `describe-key'
528 ;; or some such, return it as a key sequence.
529 (throw 'input-event event)))
530 ;; If not, return the event.
531 (throw 'input-event event)))))
532 ((eq what 'mouse-drag)
533 ;; Generate a corresponding `mouse-1' event.
534 (let* ((new-window (posn-window posn))
535 (new-point (posn-point posn))
536 (old-posn (nth 4 touch-screen-current-tool))
537 (old-window (posn-window posn))
538 (old-point (posn-point posn)))
539 (throw 'input-event
540 ;; If the position of the touch point hasn't
541 ;; changed, or it doesn't start or end on a
542 ;; window...
543 (if (and (eq new-window old-window)
544 (eq new-point old-point)
545 (windowp new-window)
546 (windowp old-window))
547 ;; ... generate a mouse-1 event...
548 (list 'mouse-1 posn)
549 ;; ... otherwise, generate a drag-mouse-1 event.
550 (list 'drag-mouse-1 (cons old-window
551 old-posn)
552 (cons new-window posn)))))))))
553
554(defun touch-screen-handle-touch (event prefix &optional interactive)
459 "Handle a single touch EVENT, and perform associated actions. 555 "Handle a single touch EVENT, and perform associated actions.
460EVENT can either be a touchscreen-begin, touchscreen-update or 556EVENT can either be a `touchscreen-begin', `touchscreen-update' or
461touchscreen-end event." 557`touchscreen-end' event.
462 (interactive "e") 558PREFIX is either nil, or a symbol specifying a virtual function
463 (cond 559key to apply to EVENT.
464 ((eq (car event) 'touchscreen-begin) 560
465 ;; A tool was just pressed against the screen. Figure out the 561If INTERACTIVE, execute the command associated with any event
466 ;; window where it is and make it the tool being tracked on the 562generated instead of throwing `input-event'. Otherwise, throw
467 ;; window. 563`input-event' with a single input event if that event should take
468 (let ((touchpoint (caadr event)) 564the place of EVENT within the key sequence being translated, or
469 (position (cdadr event))) 565`nil' if all tools have been released."
470 ;; Cancel the touch screen timer, if it is still there by any 566 (interactive "e\ni\np")
471 ;; chance. 567 (if interactive
472 (when touch-screen-current-timer 568 ;; Called interactively (probably from wid-edit.el.)
473 (cancel-timer touch-screen-current-timer) 569 ;; Add any event generated to `unread-command-events'.
474 (setq touch-screen-current-timer nil)) 570 (let ((event (catch 'input-event
475 ;; Replace any previously ongoing gesture. If POSITION has no 571 (touch-screen-handle-touch event prefix) nil)))
476 ;; window or position, make it nil instead. 572 (when event
477 (setq touch-screen-current-tool (and (windowp (posn-window position)) 573 (setq unread-command-events
478 (posn-point position) 574 (nconc unread-command-events
479 (list touchpoint 575 (list event)))))
480 (posn-window position) 576 (cond
481 (posn-x-y position) 577 ((eq (car event) 'touchscreen-begin)
482 nil position nil nil 578 ;; A tool was just pressed against the screen. Figure out the
483 nil nil))) 579 ;; window where it is and make it the tool being tracked on the
484 ;; Start the long-press timer. 580 ;; window.
485 (touch-screen-handle-timeout nil))) 581 (let* ((touchpoint (caadr event))
486 ((eq (car event) 'touchscreen-update) 582 (position (cdadr event))
487 ;; The positions of tools currently pressed against the screen 583 (window (posn-window position))
488 ;; have changed. If there is a tool being tracked as part of a 584 (point (posn-point position)))
489 ;; gesture, look it up in the list of tools. 585 ;; Cancel the touch screen timer, if it is still there by any
490 (let ((new-point (assq (car touch-screen-current-tool) 586 ;; chance.
491 (cadr event)))) 587 (when touch-screen-current-timer
492 (when new-point 588 (cancel-timer touch-screen-current-timer)
493 (touch-screen-handle-point-update new-point)))) 589 (setq touch-screen-current-timer nil))
494 ((eq (car event) 'touchscreen-end) 590 ;; Replace any previously ongoing gesture. If POSITION has no
495 ;; A tool has been removed from the screen. If it is the tool 591 ;; window or position, make it nil instead.
496 ;; currently being tracked, clear `touch-screen-current-tool'. 592 (setq touch-screen-current-tool (and (windowp window)
497 (when (eq (caadr event) (car touch-screen-current-tool)) 593 (list touchpoint window
498 ;; Cancel the touch screen long-press timer, if it is still there 594 (posn-x-y position)
499 ;; by any chance. 595 nil position
500 (when touch-screen-current-timer 596 nil nil nil nil)))
501 (cancel-timer touch-screen-current-timer) 597 ;; Determine if there is a command bound to `down-mouse-1' at
502 (setq touch-screen-current-timer nil)) 598 ;; the position of the tap and that command is not a command
503 (touch-screen-handle-point-up (cadr event)) 599 ;; whose functionality is replaced by the long-press mechanism.
504 (setq touch-screen-current-tool nil))))) 600 ;; If so, set the fourth element of `touch-screen-current-tool'
505 601 ;; to `mouse-drag' and generate an emulated `mouse-1' event.
506(define-key global-map [touchscreen-begin] #'touch-screen-handle-touch) 602 (if (and touch-screen-current-tool
507(define-key global-map [touchscreen-update] #'touch-screen-handle-touch) 603 (with-selected-window window
508(define-key global-map [touchscreen-end] #'touch-screen-handle-touch) 604 (let ((binding (key-binding (if prefix
605 (vector prefix
606 'down-mouse-1)
607 [down-mouse-1])
608 t nil position)))
609 (and binding
610 (not (and (symbolp binding)
611 (get binding 'ignored-mouse-command)))))))
612 (progn (setcar (nthcdr 3 touch-screen-current-tool)
613 'mouse-drag)
614 (throw 'input-event (list 'down-mouse-1 position)))
615 (and point
616 ;; Start the long-press timer.
617 (touch-screen-handle-timeout nil)))))
618 ((eq (car event) 'touchscreen-update)
619 ;; The positions of tools currently pressed against the screen
620 ;; have changed. If there is a tool being tracked as part of a
621 ;; gesture, look it up in the list of tools.
622 (let ((new-point (assq (car touch-screen-current-tool)
623 (cadr event))))
624 (when new-point
625 (touch-screen-handle-point-update new-point))))
626 ((eq (car event) 'touchscreen-end)
627 ;; A tool has been removed from the screen. If it is the tool
628 ;; currently being tracked, clear `touch-screen-current-tool'.
629 (when (eq (caadr event) (car touch-screen-current-tool))
630 ;; Cancel the touch screen long-press timer, if it is still there
631 ;; by any chance.
632 (when touch-screen-current-timer
633 (cancel-timer touch-screen-current-timer)
634 (setq touch-screen-current-timer nil))
635 (unwind-protect
636 (touch-screen-handle-point-up (cadr event) prefix)
637 ;; Make sure the tool list is cleared even if
638 ;; `touch-screen-handle-point-up' throws.
639 (setq touch-screen-current-tool nil)))
640 ;; Throw to the key translation function.
641 (throw 'input-event nil)))))
642
643;; Mark `mouse-drag-region' as ignored for the purposes of mouse click
644;; emulation.
645
646(put 'mouse-drag-region 'ignored-mouse-command t)
647
648(defun touch-screen-translate-touch (prompt)
649 "Translate touch screen events into a sequence of mouse events.
650PROMPT is the prompt string given to `read-key-sequence', or nil
651if this function is being called from the keyboard command loop.
652Value is a new key sequence.
653
654Read the touch screen event within `current-key-remap-sequence'
655and give it to `touch-screen-handle-touch'. Return any key
656sequence signaled.
657
658If `touch-screen-handle-touch' does not signal for an event to be
659returned after the last element of the key sequence is read,
660continue reading touch screen events until
661`touch-screen-handle-touch' signals. Return a sequence
662consisting of the first event encountered that is not a touch
663screen event.
664
665In addition to non-touchscreen events read, key sequences
666returned may contain any one of the following events:
667
668 (touchscreen-scroll WINDOW DX DY)
669
670where WINDOW specifies a window to scroll, and DX and DY are
671integers describing how many pixels to be scrolled horizontally
672and vertically.
673
674 (down-mouse-1 POSN)
675 (drag-mouse-1 POSN)
676
677where POSN is the position of the mouse button press or click.
678
679 (mouse-1 POSN)
680 (mouse-2 POSN)
681
682where POSN is the position of the mouse click, either `mouse-2'
683if POSN is on a link or a button, or `mouse-1' otherwise."
684 (if (> (length current-key-remap-sequence) 0)
685 ;; Save the virtual function key if this is a mode line event.
686 (let* ((prefix (and (> (length current-key-remap-sequence) 1)
687 (aref current-key-remap-sequence 0)))
688 (touch-screen-translate-prompt prompt)
689 (event (catch 'input-event
690 ;; First, process the one event already within
691 ;; `current-key-remap-sequence'.
692 (touch-screen-handle-touch
693 (aref current-key-remap-sequence
694 (if prefix 1 0))
695 prefix)
696 ;; Next, continue reading input events.
697 (while t
698 (let ((event1 (read-event)))
699 ;; If event1 is a virtual function key, make
700 ;; it the new prefix.
701 (if (memq event1 '(mode-line tab-line
702 header-line tool-bar tab-bar
703 left-fringe right-fringe
704 left-margin right-margin
705 right-divider bottom-divider))
706 (setq prefix event1)
707 ;; If event1 is not a touch screen event, return
708 ;; it.
709 (if (not (memq (car-safe event1)
710 '(touchscreen-begin
711 touchscreen-end
712 touchscreen-update)))
713 (throw 'input-event event1)
714 ;; Process this event as well.
715 (touch-screen-handle-touch event1 prefix))))))))
716 ;; Return a key sequence consisting of event
717 ;; or an empty vector if it is nil, meaning that
718 ;; no key events have been translated.
719 (if event (or (and prefix (consp event)
720 ;; If this is a mode line event, then generate
721 ;; the appropriate function key.
722 (vector prefix event))
723 (vector event))
724 ""))))
725
726(define-key function-key-map [touchscreen-begin]
727 #'touch-screen-translate-touch)
728(define-key function-key-map [touchscreen-update]
729 #'touch-screen-translate-touch)
730(define-key function-key-map [touchscreen-end]
731 #'touch-screen-translate-touch)
732
733(define-key function-key-map [mode-line touchscreen-begin]
734 #'touch-screen-translate-touch)
735(define-key function-key-map [mode-line touchscreen-update]
736 #'touch-screen-translate-touch)
737(define-key function-key-map [mode-line touchscreen-end]
738 #'touch-screen-translate-touch)
739
740(define-key function-key-map [header-line touchscreen-begin]
741 #'touch-screen-translate-touch)
742(define-key function-key-map [header-line touchscreen-update]
743 #'touch-screen-translate-touch)
744(define-key function-key-map [header-line touchscreen-end]
745 #'touch-screen-translate-touch)
746
747(define-key function-key-map [bottom-divider touchscreen-begin]
748 #'touch-screen-translate-touch)
749(define-key function-key-map [bottom-divider touchscreen-update]
750 #'touch-screen-translate-touch)
751(define-key function-key-map [bottom-divider touchscreen-end]
752 #'touch-screen-translate-touch)
753
754(define-key function-key-map [right-divider touchscreen-begin]
755 #'touch-screen-translate-touch)
756(define-key function-key-map [right-divider touchscreen-update]
757 #'touch-screen-translate-touch)
758(define-key function-key-map [right-divider touchscreen-end]
759 #'touch-screen-translate-touch)
760
761(define-key function-key-map [right-divider touchscreen-begin]
762 #'touch-screen-translate-touch)
763(define-key function-key-map [right-divider touchscreen-update]
764 #'touch-screen-translate-touch)
765(define-key function-key-map [right-divider touchscreen-end]
766 #'touch-screen-translate-touch)
767
768(define-key function-key-map [left-fringe touchscreen-begin]
769 #'touch-screen-translate-touch)
770(define-key function-key-map [left-fringe touchscreen-update]
771 #'touch-screen-translate-touch)
772(define-key function-key-map [left-fringe touchscreen-end]
773 #'touch-screen-translate-touch)
774
775(define-key function-key-map [right-fringe touchscreen-begin]
776 #'touch-screen-translate-touch)
777(define-key function-key-map [right-fringe touchscreen-update]
778 #'touch-screen-translate-touch)
779(define-key function-key-map [right-fringe touchscreen-end]
780 #'touch-screen-translate-touch)
781
782(define-key function-key-map [left-margin touchscreen-begin]
783 #'touch-screen-translate-touch)
784(define-key function-key-map [left-margin touchscreen-update]
785 #'touch-screen-translate-touch)
786(define-key function-key-map [left-margin touchscreen-end]
787 #'touch-screen-translate-touch)
788
789(define-key function-key-map [right-margin touchscreen-begin]
790 #'touch-screen-translate-touch)
791(define-key function-key-map [right-margin touchscreen-update]
792 #'touch-screen-translate-touch)
793(define-key function-key-map [right-margin touchscreen-end]
794 #'touch-screen-translate-touch)
509 795
510 796
511;; Exports. These functions are intended for use externally. 797;; Exports. These functions are intended for use externally.
@@ -582,149 +868,6 @@ touch point in EVENT did not move significantly, and t otherwise."
582 868
583 869
584 870
585;; Modeline dragging.
586
587(defun touch-screen-drag-mode-line-1 (event)
588 "Internal helper for `touch-screen-drag-mode-line'.
589This is called when that function determines that no drag really
590happened. EVENT is the same as in `touch-screen-drag-mode-line'."
591 ;; If there is an object at EVENT, then look either a keymap bound
592 ;; to [down-mouse-1] or a command bound to [mouse-1]. Then, if a
593 ;; keymap was found, pop it up as a menu. Otherwise, wait for a tap
594 ;; to complete and run the command found.
595 ;; Also, select the window in EVENT.
596 (select-window (posn-window (cdadr event)))
597 (let* ((object (posn-object (cdadr event)))
598 (object-keymap (and (consp object)
599 (stringp (car object))
600 (or (get-text-property (cdr object)
601 'keymap
602 (car object))
603 (get-text-property (cdr object)
604 'local-map
605 (car object)))))
606 (keymap (lookup-key object-keymap [mode-line down-mouse-1]))
607 (command (or (lookup-key object-keymap [mode-line mouse-1])
608 keymap)))
609 (when (or (keymapp keymap) command)
610 (if (keymapp keymap)
611 (when-let* ((command (x-popup-menu event keymap))
612 (tem (lookup-key keymap
613 (if (consp command)
614 (apply #'vector command)
615 (vector command))
616 t)))
617 (call-interactively tem))
618 (when (commandp command)
619 (call-interactively command nil
620 (vector (list 'mouse-1 (cdadr event)))))))))
621
622(defun touch-screen-drag-mode-line (event)
623 "Begin dragging the mode line in response to a touch EVENT.
624Change the height of the window based on where the touch point in
625EVENT moves.
626
627If it does not actually move anywhere and the touch point is
628removed, and EVENT lies on top of text with a mouse command
629bound, run that command instead."
630 (interactive "e")
631 ;; Find the window that should be dragged and the starting position.
632 (let* ((window (posn-window (cdadr event)))
633 (relative-xy (touch-screen-relative-xy (cdadr event)
634 'frame))
635 (last-position (cdr relative-xy)))
636 (when (window-resizable window 0)
637 (when (eq
638 (touch-screen-track-drag
639 event (lambda (new-event &optional _data)
640 ;; Find the position of the touchpoint in
641 ;; NEW-EVENT.
642 (let* ((touchpoint (assq (caadr event)
643 (cadr new-event)))
644 (new-relative-xy
645 (touch-screen-relative-xy (cdr touchpoint) 'frame))
646 (position (cdr new-relative-xy))
647 (window-resize-pixelwise t)
648 growth)
649 ;; Now set the new height of the window. If
650 ;; new-relative-y is above relative-xy, then
651 ;; make the window that much shorter.
652 ;; Otherwise, make it bigger.
653 (unless (or (zerop (setq growth
654 (- position last-position)))
655 (and (> growth 0)
656 (< position
657 (+ (window-pixel-top window)
658 (window-pixel-height window))))
659 (and (< growth 0)
660 (> position
661 (+ (window-pixel-top window)
662 (window-pixel-height window)))))
663 (when (ignore-errors
664 (adjust-window-trailing-edge window growth nil t) t)
665 (setq last-position position))))))
666 'no-drag)
667 ;; Dragging did not actually happen, so try to run any command
668 ;; necessary.
669 (touch-screen-drag-mode-line-1 event)))))
670
671(global-set-key [mode-line touchscreen-begin]
672 #'touch-screen-drag-mode-line)
673(global-set-key [bottom-divider touchscreen-begin]
674 #'touch-screen-drag-mode-line)
675
676
677
678;; Header line tapping.
679
680(defun touch-screen-tap-header-line (event)
681 "Handle a `touchscreen-begin' EVENT on the header line.
682Wait for the tap to complete, then run any command bound to
683`mouse-1' at the position of EVENT.
684
685If another keymap is bound to `down-mouse-1', then display a menu
686with its contents instead, and run the selected command."
687 (interactive "e")
688 (let* ((posn (cdadr event))
689 (object (posn-object posn))
690 ;; Look for the keymap defined by the object itself.
691 (object-keymap (and (consp object)
692 (stringp (car object))
693 (or (get-text-property (cdr object)
694 'keymap
695 (car object))
696 (get-text-property (cdr object)
697 'local-map
698 (car object)))))
699 command keymap)
700 ;; Now look for either a command bound to `mouse-1' or a keymap
701 ;; bound to `down-mouse-1'.
702 (with-selected-window (posn-window posn)
703 (setq command (lookup-key object-keymap
704 [header-line mouse-1] t)
705 keymap (lookup-key object-keymap
706 [header-line down-mouse-1] t))
707 (unless (keymapp keymap)
708 (setq keymap nil)))
709 ;; Wait for the tap to complete.
710 (when (touch-screen-track-tap event)
711 ;; Select the window whose header line was clicked.
712 (with-selected-window (posn-window posn)
713 (if keymap
714 (when-let* ((command (x-popup-menu event keymap))
715 (tem (lookup-key keymap
716 (if (consp command)
717 (apply #'vector command)
718 (vector command))
719 t)))
720 (call-interactively tem))
721 (when (commandp command)
722 (call-interactively command nil
723 (vector (list 'mouse-1 (cdadr event))))))))))
724
725(global-set-key [header-line touchscreen-begin]
726 #'touch-screen-tap-header-line)
727
728(provide 'touch-screen) 871(provide 'touch-screen)
729 872
730;;; touch-screen ends here 873;;; touch-screen ends here
diff --git a/lisp/wid-edit.el b/lisp/wid-edit.el
index 4df1fb7ab08..fa801cab51b 100644
--- a/lisp/wid-edit.el
+++ b/lisp/wid-edit.el
@@ -1193,8 +1193,7 @@ If nothing was called, return non-nil."
1193 ;; up event. 1193 ;; up event.
1194 (cond 1194 (cond
1195 ((eq (car event) 'touchscreen-begin) 1195 ((eq (car event) 'touchscreen-begin)
1196 (setq command (lookup-key widget-global-map 1196 (setq command 'touch-screen-handle-touch))
1197 [touchscreen-begin])))
1198 (mouse-1 (cond ((setq command ;down event 1197 (mouse-1 (cond ((setq command ;down event
1199 (lookup-key widget-global-map [down-mouse-1])) 1198 (lookup-key widget-global-map [down-mouse-1]))
1200 (setq up nil)) 1199 (setq up nil))
@@ -1213,6 +1212,11 @@ If nothing was called, return non-nil."
1213 (call-interactively command))))) 1212 (call-interactively command)))))
1214 (message "You clicked somewhere weird."))) 1213 (message "You clicked somewhere weird.")))
1215 1214
1215;; Make sure `touch-screen-handle-touch' abstains from emulating
1216;; down-mouse-1 events for `widget-button-click'.
1217
1218(put 'widget-button-click 'ignored-mouse-command t)
1219
1216(defun widget-button-press (pos &optional event) 1220(defun widget-button-press (pos &optional event)
1217 "Invoke button at POS." 1221 "Invoke button at POS."
1218 (interactive "@d") 1222 (interactive "@d")
diff --git a/src/keyboard.c b/src/keyboard.c
index ea07c538aa2..e10128def13 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -9994,13 +9994,18 @@ typedef struct keyremap
9994 If the mapping is a function and DO_FUNCALL is true, 9994 If the mapping is a function and DO_FUNCALL is true,
9995 the function is called with PROMPT as parameter and its return 9995 the function is called with PROMPT as parameter and its return
9996 value is used as the return value of this function (after checking 9996 value is used as the return value of this function (after checking
9997 that it is indeed a vector). */ 9997 that it is indeed a vector).
9998
9999 START and END are the indices of the first and last key of the
10000 sequence being remapped within the keyboard buffer KEYBUF. */
9998 10001
9999static Lisp_Object 10002static Lisp_Object
10000access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt, 10003access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
10001 bool do_funcall) 10004 bool do_funcall, ptrdiff_t start, ptrdiff_t end,
10005 Lisp_Object *keybuf)
10002{ 10006{
10003 Lisp_Object next; 10007 Lisp_Object next;
10008 specpdl_ref count;
10004 10009
10005 next = access_keymap (map, key, 1, 0, 1); 10010 next = access_keymap (map, key, 1, 0, 1);
10006 10011
@@ -10016,10 +10021,18 @@ access_keymap_keyremap (Lisp_Object map, Lisp_Object key, Lisp_Object prompt,
10016 its value instead. */ 10021 its value instead. */
10017 if (do_funcall && FUNCTIONP (next)) 10022 if (do_funcall && FUNCTIONP (next))
10018 { 10023 {
10019 Lisp_Object tem; 10024 Lisp_Object tem, remap;
10020 tem = next; 10025 tem = next;
10021 10026
10022 next = call1 (next, prompt); 10027 /* Build Vcurrent_key_remap_sequence. */
10028 remap = Fvector (end - start + 1, keybuf + start);
10029
10030 /* Bind `current-key-remap-sequence' to the key sequence being
10031 remapped. */
10032 count = SPECPDL_INDEX ();
10033 specbind (Qcurrent_key_remap_sequence, remap);
10034 next = unbind_to (count, call1 (next, prompt));
10035
10023 /* If the function returned something invalid, 10036 /* If the function returned something invalid,
10024 barf--don't ignore it. */ 10037 barf--don't ignore it. */
10025 if (! (NILP (next) || VECTORP (next) || STRINGP (next))) 10038 if (! (NILP (next) || VECTORP (next) || STRINGP (next)))
@@ -10044,11 +10057,17 @@ keyremap_step (Lisp_Object *keybuf, volatile keyremap *fkey,
10044 int input, bool doit, int *diff, Lisp_Object prompt) 10057 int input, bool doit, int *diff, Lisp_Object prompt)
10045{ 10058{
10046 Lisp_Object next, key; 10059 Lisp_Object next, key;
10060 ptrdiff_t buf_start, buf_end;
10061
10062 /* Save the key sequence being translated. */
10063 buf_start = fkey->start;
10064 buf_end = fkey->end;
10047 10065
10048 key = keybuf[fkey->end++]; 10066 key = keybuf[fkey->end++];
10049 10067
10050 if (KEYMAPP (fkey->parent)) 10068 if (KEYMAPP (fkey->parent))
10051 next = access_keymap_keyremap (fkey->map, key, prompt, doit); 10069 next = access_keymap_keyremap (fkey->map, key, prompt, doit,
10070 buf_start, buf_end, keybuf);
10052 else 10071 else
10053 next = Qnil; 10072 next = Qnil;
10054 10073
@@ -12479,6 +12498,7 @@ static const struct event_head head_table[] = {
12479 {SYMBOL_INDEX (Qselect_window), SYMBOL_INDEX (Qswitch_frame)}, 12498 {SYMBOL_INDEX (Qselect_window), SYMBOL_INDEX (Qswitch_frame)},
12480 /* Touchscreen events should be prefixed by the posn. */ 12499 /* Touchscreen events should be prefixed by the posn. */
12481 {SYMBOL_INDEX (Qtouchscreen_begin), SYMBOL_INDEX (Qtouchscreen)}, 12500 {SYMBOL_INDEX (Qtouchscreen_begin), SYMBOL_INDEX (Qtouchscreen)},
12501 {SYMBOL_INDEX (Qtouchscreen_end), SYMBOL_INDEX (Qtouchscreen)},
12482}; 12502};
12483 12503
12484static Lisp_Object 12504static Lisp_Object
@@ -13575,6 +13595,15 @@ If non-nil, text conversion will continue to happen after a prefix
13575key has been read inside `read-key-sequence'. */); 13595key has been read inside `read-key-sequence'. */);
13576 disable_inhibit_text_conversion = false; 13596 disable_inhibit_text_conversion = false;
13577 13597
13598 DEFVAR_LISP ("current-key-remap-sequence",
13599 Vcurrent_key_remap_sequence,
13600 doc: /* The key sequence currently being remap, or nil.
13601Bound to a vector containing the sub-sequence matching a binding
13602within `input-decode-map' or `local-function-key-map' when its bound
13603function is called to remap that sequence. */);
13604 Vcurrent_key_remap_sequence = Qnil;
13605 DEFSYM (Qcurrent_key_remap_sequence, "current-key-remap-sequence");
13606
13578 pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper); 13607 pdumper_do_now_and_after_load (syms_of_keyboard_for_pdumper);
13579} 13608}
13580 13609