# Drag and Drop (OSC 72)

> Let a program in the terminal accept dropped files and text, and start drags of its own: kitty's drag and drop protocol.

- **Sequence:** `OSC 72 ; metadata ; payload ST`
- **ECMA-48:** [§8.3.89 OSC – Operating System Command, p. 51](https://archive.org/details/ecma-48-5th-edition-june-1991/page/n64/mode/1up)
- **Specification:** [The Drag and Drop protocol, kitty documentation](https://sw.kovidgoyal.net/kitty/dnd-protocol/)

`OSC 72 ; metadata ; payload ST` lets a program in the terminal take part in
drag and drop as a graphical program would: accept files or text dropped on
it, by MIME type, and start drags of its own. Its definition is kitty's
[Drag and Drop protocol](https://sw.kovidgoyal.net/kitty/dnd-protocol/).
The metadata is `key=value` pairs separated by `:`, the `t` key says which
message it is, and a payload over 4096 bytes is sent in chunks marked `m=1`.
Some of the messages:

| Sequence | Does |
| --- | --- |
| `OSC 72 ; t=a ; types ST` | accept drops of these MIME types, a space-separated list |
| `OSC 72 ; t=A ST` | stop accepting drops |
| `OSC 72 ; t=q ST` | ask whether the terminal has the protocol |

A terminal that has it answers `t=q` with `OSC 72 ; t=q ; payload ST`, where
the payload lists optional parts it supports, empty for now, and echoes an
`i=` key if the question had one; a program sends the question and then
[DA](https://control-codes.page/csi/da/index.html.md), and takes an answer to DA alone as a no.

A default xterm does not have it and ignores it
([the OSC numbers it knows](https://github.com/ThomasDickey/xterm-snapshots/blob/xterm-411a/misc.c#L3476-L3504)).
The cases follow xterm. libghostty-vt implements the protocol, passing
drags and drops to its host through the `drag_and_drop` callback, and
answers `t=q` itself, so that case is a known difference. It answers only a
bare `t=q`, though: a question with `i=` goes unanswered, which kitty's
document says should be answered with the `i` echoed.

## Validation

### OSC72-1: The question is not answered

*A known difference: libghostty-vt does not pass this case.*

Input, one step per line:

```text
\e]72;t=q\e\\
```

Expected screen:

```text
|______|
reply none
```

### OSC72-2: Accepting drops changes nothing on screen

Input, one step per line:

```text
A
\e]72;t=a;dGV4dC9wbGFpbg==\e\\  # text/plain
B
```

Expected screen:

```text
|AB____|
cursor 1,3
reply none
```

---

This is the Markdown version of <https://control-codes.page/osc/dnd/>. On that page every validation case runs live in libghostty-vt, the terminal emulation core of Ghostty, compiled to WebAssembly.

The validation cases are written in the notation described in <https://control-codes.page/notation/index.html.md>.
