From: Po Lu Date: Wed, 1 Jun 2022 08:25:53 +0000 (+0800) Subject: Clean up text/uri-list mess inside the Dired drag-and-drop code X-Git-Tag: emacs-29.0.90~1910^2~295^2~24 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=f5fadbbfec8c8f5d66fe0169c92096743102990e;p=emacs.git Clean up text/uri-list mess inside the Dired drag-and-drop code * doc/lispref/frames.texi (Window System Selections): * etc/NEWS: Document new changes to `gui-get-selection'. * lisp/dired.el (dired-mouse-drag): Specify text/uri-list value explicitly. * lisp/select.el (gui-set-selection): Update doc string. (xselect-convert-to-text-uri-list): Update to handle either a single URL (as a string) or a vector of URLs, instead of file names. (xselect-uri-list-available-p): Likewise. * src/xselect.c (x_get_local_selection): Look in tem's text properties (if it is a string) for a local value before using tem itself. --- diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi index 20e9c17f1f9..13bd144115a 100644 --- a/doc/lispref/frames.texi +++ b/doc/lispref/frames.texi @@ -3943,6 +3943,13 @@ overlay or a pair of markers stands for text in the overlay or between the markers. The argument @var{data} may also be a vector of valid non-vector selection values. +If @var{data} is a string, then its text properties can specify values +used for individual data types. For example, if @var{data} has a +property named @code{text/uri-list}, then a call to +@code{gui-get-selection} with the data type @code{text/uri-list} will +result in the value of that property being used instead of @var{data} +itself. + This function returns @var{data}. @end deffn diff --git a/etc/NEWS b/etc/NEWS index 87cd41ec014..1233e245a04 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1909,6 +1909,11 @@ functions. * Lisp Changes in Emacs 29.1 ++++ +** 'gui-set-selection' can now specify different values for different data types. +If DATA is a string, then its text properties are searched for values +for each specific data type while the selection is being converted. + --- ** New eldoc function: 'elisp-eldoc-var-docstring-with-value'. This function includes the current value of the variable in eldoc display diff --git a/lisp/dired.el b/lisp/dired.el index 3f2e52e6290..5a1fce860e1 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -1764,7 +1764,15 @@ when Emacs exits or the user drags another file.") (setq dired-last-dragged-remote-file filename) (add-hook 'kill-emacs-hook #'dired-remove-last-dragged-local-file)) - (gui-backend-set-selection 'XdndSelection filename) + (gui-backend-set-selection + ;; FIXME: this seems arbitrarily confusing. + ;; Should drag-and-drop for common items (such as + ;; files and text) should be abstracted into + ;; dnd.el? + 'XdndSelection + (propertize filename 'text/uri-list + (concat "file://" + (expand-file-name filename)))) (x-begin-drag '("text/uri-list" "text/x-dnd-username" "FILE_NAME" "FILE" "HOST_NAME" "_DT_NETFILE") (if (eq 'dired-mouse-drag-files 'link) diff --git a/lisp/select.el b/lisp/select.el index dbe9633517f..01e002db709 100644 --- a/lisp/select.el +++ b/lisp/select.el @@ -401,11 +401,16 @@ also be a string, which stands for the symbol with that name, but this is considered obsolete.) DATA may be a string, a symbol, or an integer. -The selection may also be a cons of two markers pointing to the same buffer, -or an overlay. In these cases, the selection is considered to be the text -between the markers *at whatever time the selection is examined*. -Thus, editing done in the buffer after you specify the selection -can alter the effective value of the selection. +The selection may also be a cons of two markers pointing to the +same buffer, or an overlay. In these cases, the selection is +considered to be the text between the markers *at whatever time +the selection is examined*. Thus, editing done in the buffer +after you specify the selection can alter the effective value of +the selection. If DATA is a string, then its text properties can +specify alternative values for different data types. For +example, the value of any property named `text/uri-list' will be +used instead of DATA itself when another program converts TYPE to +the target `text/uri-list'. The data may also be a vector of valid non-vector selection values. @@ -692,18 +697,15 @@ This function returns the string \"emacs\"." (user-real-login-name)) (defun xselect-convert-to-text-uri-list (_selection _type value) - (when (and (stringp value) - (file-exists-p value)) - (concat (url-encode-url - ;; Uncomment the following code code in a better world where - ;; people write correct code that adds the hostname to the URI. - ;; Since most programs don't implement this properly, we omit the - ;; hostname so that copying files actually works. Most properly - ;; written programs will look at WM_CLIENT_MACHINE to determine - ;; the hostname anyway. (format "file://%s%s\n" (system-name) - ;; (expand-file-name value)) - (concat "file://" (expand-file-name value))) - "\n"))) + (if (stringp value) + (concat (url-encode-url value) "\n") + (when (vectorp value) + (with-temp-buffer + (cl-loop for tem across value + do (progn + (insert (url-encode-url tem)) + (insert "\n"))) + (buffer-string))))) (defun xselect-convert-to-xm-file (selection _type value) (when (and (stringp value) @@ -716,8 +718,8 @@ This function returns the string \"emacs\"." "Return whether or not `text/uri-list' is a valid target for SELECTION. VALUE is the local selection value of SELECTION." (and (eq selection 'XdndSelection) - (stringp value) - (file-exists-p value))) + (or (stringp value) + (vectorp value)))) (defun xselect-convert-xm-special (_selection _type _value) "") diff --git a/src/xselect.c b/src/xselect.c index a4148735945..5f2a0cf56de 100644 --- a/src/xselect.c +++ b/src/xselect.c @@ -399,7 +399,7 @@ static Lisp_Object x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type, bool local_request, struct x_display_info *dpyinfo) { - Lisp_Object local_value; + Lisp_Object local_value, tem; Lisp_Object handler_fn, value, check; local_value = LOCAL_SELECTION (selection_symbol, dpyinfo); @@ -426,10 +426,21 @@ x_get_local_selection (Lisp_Object selection_symbol, Lisp_Object target_type, if (CONSP (handler_fn)) handler_fn = XCDR (handler_fn); + tem = XCAR (XCDR (local_value)); + + if (STRINGP (tem)) + { + local_value = Fget_text_property (make_fixnum (0), + target_type, tem); + + if (!NILP (local_value)) + tem = local_value; + } + if (!NILP (handler_fn)) - value = call3 (handler_fn, - selection_symbol, (local_request ? Qnil : target_type), - XCAR (XCDR (local_value))); + value = call3 (handler_fn, selection_symbol, + (local_request ? Qnil : target_type), + tem); else value = Qnil; value = unbind_to (count, value);