Function: dnd-begin-drag-files

dnd-begin-drag-files is a byte-compiled function defined in dnd.el.gz.

Signature

(dnd-begin-drag-files FILES &optional FRAME ACTION ALLOW-SAME-FRAME)

Documentation

Begin dragging FILES from FRAME.

This is like dnd-begin-file-drag, except with multiple files. FRAME, ACTION and ALLOW-SAME-FRAME mean the same as in dnd-begin-file-drag.

FILES is a list of files that will be dragged. If the drop target doesn't support dropping multiple files, the first file in FILES will be dragged.

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-drag-files (files &optional frame action allow-same-frame)
  "Begin dragging FILES from FRAME.
This is like `dnd-begin-file-drag', except with multiple files.
FRAME, ACTION and ALLOW-SAME-FRAME mean the same as in
`dnd-begin-file-drag'.

FILES is a list of files that will be dragged.  If the drop
target doesn't support dropping multiple files, the first file in
FILES will be dragged.

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)
  (let* ((new-files (copy-sequence files))
         (tem new-files))
    (while tem
      (setcar tem (expand-file-name (car tem)))
      (when (file-remote-p (car tem))
        (when (eq action 'link)
          (error "Cannot create symbolic link to remote file"))
        (condition-case error
            (progn (setcar tem (file-local-copy (car tem)))
                   (push (car tem) dnd-last-dragged-remote-file))
          (error (message "Failed to download file: %s" error)
                 (setcar tem nil))))
      (setq tem (cdr tem)))
    (when dnd-last-dragged-remote-file
      (add-hook 'kill-emacs-hook
                #'dnd-remove-last-dragged-remote-file))
    ;; Remove any files that failed to download from a remote host.
    (setq new-files (delq nil new-files))
    (unless new-files
      (error "No files were specified or no remote file could be downloaded"))
    (unless action
      (setq action 'copy))
    (gui-set-selection 'XdndSelection
                       (propertize (car new-files)
                                   'text/uri-list
                                   (cl-loop for file in new-files
                                            collect (concat "file://" file)
                                            into targets finally return
                                            (apply #'vector targets))
                                   'FILE_NAME (apply #'vector new-files)))
    (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" "HOST_NAME")
                         (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.
          (dolist (original-file files)
            (when (file-remote-p original-file)
              (ignore-errors
                (delete-file original-file))))))
       ((eq return-value 'XdndActionLink) 'link)
       ((not return-value) nil)
       (t 'private)))))