[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 2ce686c049 2/2: Support dragging multiple files on NS
From: |
Po Lu |
Subject: |
master 2ce686c049 2/2: Support dragging multiple files on NS |
Date: |
Sat, 4 Jun 2022 03:47:38 -0400 (EDT) |
branch: master
commit 2ce686c049a7a35cdc3eb87626d8a94539388a35
Author: Po Lu <luangruo@yahoo.com>
Commit: Po Lu <luangruo@yahoo.com>
Support dragging multiple files on NS
This has to use a deprecated pasteboard type, since Emacs uses
the "old" (but not deprecated) dragImage: method for
drag-and-drop, which can't drop file URLs.
* lisp/term/ns-win.el (x-begin-drag): Update accordingly.
* src/nsselect.m (ns_decode_data_to_pasteboard):
(Fns_begin_drag): Allow files to be a list of filenames as well.
---
lisp/term/ns-win.el | 20 +++++++++++++++-----
src/nsselect.m | 50 ++++++++++++++++++++++++++++++++++++++++++--------
2 files changed, 57 insertions(+), 13 deletions(-)
diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el
index a36d5d11e7..2e021b9b29 100644
--- a/lisp/term/ns-win.el
+++ b/lisp/term/ns-win.el
@@ -905,11 +905,21 @@ See the documentation of
`create-fontset-from-fontset-spec' for the format.")
(push (cons 'string ns-dnd-selection-value) pasteboard))
(when (and (member "FILE_NAME" targets)
(file-exists-p ns-dnd-selection-value))
- (push (cons 'file
- (url-encode-url (concat "file://"
- (expand-file-name
- ns-dnd-selection-value))))
- pasteboard))
+ (let ((value (if (stringp ns-dnd-selection-value)
+ (or (get-text-property 0 'FILE_NAME
+ ns-dnd-selection-value)
+ ns-dnd-selection-value)
+ ns-dnd-selection-value)))
+ (if (vectorp value)
+ (push (cons 'file
+ (cl-loop for file across value
+ collect (expand-file-name file)))
+ pasteboard)
+ (push (cons 'file
+ (url-encode-url (concat "file://"
+ (expand-file-name
+ ns-dnd-selection-value))))
+ pasteboard))))
(ns-begin-drag frame pasteboard action return-frame allow-current-frame)))
(defun ns-handle-drag-motion (frame x y)
diff --git a/src/nsselect.m b/src/nsselect.m
index a4129b12f0..a719eef4e8 100644
--- a/src/nsselect.m
+++ b/src/nsselect.m
@@ -562,8 +562,12 @@ ns_decode_data_to_pasteboard (Lisp_Object type,
Lisp_Object data,
NSPasteboard *pasteboard)
{
NSArray *types, *new;
+ NSMutableArray *temp;
+ Lisp_Object tem;
+ specpdl_ref count;
types = [pasteboard types];
+ count = SPECPDL_INDEX ();
CHECK_SYMBOL (type);
@@ -580,10 +584,11 @@ ns_decode_data_to_pasteboard (Lisp_Object type,
Lisp_Object data,
}
else if (EQ (type, Qfile))
{
- CHECK_STRING (data);
-
#if NS_USE_NSPasteboardTypeFileURL
- new = [types arrayByAddingObject: NSPasteboardTypeFileURL];
+ if (CONSP (data))
+ new = [types arrayByAddingObject: NSPasteboardTypeURL];
+ else
+ new = [types arrayByAddingObject: NSPasteboardTypeFileURL];
#else
new = [types arrayByAddingObject: NSFilenamesPboardType];
#endif
@@ -591,13 +596,41 @@ ns_decode_data_to_pasteboard (Lisp_Object type,
Lisp_Object data,
[pasteboard declareTypes: new
owner: nil];
+ if (STRINGP (data))
+ {
#if NS_USE_NSPasteboardTypeFileURL
- [pasteboard setString: [NSString stringWithLispString: data]
- forType: NSPasteboardTypeFileURL];
+ [pasteboard setString: [NSString stringWithLispString: data]
+ forType: NSPasteboardTypeFileURL];
#else
- [pasteboard setString: [NSString stringWithLispString: data]
- forType: NSFilenamesPboardType];
+ [pasteboard setString: [NSString stringWithLispString: data]
+ forType: NSFilenamesPboardType];
+#endif
+ }
+ else
+ {
+ CHECK_LIST (data);
+ temp = [[NSMutableArray alloc] init];
+ record_unwind_protect_ptr (ns_release_object, temp);
+
+ for (tem = data; CONSP (tem); tem = XCDR (tem))
+ {
+ CHECK_STRING (XCAR (tem));
+
+ [temp addObject: [NSString stringWithLispString: XCAR (tem)]];
+ }
+ CHECK_LIST_END (tem, data);
+#if NS_USE_NSPasteboardTypeFileURL
+ [pasteboard setPropertyList: temp
+ /* We have to use this deprecated pasteboard
+ type, since Apple doesn't let us use
+ dragImage:at: to drag multiple file URLs. */
+ forType: @"NSFilenamesPboardType"];
+#else
+ [pasteboard setPropertyList: temp
+ forType: NSFilenamesPboardType];
#endif
+ unbind_to (count, Qnil);
+ }
}
else
signal_error ("Unknown pasteboard type", type);
@@ -673,7 +706,8 @@ the meaning of DATA:
be dragged to another program.
- `file' means DATA should be a file URL that will be dragged to
- another program.
+ another program. DATA may also be a list of file names; that
+ means each file in the list will be dragged to another program.
ACTION is the action that will be taken by the drop target towards the
data inside PBOARD.