30.22 Drag and Drop

When the user drops something from another application over Emacs, Emacs will try to insert any text and open any URL that was dropped. If text was dropped, then it will always be inserted at the location of the mouse pointer where the drop happened, or saved in the kill ring if insertion failed, which could happen if the buffer was read-only. If a URL was dropped instead, then Emacs will first try to call an appropriate handler function by matching the URL against regexps defined in the variable dnd-protocol-alist, and then against those defined in the variables browse-url-handlers and browse-url-default-handlers. Should no suitable handler be located, Emacs will fall back to inserting the URL as plain text.

Variable: dnd-protocol-alist

This variable is a list of cons cells of the form (pattern . action). pattern is a regexp that URLs are matched against after being dropped. action is a function that is called with two arguments, should a URL being dropped match pattern: the URL being dropped, and the action being performed for the drop, which is one of the symbols copy, move, link, private or ask.

If action is private, then it means the program that initiated the drop wants Emacs to perform an unspecified action with the URL; a reasonable action to perform in that case is to open the URL or copy its contents into the current buffer. Otherwise, action has the same meaning as the action argument to dnd-begin-file-drag.

Emacs implements receiving text and URLs individually for each window system, and does not by default support receiving other kinds of data as drops. To support receiving other kinds of data, use the X-specific interface described below.

When a user drags something from another application over Emacs under the X Window System, that other application expects Emacs to tell it if Emacs understands the data being dragged. The function in the variable x-dnd-test-function is called by Emacs to determine what to reply to any such inquiry. The default value is x-dnd-default-test-function, which accepts drops if the type of the data to be dropped is present in x-dnd-known-types. Changing the variables x-dnd-test-function and x-dnd-known-types can make Emacs accept or reject drops based on some other criteria.

If you want to change the way Emacs receives drops of different data types, or you want to enable it to understand a new type, change the variable x-dnd-types-alist. Doing so correctly requires detailed knowledge of what data types other applications use for drag and drop.

These data types are typically implemented as special data types that can be obtained from an X selection provided by the other application. In most cases, they are either the same data types that are typically accepted by gui-set-selection, or MIME types, depending on the specific drag-and-drop protocol being used. For example, the data type used for plain text may be either "STRING" or "text/plain".

When Emacs runs on X window system, it supports the X Direct Save (XDS) protocol, which allows users to save a file by dragging and dropping it onto an Emacs window, such as a Dired window. To comply with the unique requirements of XDS, these drag-and-drop requests are processed specially: instead of being handled according to x-dnd-types-alist, they are handled by the direct-save function that is the value of the variable x-dnd-direct-save-function. The value should be a function of two arguments, need-name and filename. The XDS protocol uses a two-step procedure for dragging files:

  1. The application from which the file is dragged asks Emacs to provide the full file name under which to save the file. For this purpose, the direct-save function is called with its first argument need-name non-nil, and the second argument filename set to the basename of the file to be saved. It should return the fully-expanded absolute file name under which to save the file. For example, if a file is dragged to a Dired window, the natural directory for the file is the directory of the file shown at location of the drop. If saving the file is not possible for some reason, the function should return nil, which will cancel the drag-and-drop operation.
  2. The application from which the file is dragged saves the file under the name returned by the first call to the direct-save function. If it succeeds in saving the file, the direct-save function is called again, this time with the first argument need-name set to nil and the second argument filename set to the full absolute name of the saved file. The function is then expected to do whatever is needed given the fact that file was saved. For example, Dired should update the directory on display by showing the new file there.

The default value of x-dnd-direct-save-function is x-dnd-save-direct.

Function: x-dnd-save-direct need-name filename

When called with the need-name argument non-nil, this function prompts the user for the absolute file name under which it should be saved. If the specified file already exists, it additionally asks the user whether to overwrite it, and returns the absolute file name only if the user confirms the overwriting.

When called with the need-name argument nil, it reverts the Dired listing if the current buffer is in Dired mode or one of its descendants, and otherwise visits the file by calling find-file (see Functions for Visiting Files).

Function: x-dnd-save-direct-immediately need-name filename

This function works like x-dnd-save-direct, but when called with its need-name argument non-nil, it doesn’t prompt the user for the full name of the file to be saved; instead, it returns its argument filename expanded against the current buffer’s default directory (see Functions that Expand Filenames). (It still asks for confirmation if a file by that name already exists in the default directory.)

On capable window systems, Emacs also supports dragging contents from its frames to windows of other applications.

Function: dnd-begin-text-drag text &optional frame action allow-same-frame

This function begins dragging text from frame to another program (known as the drop target), and returns the result of drag-and-drop operation when the text is dropped or the drag-and-drop operation is canceled. text is the text that will be inserted by the drop target.

action must be one of the symbols copy or move, where copy means that text should be inserted by the drop target, and move means the same as copy, but in addition the caller may have to delete text from its source as explained below.

frame is the frame where the mouse is currently held down, or nil, which means to use the selected frame. This function may return immediately if no mouse buttons are held down, so it should be only called immediately after a down-mouse-1 or similar event (see Mouse Events), with frame set to the frame where that event was generated (see Click Events).

