Function: dnd-begin-file-drag

dnd-begin-file-drag is an autoloaded and byte-compiled function defined in dnd.el.gz.

Signature

(dnd-begin-file-drag FILE &optional FRAME ACTION ALLOW-SAME-FRAME)

Documentation

Begin dragging FILE from FRAME.

Initiate a drag-and-drop operation allowing the user to drag a file from Emacs to another program (the drop target), then block until the drop happens or is canceled.

Return the action that the drop target actually performed, which can be one of the following symbols:

  - copy, which means FILE was opened by the drop target.

  - move, which means FILE was moved to another location by the
    drop target.

  - link, which means a symbolic link was created to FILE by
    the drop target, usually a file manager.

  - private, which means the drop target chose to perform an
    unspecified action.

Return nil if the drop was canceled.

FILE is the file name that will be sent to the program where the drop happened. If it is a remote file, Emacs will make a temporary copy and pass that. FRAME is the frame where the mouse is currently held down, or nil (which means to use the current frame). ACTION is one of the symbols copy, move or link, where copy means that the file should be opened or copied by the drop target, move means the drop target should move the file to another location, and link means the drop target should create a symbolic link to FILE. It is an error to specify link as the action if FILE is a remote file. If ALLOW-SAME-FRAME is nil, any drops on FRAME itself will be ignored.

This function might return immediately if no mouse buttons are currently being held down. It should only be called upon a down-mouse-1 (or similar) event.

This function is only supported on X Windows, macOS/GNUstep, and Haiku; on all other platforms it will signal an error.

View in manual

Probably introduced at or before Emacs version 29.1.

Source Code

;; Defined in /usr/src/emacs/lisp/dnd.el.gz
(defun dnd-begin-file-drag (file &optional frame action allow-same-frame)
  "Begin dragging FILE from FRAME.
Initiate a drag-and-drop operation allowing the user to drag a file
from Emacs to another program (the drop target), then block until
the drop happens or is canceled.

Return the action that the drop target actually performed, which
can be one of the following symbols:

  - `copy', which means FILE was opened by the drop target.

  - `move', which means FILE was moved to another location by the
    drop target.

  - `link', which means a symbolic link was created to FILE by
    the drop target, usually a file manager.

  - `private', which means the drop target chose to perform an
    unspecified action.

Return nil if the drop was canceled.

FILE is the file name that will be sent to the program where the
drop happened.  If it is a remote file, Emacs will make a
temporary copy and pass that.  FRAME is the frame where the mouse
is currently held down, or nil (which means to use the current
frame).  ACTION is one of the symbols `copy', `move' or `link',
where `copy' means that the file should be opened or copied by
the drop target, `move' means the drop target should move the
file to another location, and `link' means the drop target should
create a symbolic link to FILE.  It is an error to specify `link'
as the action if FILE is a remote file.  If ALLOW-SAME-FRAME is
nil, any drops on FRAME itself will be ignored.

This function might return immediately if no mouse buttons are
currently being held down.  It should only be called upon a
`down-mouse-1' (or similar) event.

This function is only supported on X Windows, macOS/GNUstep, and Haiku;
on all other platforms it will signal an error."
  (unless (fboundp 'x-begin-drag)
    (error "Dragging files from Emacs is not supported by this window system"))
  (dnd-remove-last-dragged-remote-file)
  (unless action
    (setq action 'copy))
  (if (and (or (and (eq dnd-direct-save-remote-files 'x)
                    (eq (framep (or frame
                                    (selected-frame)))
                        'x))
               (and dnd-direct-save-remote-files
                    (not (eq dnd-direct-save-remote-files 'x))))
           (eq action 'copy)
           (file-remote-p file))
      (dnd-direct-save file (file-name-nondirectory file)
                       frame allow-same-frame)
    (let ((original-file file))
      (when (file-remote-p file)
        (if (eq action 'link)
            (error "Cannot create symbolic link to remote file")
          (setq file (file-local-copy file))
          (setq dnd-last-dragged-remote-file file)
          (add-hook 'kill-emacs-hook
                    #'dnd-remove-last-dragged-remote-file)))
      (gui-set-selection 'XdndSelection
                         (propertize (expand-file-name file) 'text/uri-list
                                     (concat "file://"
                                             (expand-file-name file))))
      (let ((return-value
             (x-begin-drag '(;; Xdnd types used by GTK, Qt, and most other
                             ;; modern programs that expect filenames to
                             ;; be supplied as URIs.
                             "text/uri-list" "text/x-xdnd-username"
                             ;; Traditional X selection targets used by
                             ;; programs supporting the Motif
                             ;; drag-and-drop protocols.  Also used by NS
                             ;; and Haiku.
                             "FILE_NAME" "FILE" "HOST_NAME"
                             ;; ToolTalk filename.  Mostly used by CDE
                             ;; programs.
                             "_DT_NETFILE")
                           (cl-ecase action
                             (copy 'XdndActionCopy)
                             (move 'XdndActionMove)
                             (link 'XdndActionLink))
                           frame nil allow-same-frame)))
        (cond
         ((eq return-value 'XdndActionCopy) 'copy)
         ((eq return-value 'XdndActionMove)
          (prog1 'move
            ;; If original-file is a remote file, delete it from the
            ;; remote as well.
            (when (file-remote-p original-file)
              (ignore-errors
                (delete-file original-file)))))
         ((eq return-value 'XdndActionLink) 'link)
         ((not return-value) nil)
         (t 'private))))))