From ffab237cbfda5121fe9d6a1a479dbb5a4c3e5f2f Mon Sep 17 00:00:00 2001 From: Po Lu Date: Sat, 28 May 2022 09:18:09 +0800 Subject: [PATCH] Add file dragging support to NS port * lisp/dired.el (dired-mouse-drag-files): Document that `dired-mouse-drag-files' now works on NS. * lisp/term/ns-win.el (x-begin-drag): Handle FILE_NAME. * src/nsselect.m (ns_decode_data_to_pasteboard): Handle file URL type. (ns_lisp_to_pasteboard, Fns_begin_drag): Handle new type `file'. --- lisp/dired.el | 2 +- lisp/term/ns-win.el | 7 +++++++ src/nsselect.m | 25 ++++++++++++++++++++++++- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/lisp/dired.el b/lisp/dired.el index fbf26dbce7a..6ed4a949e0a 100644 --- a/lisp/dired.el +++ b/lisp/dired.el @@ -254,7 +254,7 @@ The target is used in the prompt for file copy, rename etc." Dragging the mouse and then releasing it over the window of another program will result in that program opening the file, or creating a copy of it. This feature is supported only on X -Windows and Haiku. +Windows, Haiku, and Nextstep (macOS or GNUstep). If the value is `link', then a symbolic link will be created to the file instead by the other program (usually a file manager)." diff --git a/lisp/term/ns-win.el b/lisp/term/ns-win.el index 42b8d72c269..b49143fbc20 100644 --- a/lisp/term/ns-win.el +++ b/lisp/term/ns-win.el @@ -903,6 +903,13 @@ See the documentation of `create-fontset-from-fontset-spec' for the format.") (when (and (member "STRING" targets) (stringp ns-dnd-selection-value)) (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)) (ns-begin-drag frame pasteboard action))) (provide 'ns-win) diff --git a/src/nsselect.m b/src/nsselect.m index a481e80d770..0bd840d92b7 100644 --- a/src/nsselect.m +++ b/src/nsselect.m @@ -561,17 +561,34 @@ static void ns_decode_data_to_pasteboard (Lisp_Object type, Lisp_Object data, NSPasteboard *pasteboard) { + NSArray *types, *new; + + types = [pasteboard types]; + CHECK_SYMBOL (type); if (EQ (type, Qstring)) { CHECK_STRING (data); - [pasteboard declareTypes: [NSArray arrayWithObject: NSPasteboardTypeString] + new = [types arrayByAddingObject: NSPasteboardTypeString]; + + [pasteboard declareTypes: new owner: nil]; [pasteboard setString: [NSString stringWithLispString: data] forType: NSPasteboardTypeString]; } + else if (EQ (type, Qfile)) + { + CHECK_STRING (data); + + new = [types arrayByAddingObject: NSPasteboardTypeFileURL]; + + [pasteboard declareTypes: new + owner: nil]; + [pasteboard setString: [NSString stringWithLispString: data] + forType: NSPasteboardTypeFileURL]; + } else signal_error ("Unknown pasteboard type", type); } @@ -582,6 +599,9 @@ ns_lisp_to_pasteboard (Lisp_Object object, { Lisp_Object tem, type, data; + [pasteboard declareTypes: [NSArray array] + owner: nil]; + CHECK_LIST (object); for (tem = object; CONSP (tem); tem = XCDR (tem)) { @@ -642,6 +662,9 @@ the meaning of DATA: - `string' means DATA should be a string describing text that will be dragged to another program. + - `file' means DATA should be a file URL that will be dragged to + another program. + ACTION is the action that will be taken by the drop target towards the data inside PBOARD. -- 2.39.2