allow-same-frame specifies whether or not drops on top of frame itself are to be ignored.

The return value specifies the action that the drop target actually performed, and optionally what the caller should do. It can be one of the following symbols:

copy

The drop target inserted the dropped text.

move

The drop target inserted the dropped text, but in addition the caller should delete text from wherever it originated, such as its buffer.

private

The drop target performed some other unspecified action.

nil

The drag-and-drop operation was canceled.

Function: dnd-begin-file-drag file &optional frame action allow-same-frame

This function begins dragging file from frame to another program, and returns the result of the drag-and-drop operation when the file is dropped or the drag-and-drop operation is canceled.

If file is a remote file, then a temporary copy will be made.

action must be one of the symbols copy, move or link, where copy means that 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.

frame and allow-same-frame have the same meaning as in dnd-begin-text-drag.

The return value is the action that the drop target actually performed, which can be one of the following symbols:

copy

The drop target opened or copied file to a different location.

move

The drop target moved file to a different location.

link

The drop target (usually a file manager) created a symbolic link to file.

private

The drop target performed some other unspecified action.

nil

The drag-and-drop operation was canceled.

Function: dnd-begin-drag-files files &optional frame action allow-same-frame

This function is like dnd-begin-file-drag, except that files is a list of files. If the drop target doesn’t support dropping multiple files, then the first file will be used instead.

Function: dnd-direct-save file name &optional frame allow-same-frame

This function is similar to dnd-begin-file-drag (with the default action of copy), but instead of specifying the action you specify the name of the copy created by the target program in name.

The high-level interfaces described above are implemented on top of a lower-level primitive. If you need to drag content other than files or text, use the low-level interface x-begin-drag instead. However, using it will require detailed knowledge of the data types and actions used by the programs to transfer content via drag-and-drop on each platform you want to support.

Function: x-begin-drag targets &optional action frame return-frame allow-current-frame follow-tooltip

This function begins a drag from frame, and returns when the drag-and-drop operation ends, either because the drop was successful, or because the drop was rejected. The drop occurs when all mouse buttons are released on top of an X window other than frame (the drop target), or any X window if allow-current-frame is non-nil. If no mouse buttons are held down when the drag-and-drop operation begins, this function may immediately return nil.

targets is a list of strings describing selection targets, much like the data-type argument to gui-get-selection, that the drop target can request from Emacs (see Window System Selections).

action is a symbol describing the action recommended to the target. It can either be XdndActionCopy, which means to copy the contents of the selection XdndSelection to the drop target; or XdndActionMove, which means copy as with XdndActionCopy, and in addition the caller should delete whatever was stored in that selection after copying it.

action may also be an alist which associates between symbols describing the available actions, and strings that the drop target is expected to present to the user to choose between the available actions.

If return-frame is non-nil and the mouse moves over an Emacs frame after first moving out of frame, then the frame to which the mouse moves will be returned immediately. If return-frame is the symbol now, then any frame underneath the mouse pointer will be returned without waiting for the mouse to first move out of frame. return-frame is useful when you want to treat dragging content from one frame to another specially, while also being able to drag content to other programs, but it is not guaranteed to work on all systems and with all window managers.

If follow-tooltip is non-nil, the position of any tooltip (such as one shown by tooltip-show) will follow the location of the mouse pointer whenever it moves during the drag-and-drop operation. The tooltip will be hidden once all mouse buttons are released.

If the drop was rejected or no drop target was found, this function returns nil. Otherwise, it returns a symbol describing the action the target chose to perform, which can differ from action if that isn’t supported by the drop target. XdndActionPrivate is also a valid return value in addition to XdndActionCopy and XdndActionMove; it means that the drop target chose to perform an unspecified action, and no further processing is required by the caller.

The caller must cooperate with the target to fully perform the action chosen by the target. For example, callers should delete the buffer text that was dragged if this function returns XdndActionMove.

On X Windows, several different drag-and-drop protocols are supported by x-begin-drag. When dragging content that is known to not be supported by a specific drag-and-drop protocol, it might be desirable to turn that protocol off, by changing the values of the following variables:

Variable: x-dnd-disable-motif-protocol

When this is non-nil, the Motif drag and drop protocols are disabled, and dropping onto programs that only understand them will not work.

Variable: x-dnd-use-offix-drop

When this is nil, the OffiX (old KDE) drag and drop protocol is disabled. When this is the symbol files, the OffiX protocol will only be used if "FILE_NAME" is one of the targets given to x-begin-drag. Any other value means to use the OffiX protocol to drop all supported content.

Variable: x-dnd-use-unsupported-drop

When one of the "STRING", "UTF8_STRING", "COMPOUND_TEXT" or "TEXT" targets is present in the list given to x-begin-drag, Emacs will try to use synthesized mouse events and the primary selection to insert the text if the drop target doesn’t support any drag-and-drop protocol at all.

A side effect is that Emacs will become the owner of the primary selection upon such a drop. If that is not desired, then the drop emulation can be disabled by setting this variable to nil.