Skip to content

Commit 71fcc7e

Browse files
committed
Add a request id for DnD protocol data requests
Allows multiple in-flight requests. Needs implementation.
1 parent 70e4e93 commit 71fcc7e

5 files changed

Lines changed: 34 additions & 19 deletions

File tree

docs/dnd-protocol.rst

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,17 @@ it is interested in.
104104

105105
Requesting data is done by sending an escape code of the form::
106106

107-
OSC _dnd_code ; t=r ; MIME type ST
107+
OSC _dnd_code ; t=r:r=request_id ; MIME type ST
108108

109109
This will request data for the specified MIME type. The terminal must respond
110110
with a series of escape codes of the form::
111111

112-
OSC _dnd_code ; t=r ; base64 encoded data ST
112+
OSC _dnd_code ; t=r:r=request_id ; base64 encoded data ST
113113

114114
End of data is indicated by an empty payload. If some error occurs while
115115
getting the data, the terminal must send an escape code of the form::
116116

117-
OSC _dnd_code ; t=R ; POSIX error name ST
117+
OSC _dnd_code ; t=R:r=request_id ; POSIX error name ST
118118

119119
Here POSIX error name is a POSIX symbolic error name such as ``ENOENT`` or
120120
``EIO`` or the value ``EUNKNOWN`` for an unknown error. Note that if a client
@@ -138,37 +138,41 @@ clients can first request the :rfc:`text/uri-list <2483>` MIME
138138
type to get a list of dropped URIs. For every URI in the list, they can
139139
send the terminal emulator a data request of the form::
140140

141-
OSC _dnd_code ; t=s ; text/uri-list:idx ST
141+
OSC _dnd_code ; t=s:r=request_id ; text/uri-list:idx ST
142142

143143
Here ``idx`` is the zero based index into the array of MIME types in
144144
the ``text/uri-list`` entry. The terminal will then read the file and
145145
transmit the data as for a normal MIME data request.
146146

147-
Terminals must reply with ``t=R ; ENOENT`` if the index is out of bounds.
147+
Terminals must reply with ``t=R:r=request_id ; ENOENT`` if the index is out of bounds.
148148
If the client does not first request the ``text/uri-list`` MIME type or that
149149
MIME type is not present in the drop, the terminal must reply with
150-
``t=R ; EINVAL``. Terminals must support at least ``file://`` URIs.
150+
``t=R:r=request_id ; EINVAL``. Terminals must support at least ``file://`` URIs.
151151
If the client requests an entry that is not a supported URI type the
152-
terminal must reply with ``t=R ; EUNKNOWN``.
152+
terminal must reply with ``t=R:r=request_id ; EUNKNOWN``.
153153

154154
Terminals must ONLY send data for regular files. Symbolic links must be
155155
resolved and the corresponding file read. If the terminal does not have
156-
permission to read the file it must reply with ``t=R ; EPERM``. Terminals
157-
must respond with ``t=R ; EINVAL`` if the file is not a regular file after
158-
resolving symlinks and ``t=R ; ENOENT`` if the file does not exist. If an
159-
I/O error occurs the terminal must send ``t=R ; EIO``.
156+
permission to read the file it must reply with ``t=R:r=request_id ; EPERM``. Terminals
157+
must respond with ``t=R:r=request_id ; EINVAL`` if the file is not a regular file after
158+
resolving symlinks and ``t=R:r=request_id ; ENOENT`` if the file does not exist. If an
159+
I/O error occurs the terminal must send ``t=R:r=request_id ; EIO``.
160160

161-
For security reasons, terminals must reply with ``t=R ; EPERM`` if the drag
161+
For security reasons, terminals must reply with ``t=R:r=request_id ; EPERM`` if the drag
162162
originated in the same window as the drop, this prevents malicious programs
163163
from reading files on the computer by starting their own drag. This is a
164164
defense in depth feature since drags can only be started by the terminal, but
165165
it helps in case of accidental drag starts and drops into the same window.
166166

167+
Terminals may queue requests with different ids and respond in order, or they
168+
may respond in any order. If too many requests are received, they must deny
169+
the request with ``t:R:r=request_id ; EMFILE`` and end the drop.
170+
167171

168172
Reading remote directories
169173
+++++++++++++++++++++++++++
170174

171-
If the file is actually a directory the terminal must respond with ``t=d:x=idx ; payload``.
175+
If the file is actually a directory the terminal must respond with ``t=d:x=idx:r=request_id ; payload``.
172176
Here payload is a null byte separated list of entries in the directory that are
173177
either regular files, directories or symlinks. The payload must be base64
174178
encoded and might be chunked if the directory has a lot of entries. The first
@@ -180,10 +184,10 @@ number.
180184

