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.
This commit is contained in:
Po Lu 2022-06-01 16:25:53 +08:00
parent a3d3fef2bc
commit f5fadbbfec
5 changed files with 57 additions and 24 deletions

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)
"")

View file

@ -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);