Next: , Previous: , Up: Frames   [Contents][Index]

30.24 Drag and Drop

Data transferred by drag and drop is generally either plain text or a list of URLs designating files or other resources. When text is dropped, it is inserted at the location of the drop, with recourse to saving it into the kill ring if that is not possible.

URLs dropped are supplied to pertinent DND handler functions in the variable dnd-protocol-alist, or alternatively “URL handlers” as set forth by the variables browse-url-handlers and browse-url-default-handlers; absent matching handlers of either type, they are treated as plain text and inserted in the buffer.

Variable: dnd-protocol-alist

This variable is an alist between regexps against which URLs are matched and DND handler functions called on the dropping of matching URLs.

If a handler function is a symbol whose dnd-multiple-handler property (see Symbol Properties) is set, then upon a drop it is given a list of every URL that matches its regexp; absent this property, it is called once for each of those URLs. Following this first argument is one of the symbols copy, move, link, private or ask identifying the action to be taken.

If action is private, the program that initiated the drop does not insist on any particular behavior on the part of its recipient; a reasonable action to take in that case is to open the URL or copy its contents into the current buffer. The other values of action imply much the same as in the action argument to dnd-begin-file-drag.

Once its work completes, a handler function must return a symbol designating the action it took: either the action it was provided, or the symbol private, which communicates to the source of the drop that the action it prescribed has not been executed.

When multiple handlers match an overlapping subset of items within a drop, the handler matched against by the greatest number of items is called to open that subset. The items it is supplied are subsequently withheld from other handlers, even those they also match.

Emacs does not take measures to accept data besides text and URLs, for the window system interfaces which enable this are too far removed from each other to abstract over consistently. Nor are DND handlers accorded influence over the actions they are meant to take, as particular drag-and-drop protocols deny recipients such control. The X11 drag-and-drop implementation rests on several underlying protocols that make use of selection transfer and share much in common, to which low level access is provided through the following functions and variables:

Variable: x-dnd-test-function

This function is called to ascertain whether Emacs should accept a drop. It is called with three arguments:

  • The window under the item being dragged, which is to say the window whose buffer is to receive the drop. If the item is situated over a non-window component of a frame (such as scroll bars, tool bars and things to that effect), the frame itself is provided in its place.
  • One of the symbols move, copy, link or ask, representing an action to take on the item data suggested by the drop source. These symbols carry the same implications as in x-begin-drag.
  • A vector of selection data types (see X Selections) the item provides.

This function must return nil to reject the drop or a cons of the action that will be taken (such as through transfer to a DND handler function) and the selection data type to be requested. The action returned in that cons may also be the symbol private, which intimates that the action taken is as yet indeterminate.

Variable: x-dnd-known-types

Modifying x-dnd-test-function is generally unwarranted, for its default set of criteria for accepting a drop can be adjusted by changing this list of selection data types. Each element is a string, which if found as the symbol name of an element within the list of data types by the default “test function”, will induce that function to accept the drop.

Introducing a new entry into this list is not useful unless a counterpart handler function is appended to x-dnd-types-alist.

Variable: x-dnd-types-alist

This variable is an alist between strings designating selection data types and functions which are called when things of such types are dropped.

Each such function is supplied three arguments; the first is the window or frame below the location of the drop, as in x-dnd-test-function; the second is the action to be taken, which may be any of the actions returned by test functions, and third is the selection data itself (see Accessing Selections).

Selection data types as provided by X11 drag-and-drop protocols are sometimes distinct from those provided by the ICCCM and conforming clipboard or primary selection owners. Frequently, the name of a MIME type, such as "text/plain;charset=utf-8" (with discrepant capitalization of the “utf-8”), is substituted for a standard X selection name such as UTF8_STRING.

The X Direct Save (XDS) protocol enables programs to devolve responsibility for naming a dropped file upon the recipient. When such a drop transpires, DND handlers and the foregoing X-specific interface are largely circumvented, tasking a different function with responding to the drop.

Variable: x-dnd-direct-save-function

This variable should be set to a function that registers and names files dropped using the XDS protocol in a two-step procedure. It is provided two arguments, need-name and filename.

  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.

Its default 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.)

It is also possible to drag content from Emacs to other programs when this is supported by the current window-system. The functions which provide for this are as follows:

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

This function starts a drag-and-drop operation from frame to another program (dubbed the drop target), and returns when text is dropped or the operation is canceled.

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 the caller must also delete text from its source as explained in the list below.

frame is the frame where the mouse is currently held down, or nil, which means to use the selected frame. Since this function might return promptly if no mouse buttons are held down, it should be only called in response to a down-mouse-1 or analogous event (see Mouse Events), with frame set to the frame where that event was generated (see Click Events).

If allow-same-frame is nil, drops on top of frame will be ignored.

The return value reflects the action that the drop target actually performed, and thus also what action, if any, the caller should in turn take. It is one of the following symbols:

copy

The drop target inserted the dropped text.

move

The drop target inserted the dropped text, and the caller should delete text from the buffer where it was extracted from, if applicable.

private

The drop target took 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 starts a drag-and-drop operation from frame to another program (dubbed the drop target), and returns when file is dropped or the operation is canceled.

If file is a remote file, then a temporary local 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 mean the same as they do in calls to dnd-begin-text-drag.

The return value is the action that the drop target actually performed, which is 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

The behavior of this function is akin to that of dnd-begin-file-drag (when the default action copy is used), except that it accepts a name under which the copy is meant to be filed.

The high-level interfaces described above are implemented on top of a lower-level primitive. The low-level interface x-begin-drag is also available for dragging content besides text and files. It demands detailed knowledge of the data types and actions understood by programs on each platform its callers wish 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 representing 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 designating the action recommended to the target. It can either be XdndActionCopy or XdndActionMove; both imply copying the contents of the selection XdndSelection to the drop target, but the latter moreover conveys a promise to delete the contents of the selection after the copying.

action may also be an alist which associates between symbols representing available actions, and strings that the drop target presents to the user for him to select between those 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 beneath 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 dragging content to other programs, but it is not guaranteed to function on all systems and with all window managers.

If follow-tooltip is non-nil, the position of any tooltip (such as one displayed by tooltip-show) will follow the location of the mouse pointer as 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 representing the action the target opted to take, 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 suggests that the drop target opted for an indeterminate action, and no further action is required of the caller.

The caller must cooperate with the target to complete the action selected by the target. For example, callers should delete any buffer text that was dragged if this function returns XdndActionMove, and likewise for other drag data where comparable criteria apply.

The function x-begin-drag leverages several drag-and-drop protocols “behind the scenes”. When dragging content that is known to not be supported by a specific drag-and-drop protocol, that protocol can be disabled 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. Such emulation can be disabled by setting this variable to nil.

Next: Color Names, Previous: Yanking Media, Up: Frames   [Contents][Index]