mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 22:28:24 +02:00
More work on the DnD protocol
This commit is contained in:
@@ -217,7 +217,6 @@ Detailed list of changes
|
|||||||
|
|
||||||
- Password input in kittens: hide the cursor and display 🔒 (U+1F512) at the end of typed characters to make it visually clear the user is entering a password
|
- Password input in kittens: hide the cursor and display 🔒 (U+1F512) at the end of typed characters to make it visually clear the user is entering a password
|
||||||
|
|
||||||
- DnD: Use non-blocking I/O when reading file chunks in ``drop_send_file_chunks()`` to avoid blocking the main event loop
|
|
||||||
|
|
||||||
0.46.2 [2026-03-21]
|
0.46.2 [2026-03-21]
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|||||||
@@ -186,6 +186,94 @@ the terminal. Terminals may deny directory traversal requests if too many
|
|||||||
resources are used, in order to prevent denial or service attacks. In such
|
resources are used, in order to prevent denial or service attacks. In such
|
||||||
cases the terminal must respond with ``ENOMEM``.
|
cases the terminal must respond with ``ENOMEM``.
|
||||||
|
|
||||||
|
Starting drags
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Terminal programs can inform the terminal emulator that they
|
||||||
|
are willing to act as a source of drag data by sending the
|
||||||
|
sending the escape code::
|
||||||
|
|
||||||
|
OSC _dnd_code ; t=o ST
|
||||||
|
|
||||||
|
On exit, or if the program no longer is willing to start drag gestures, it must
|
||||||
|
send ``t=O`` to the terminal to indicate it no longer wants to offer drag data.
|
||||||
|
|
||||||
|
When the user performs the platform specific gesture to start a drag operation,
|
||||||
|
the terminal will send the same escape code back to the terminal program
|
||||||
|
informing it that it can potentially start a drag. The gesture is typically holding the
|
||||||
|
left mouse button down and dragging a short distance, but this protocol does
|
||||||
|
not mandate any particular gesture to start drag operations. The terminal, when
|
||||||
|
sending the event will also set the ``x, y, X, Y`` keys to indicate the cell
|
||||||
|
and pixel locations in the window of the start drag event.
|
||||||
|
|
||||||
|
If the terminal program determines that it wants to start a drag at that
|
||||||
|
location, it must send the terminal the ``t=o:o=flags`` escape code again, but
|
||||||
|
with a payload consisting of the space separated MIME types it offers. The
|
||||||
|
``flags`` indicate what types of operations the client supports, ``1`` for
|
||||||
|
copy, ``2`` for move and ``3`` for either. Note that at this time the drag
|
||||||
|
operation has not actually started, this gives the terminal program the
|
||||||
|
opportunity to pre-send some data or set one or more images to act as
|
||||||
|
thumbnails for the drag operation.
|
||||||
|
|
||||||
|
If at the time the terminal receives this request the drag gesture has already
|
||||||
|
been terminated or the terminal otherwise determines that it is not appropriate
|
||||||
|
to start the drag, it must reply with ``t=R ; EPERM`` to indicate the drag
|
||||||
|
offer was not accepted.
|
||||||
|
|
||||||
|
For some well known types like ``text/plain`` or ``text/uri-list`` the
|
||||||
|
terminal program should pre-send the data for them unless it is very large.
|
||||||
|
This is because some platforms, such as macOS, need pre sent data to be able
|
||||||
|
to interoperate with native programs. The terminal emulator should reply with
|
||||||
|
``t=R ; EFBIG`` if too much data is sent and cancel the drag. Terminals must
|
||||||
|
accept at least 64MB of present data.
|
||||||
|
|
||||||
|
Pre sent data is sent with escape codes of the form::
|
||||||
|
|
||||||
|
OSC _dnd_code ; t=p:x=idx ; base64 encoded data ST
|
||||||
|
|
||||||
|
Here ``idx`` is the zero based index into the list of previously sent MIME
|
||||||
|
types indicating this data is for that MIME type. Transmission should be chunked
|
||||||
|
using the ``m`` key. End of data is indicated by sending the escape code with no
|
||||||
|
payload and ``m=0``. Terminal programs should pre-read this data and only send
|
||||||
|
the ``t=o`` key indicating the offer if the data is available.
|
||||||
|
|
||||||
|
To associate one or more images with the drag operation, the terminal program
|
||||||
|
must transmit the data for the image with the ``idx`` value above being a
|
||||||
|
negative number starting with ``-1`` for the first image and so on. When
|
||||||
|
transmitting images, the image data format is specified using the ``y`` key.
|
||||||
|
A value of ``y=24`` mean 24bit RGB data and ``y=32`` means 32bit RGBA data.
|
||||||
|
Colors in the RGB/A data must be in the sRGB color space.
|
||||||
|
Using ``y=100`` means the data is a PNG image. Additionally, the ``X`` and
|
||||||
|
``Y`` keys must be used to specify the width and height of the image data in
|
||||||
|
pixels. If the size of the transmitted data does not match the image dimensions
|
||||||
|
the terminal must replay with ``t=R ; EINVAL``. Terminals are free to impose a
|
||||||
|
limit on the amount of image data, too avoid Denial-of-service attacks. If the
|
||||||
|
image data is too much or the image is too large they must reply with ``t=R ;
|
||||||
|
EFBIG`` and abort the drag. By default, the drag will be started using the
|
||||||
|
first image, if any. During the drag, the terminal program can change the
|
||||||
|
image by sending::
|
||||||
|
|
||||||
|
OSC _dnd_code ; t=P:x=idx ST
|
||||||
|
|
||||||
|
Where ``idx`` is now a zero based index with zero being the first image and so on.
|
||||||
|
|
||||||
|
Once the terminal program has present all data and images for the drag
|
||||||
|
operation, it indicates the drag should be started by sending ``t=P:x=-1``. At
|
||||||
|
this time if the user has already cancelled the drag or the terminal determines
|
||||||
|
the drag operation is not allowed, it must respond with ``t=R ; EPERM``. If any
|
||||||
|
other error occurs starting the drag operation, it must respond with the appropriate
|
||||||
|
POSIX error code. If the drag operation is successfully started, it must respond with
|
||||||
|
``t=R ; OK``.
|
||||||
|
|
||||||
|
Multiplexers
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
To support multiplexers, the ``i`` key exists. When the terminal receives and
|
||||||
|
``t=a`` or ``t=o`` escape code that has the ``i`` key set, all escape codes it
|
||||||
|
sends to the terminal program must include the ``i`` key with the same value.
|
||||||
|
This allows terminal multiplexers to direct the response codes to the correct
|
||||||
|
client.
|
||||||
|
|
||||||
Metadata reference
|
Metadata reference
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
@@ -201,9 +289,13 @@ Key Value Default Description
|
|||||||
``m`` - a drop move event
|
``m`` - a drop move event
|
||||||
``M`` - a drop dropped event
|
``M`` - a drop dropped event
|
||||||
``r`` - request dropped data
|
``r`` - request dropped data
|
||||||
``R`` - report an error while retrieving data
|
``R`` - report an error to the terminal program
|
||||||
``s`` - request data from the URI list entry
|
``s`` - request data from the URI list entry
|
||||||
``d`` - send directory contents
|
``d`` - send directory contents
|
||||||
|
``o`` - start offering drags
|
||||||
|
``O`` - stop offering drags
|
||||||
|
``p`` - present data for drag offers
|
||||||
|
``P`` - Change drag image or start drag
|
||||||
|
|
||||||
``m`` Chunking indicator ``0`` ``0`` or ``i``
|
``m`` Chunking indicator ``0`` ``0`` or ``i``
|
||||||
|
|
||||||
@@ -224,3 +316,5 @@ Key Value Default Description
|
|||||||
``Y`` Integer ``0`` Pixel y-coordinate origin is 0, 0 at top left of screen
|
``Y`` Integer ``0`` Pixel y-coordinate origin is 0, 0 at top left of screen
|
||||||
======= ==================== ========= =================
|
======= ==================== ========= =================
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -331,7 +331,7 @@ def parsers() -> None:
|
|||||||
write_header(text, 'kitty/parse-multicell-command.h')
|
write_header(text, 'kitty/parse-multicell-command.h')
|
||||||
|
|
||||||
keymap = {
|
keymap = {
|
||||||
't': ('type', flag('aAmMrRsd')),
|
't': ('type', flag('aAmMrRsdoOpP')),
|
||||||
'm': ('more', 'uint'),
|
'm': ('more', 'uint'),
|
||||||
'i': ('client_id', 'uint'),
|
'i': ('client_id', 'uint'),
|
||||||
'o': ('operation', 'uint'),
|
'o': ('operation', 'uint'),
|
||||||
|
|||||||
@@ -86,8 +86,9 @@ static inline void parse_dnd_code(PS *self, uint8_t *parser_buf,
|
|||||||
|
|
||||||
case type: {
|
case type: {
|
||||||
g.type = parser_buf[pos++];
|
g.type = parser_buf[pos++];
|
||||||
if (g.type != 'A' && g.type != 'M' && g.type != 'R' && g.type != 'a' &&
|
if (g.type != 'A' && g.type != 'M' && g.type != 'O' && g.type != 'P' &&
|
||||||
g.type != 'd' && g.type != 'm' && g.type != 'r' && g.type != 's') {
|
g.type != 'R' && g.type != 'a' && g.type != 'd' && g.type != 'm' &&
|
||||||
|
g.type != 'o' && g.type != 'p' && g.type != 'r' && g.type != 's') {
|
||||||
REPORT_ERROR("Malformed DnDCommand control block, unknown flag value "
|
REPORT_ERROR("Malformed DnDCommand control block, unknown flag value "
|
||||||
"for type: 0x%x",
|
"for type: 0x%x",
|
||||||
g.type);
|
g.type);
|
||||||
|
|||||||
Reference in New Issue
Block a user