181185
``idx`` is an arbitrary 32 bit integer that acts as a handle to this
182186
directory. The client can now read the files in this directory using requests of the form
183-
``t=d:x=idx:y=num``, here ``num`` is the index into the list of
187+
``t=d:x=idx:y=num:r=request_id``, here ``num`` is the index into the list of
184188
directory entries previously transmitted to the client. Here, ``1`` will
185189
correspond to the first entry in the directory. Once the client is done
186-
reading a directory it should transmit ``t=d:x=idx`` to the terminal. The
190+
reading a directory it should transmit ``t=d:x=idx:r=request_id`` to the terminal. The
187191
terminal can then free any resources associated with that directory. The
188192
directory handle is now invalid and terminals must return ``EINVAL`` if the
189193
client sends a request using and invalid directory handle. It is recommended
@@ -352,7 +356,7 @@ Key Value Default Description
352356
``P`` - Change drag image or start drag
353357
``e`` - a drag offer event occurred
354358

355-
``m`` Chunking indicator ``0`` ``0`` or ``i``
359+
``m`` Chunking indicator ``0`` ``0`` or ``1``
356360

357361
``i`` Postive integer ``0`` This id is for use by multiplexers.
358362
When it is set, all responses from
@@ -363,6 +367,8 @@ Key Value Default Description
363367
means rejected, ``1`` means copy and
364368
``2`` means move.
365369

370+
``r`` Positive integer ``0`` The request id
371+
366372
**Keys for location**
367373
-----------------------------------------------------------
368374
``x`` Integer ``0`` Cell x-coordinate origin is 0, 0 at top left of screen

gen/apc_parsers.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,7 @@ def parsers() -> None:
335335
'm': ('more', 'uint'),
336336
'i': ('client_id', 'uint'),
337337
'o': ('operation', 'uint'),
338+
'r': ('request_id', 'uint'),
338339
'x': ('cell_x', 'int'),
339340
'y': ('cell_y', 'int'),
340341
'X': ('pixel_x', 'int'),

kitty/dnd.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ get_errno_name(int err) {
392392
case ENOENT: return "ENOENT";
393393
case EIO: return "EIO";
394394
case EINVAL: return "EINVAL";
395+
case EMFILE: return "EMFILE";
395396
case ENOMEM: return "ENOMEM";
396397
case 0: return "OK";
397398
default: return "EUNKNOWN";
@@ -1195,6 +1196,7 @@ parse_errno_name(const uint8_t *data, size_t sz) {
11951196
if (sz >= 6 && memcmp(data, "ENOMEM", 6) == 0) return ENOMEM;
11961197
if (sz >= 5 && memcmp(data, "EFBIG", 5) == 0) return EFBIG;
11971198
if (sz >= 3 && memcmp(data, "EIO", 3) == 0) return EIO;
1199+
if (sz >= 6 && memcmp(data, "EMFILE", 6) == 0) return EMFILE;
11981200
return EIO;
11991201
}
12001202

kitty/parse-dnd-command.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ static inline void parse_dnd_code(PS *self, uint8_t *parser_buf,
2323
more = 'm',
2424
client_id = 'i',
2525
operation = 'o',
26+
request_id = 'r',
2627
cell_x = 'x',
2728
cell_y = 'y',
2829
pixel_x = 'X',
@@ -51,6 +52,9 @@ static inline void parse_dnd_code(PS *self, uint8_t *parser_buf,
5152
case operation:
5253
value_state = UINT;
5354
break;
55+
case request_id:
56+
value_state = UINT;
57+
break;
5458
case cell_x:
5559
value_state = INT;
5660
break;
@@ -156,6 +160,7 @@ static inline void parse_dnd_code(PS *self, uint8_t *parser_buf,
156160
U(more);
157161
U(client_id);
158162
U(operation);
163+
U(request_id);
159164
default:
160165
break;
161166
}
@@ -207,12 +212,13 @@ static inline void parse_dnd_code(PS *self, uint8_t *parser_buf,
207212
}
208213

209214
REPORT_VA_COMMAND(
210-
"K s {sc sI sI sI si si si si ss#}", self->window_id, "dnd_command",
215+
"K s {sc sI sI sI sI si si si si ss#}", self->window_id, "dnd_command",
211216

212217
"type", g.type,
213218

214219
"more", (unsigned int)g.more, "client_id", (unsigned int)g.client_id,
215-
"operation", (unsigned int)g.operation,
220+
"operation", (unsigned int)g.operation, "request_id",
221+
(unsigned int)g.request_id,
216222

217223
"cell_x", (int)g.cell_x, "cell_y", (int)g.cell_y, "pixel_x",
218224
(int)g.pixel_x, "pixel_y", (int)g.pixel_y,

kitty/screen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ typedef enum ScrollTypes { SCROLL_LINE = -999999, SCROLL_PAGE, SCROLL_FULL } Scr
1717
typedef struct DnDCommand {
1818
char type;
1919
unsigned more;
20-
uint32_t client_id;
20+
uint32_t client_id, request_id;
2121
size_t payload_sz;
2222
int32_t cell_x, cell_y, pixel_x, pixel_y;
2323
uint32_t operation;

0 commit comments

Comments
 (0)