From 51a06388b79c8d42241455afeb5ca3ad0d8225d9 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 17 Jul 2023 13:58:32 +0800 Subject: [PATCH] Update Android port * doc/lispref/commands.texi (Touchscreen Events): Document changes to simple translation. * lisp/touch-screen.el (touch-screen-handle-point-up): Generate `down-mouse-1' if the current gesture is `mouse-1-menu'. (touch-screen-handle-touch): If binding is a keymap, set state to `mouse-1-menu' and wait for point to be released before generating down-mouse-1. --- doc/lispref/commands.texi | 8 +++++ lisp/touch-screen.el | 65 +++++++++++++++++++++++++++------------ 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi index 025ac197feb..74b57f58ee8 100644 --- a/doc/lispref/commands.texi +++ b/doc/lispref/commands.texi @@ -2080,6 +2080,14 @@ selected, as a compromise for packages which assume @code{mouse-drag-region} has already set point to the location of any mouse click and selected the window where it took place. +To prevent unwanted @code{mouse-1} events arriving after a mouse menu +is dismissed (@pxref{Mouse Menus}), Emacs also avoids simple +translation if @code{down-mouse-1} is bound to a keymap, making it a +prefix key. In lieu of simple translation, it translates the closing +@code{touchscreen-end} to a @code{down-mouse-1} event with the +starting position of the touch sequence, consequentially displaying +the mouse menu. + If touch gestures are detected during translation, one of the following input events may be generated: diff --git a/lisp/touch-screen.el b/lisp/touch-screen.el index f500076c78a..7d733bdb77f 100644 --- a/lisp/touch-screen.el +++ b/lisp/touch-screen.el @@ -648,6 +648,11 @@ If the fourth element of `touch-screen-current-tool' is `drag-mouse-1' event depending on how far the position of POINT is from the starting point of the touch. +If the fourth element of `touch-screen-current-tool' is +`mouse-1-menu', then generate a `down-mouse-1' event at the +original position of the tool to display its bound keymap as a +menu. + If the command being executed is listed in `touch-screen-set-point-commands' also display the on-screen keyboard if the current buffer and the character at the new point @@ -738,7 +743,13 @@ is not read-only." ;; ... otherwise, generate a drag-mouse-1 event. (list 'drag-mouse-1 (cons old-window old-posn) - (cons new-window posn))))))))) + (cons new-window posn)))))) + ((eq what 'mouse-1-menu) + ;; Generate a `down-mouse-1' event at the position the tap + ;; took place. + (throw 'input-event + (list 'down-mouse-1 + (nth 4 touch-screen-current-tool))))))) (defun touch-screen-handle-touch (event prefix &optional interactive) "Handle a single touch EVENT, and perform associated actions. @@ -757,11 +768,11 @@ the place of EVENT within the key sequence being translated, or ;; Called interactively (probably from wid-edit.el.) ;; Add any event generated to `unread-command-events'. (let ((event (catch 'input-event - (touch-screen-handle-touch event prefix) nil))) - (when event + (touch-screen-translate-touch nil) nil))) + (when (vectorp event) (setq unread-command-events (nconc unread-command-events - (list event))))) + (nreverse (append event nil)))))) (cond ((eq (car event) 'touchscreen-begin) ;; A tool was just pressed against the screen. Figure out the @@ -770,7 +781,8 @@ the place of EVENT within the key sequence being translated, or (let* ((touchpoint (caadr event)) (position (cdadr event)) (window (posn-window position)) - (point (posn-point position))) + (point (posn-point position)) + binding) ;; Cancel the touch screen timer, if it is still there by any ;; chance. (when touch-screen-current-timer @@ -785,22 +797,37 @@ the place of EVENT within the key sequence being translated, or nil nil nil nil))) ;; Determine if there is a command bound to `down-mouse-1' at ;; the position of the tap and that command is not a command - ;; whose functionality is replaced by the long-press mechanism. - ;; If so, set the fourth element of `touch-screen-current-tool' - ;; to `mouse-drag' and generate an emulated `mouse-1' event. + ;; whose functionality is replaced by the long-press + ;; mechanism. If so, set the fourth element of + ;; `touch-screen-current-tool' to `mouse-drag' and generate an + ;; emulated `mouse-1' event. + ;; + ;; If the command in question is a keymap, use `mouse-1-menu' + ;; instead of `mouse-drag', and don't generate a + ;; `down-mouse-1' event immediately. Instead, wait for the + ;; touch point to be released. (if (and touch-screen-current-tool (with-selected-window window - (let ((binding (key-binding (if prefix - (vector prefix - 'down-mouse-1) - [down-mouse-1]) - t nil position))) - (and binding - (not (and (symbolp binding) - (get binding 'ignored-mouse-command))))))) - (progn (setcar (nthcdr 3 touch-screen-current-tool) - 'mouse-drag) - (throw 'input-event (list 'down-mouse-1 position))) + (and (setq binding + (key-binding (if prefix + (vector prefix + 'down-mouse-1) + [down-mouse-1]) + t nil position)) + (not (and (symbolp binding) + (get binding 'ignored-mouse-command)))))) + (if (keymapp binding) + ;; binding is a keymap. If a `mouse-1' event is + ;; generated after the keyboard command loop displays + ;; it as a menu, that event could cause unwanted + ;; commands to be run. Set what to `mouse-1-menu' + ;; instead and wait for the up event to display the + ;; menu. + (setcar (nthcdr 3 touch-screen-current-tool) + 'mouse-1-menu) + (progn (setcar (nthcdr 3 touch-screen-current-tool) + 'mouse-drag) + (throw 'input-event (list 'down-mouse-1 position)))) (and point ;; Start the long-press timer. (touch-screen-handle-timeout nil))))) -- 2.39.2