From de380adb64688455ef315ea807622de25e385c44 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Mon, 6 Nov 2023 10:14:09 +0800 Subject: [PATCH] Emulate secondary selections on Android * doc/lispref/frames.texi (Other Selections): Revise documentation to match. * lisp/term/android-win.el (android-secondary-selection): New variable. (android-primary-selection, android-get-clipboard-1) (android-get-primary, gui-backend-get-selection) (gui-backend-selection-exists-p, gui-backend-selection-owner-p) (gui-backend-set-selection): Update doc strings and code as is proper. --- doc/lispref/frames.texi | 9 ++++-- lisp/term/android-win.el | 61 +++++++++++++++++++++++++++++----------- 2 files changed, 51 insertions(+), 19 deletions(-) diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 6193a4fe1cd..ca8c79395ed 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -4686,15 +4686,18 @@ of available selection data types, as elsewhere. @cindex Android selections Much like MS-Windows, Android provides a clipboard but no primary or secondary selection; @code{gui-set-selection} simulates the primary -selection by saving the value supplied into a variable subsequent -calls to @code{gui-get-selection} return. +and secondary selections by saving the value supplied into a variable +subsequent calls to @code{gui-get-selection} return. From the clipboard, @code{gui-get-selection} is capable of returning UTF-8 string data of the type @code{STRING}, the @code{TAREGTS} data type, or image and application data of any MIME type. @code{gui-set-selection} sets only string data, much as under MS-Windows, although this data is not affected by the value of -@code{selection-coding-system}. +@code{selection-coding-system}. By contrast, only string data can be +saved to and from the primary and secondary selections; but since this +data is not communicated to programs besides Emacs, it is not subject +to encoding or decoding by any coding system. @node Yanking Media @section Yanking Media diff --git a/lisp/term/android-win.el b/lisp/term/android-win.el index 70e24f4ccc7..7d9a033d723 100644 --- a/lisp/term/android-win.el +++ b/lisp/term/android-win.el @@ -75,19 +75,28 @@ DISPLAY is ignored on Android." (defvar android-primary-selection nil "The last string placed in the primary selection. -Nil if there was no such string. +nil if there was no such string. -Android does not have a primary selection of its own, so Emacs -emulates one inside Lisp.") +Android is not equipped with a primary selection of its own, so +Emacs emulates one in Lisp.") + +(defvar android-secondary-selection nil + "The last string placed in the secondary selection. +nil if there was no such string. + +Android is not equipped with a secondary selection of its own, so +Emacs emulates one in Lisp.") (defun android-get-clipboard-1 (data-type) - "Return the clipboard data. -DATA-TYPE is a selection conversion target. `STRING' means to -return the contents of the clipboard as a string. `TARGETS' -means to return supported data types as a vector. + "Return data saved from the clipboard. +DATA-TYPE is a selection conversion target. -Interpret any other symbol as a MIME type, and return its -corresponding data." +`STRING' means return the contents of the clipboard as a string, +while `TARGETS' means return the types of all data present within +the clipboard as a vector. + +Interpret any other symbol as a MIME type for which any clipboard +data is returned" (or (and (eq data-type 'STRING) (android-get-clipboard)) (and (eq data-type 'TARGETS) @@ -95,7 +104,8 @@ corresponding data." (vconcat [TARGETS STRING] (let ((i nil)) (dolist (type (android-get-clipboard-targets)) - ;; Don't report plain text as a valid target. + ;; Don't report plain text as a valid target + ;; since it is addressed by STRING. (unless (equal type "text/plain") (push (intern type) i))) (nreverse i)))) @@ -109,7 +119,16 @@ Return nil if DATA-TYPE is anything other than STRING or TARGETS." (or (and (eq data-type 'STRING) android-primary-selection) (and (eq data-type 'TARGETS) - [TARGETS])))) + [TARGETS STRING])))) + +(defun android-get-secondary (data-type) + "Return the last string placed in the secondary selection, or nil. +Return nil if DATA-TYPE is anything other than STRING or TARGETS." + (when android-secondary-selection + (or (and (eq data-type 'STRING) + android-secondary-selection) + (and (eq data-type 'TARGETS) + [TARGETS STRING])))) (defun android-selection-bounds (value) "Return bounds of selection value VALUE. @@ -152,26 +171,34 @@ VALUE should be something suitable for passing to (cond ((eq type 'CLIPBOARD) (android-get-clipboard-1 data-type)) ((eq type 'PRIMARY) - (android-get-primary data-type)))) + (android-get-primary data-type)) + ((eq type 'SECONDARY) + (android-get-secondary data-type)))) (cl-defmethod gui-backend-selection-exists-p (selection &context (window-system android)) (cond ((eq selection 'CLIPBOARD) (android-clipboard-exists-p)) ((eq selection 'PRIMARY) - (not (null android-primary-selection))))) + (not (null android-primary-selection))) + ((eq selection 'SECONDARY) + (not (null android-secondary-selection))))) (cl-defmethod gui-backend-selection-owner-p (selection &context (window-system android)) (cond ((eq selection 'CLIPBOARD) (let ((ownership (android-clipboard-owner-p))) - ;; If ownership is `lambda', then Emacs couldn't determine + ;; If ownership is `lambda', then Emacs couldn't establish ;; whether or not it owns the clipboard. (and (not (eq ownership 'lambda)) ownership))) ((eq selection 'PRIMARY) ;; Emacs always owns its own primary selection as long as it ;; exists. - (not (null android-primary-selection))))) + (not (null android-primary-selection))) + ((eq selection 'SECONDARY) + ;; Emacs always owns its own secondary selection as long as + ;; it exists. + (not (null android-secondary-selection))))) (cl-defmethod gui-backend-set-selection (type value &context (window-system android)) @@ -181,7 +208,9 @@ VALUE should be something suitable for passing to (cond ((eq type 'CLIPBOARD) (android-set-clipboard string)) ((eq type 'PRIMARY) - (setq android-primary-selection string))))) + (setq android-primary-selection string)) + ((eq type 'SECONDARY) + (setq android-secondary-selection string))))) ;;; Character composition display. -- 2.39.2