emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master f5fadbbfec: Clean up text/uri-list mess inside the Dired drag-and


From: Po Lu
Subject: master f5fadbbfec: Clean up text/uri-list mess inside the Dired drag-and-drop code
Date: Wed, 1 Jun 2022 04:26:10 -0400 (EDT)

branch: master
commit f5fadbbfec8c8f5d66fe0169c92096743102990e
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>

    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.
---
 doc/lispref/frames.texi |  7 +++++++
 etc/NEWS                |  5 +++++
 lisp/dired.el           | 10 +++++++++-
 lisp/select.el          | 40 +++++++++++++++++++++-------------------
 src/xselect.c           | 19 +++++++++++++++----
 5 files changed, 57 insertions(+), 24 deletions(-)

diff --git a/doc/lispref/frames.texi b/doc/lispref/frames.texi
index 20e9c17f1f..13bd144115 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 87cd41ec01..1233e245a0 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 3f2e52e629..5a1fce860e 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 dbe9633517..01e002db70 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 a414873594..5f2a0cf56d 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);



reply via email to

[Prev in Thread] Current Thread [Next in Thread]