mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 14:18:26 +02:00
Add a request id for DnD protocol data requests
Allows multiple in-flight requests. Needs implementation.
This commit is contained in:
@@ -104,17 +104,17 @@ it is interested in.
|
|||||||
|
|
||||||
Requesting data is done by sending an escape code of the form::
|
Requesting data is done by sending an escape code of the form::
|
||||||
|
|
||||||
OSC _dnd_code ; t=r ; MIME type ST
|
OSC _dnd_code ; t=r:r=request_id ; MIME type ST
|
||||||
|
|
||||||
This will request data for the specified MIME type. The terminal must respond
|
This will request data for the specified MIME type. The terminal must respond
|
||||||
with a series of escape codes of the form::
|
with a series of escape codes of the form::
|
||||||
|
|
||||||
OSC _dnd_code ; t=r ; base64 encoded data ST
|
OSC _dnd_code ; t=r:r=request_id ; base64 encoded data ST
|
||||||
|
|
||||||
End of data is indicated by an empty payload. If some error occurs while
|
End of data is indicated by an empty payload. If some error occurs while
|
||||||
getting the data, the terminal must send an escape code of the form::
|
getting the data, the terminal must send an escape code of the form::
|
||||||
|
|
||||||
OSC _dnd_code ; t=R ; POSIX error name ST
|
OSC _dnd_code ; t=R:r=request_id ; POSIX error name ST
|
||||||
|
|
||||||
Here POSIX error name is a POSIX symbolic error name such as ``ENOENT`` or
|
Here POSIX error name is a POSIX symbolic error name such as ``ENOENT`` or
|
||||||
``EIO`` or the value ``EUNKNOWN`` for an unknown error. Note that if a client
|
``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
|
|||||||
type to get a list of dropped URIs. For every URI in the list, they can
|
type to get a list of dropped URIs. For every URI in the list, they can
|
||||||
send the terminal emulator a data request of the form::
|
send the terminal emulator a data request of the form::
|
||||||
|
|
||||||
OSC _dnd_code ; t=s ; text/uri-list:idx ST
|
OSC _dnd_code ; t=s:r=request_id ; text/uri-list:idx ST
|
||||||
|
|
||||||
Here ``idx`` is the zero based index into the array of MIME types in
|
Here ``idx`` is the zero based index into the array of MIME types in
|
||||||
the ``text/uri-list`` entry. The terminal will then read the file and
|
the ``text/uri-list`` entry. The terminal will then read the file and
|
||||||
transmit the data as for a normal MIME data request.
|
transmit the data as for a normal MIME data request.
|
||||||
|
|
||||||
Terminals must reply with ``t=R ; ENOENT`` if the index is out of bounds.
|
Terminals must reply with ``t=R:r=request_id ; ENOENT`` if the index is out of bounds.
|
||||||
If the client does not first request the ``text/uri-list`` MIME type or that
|
If the client does not first request the ``text/uri-list`` MIME type or that
|
||||||
MIME type is not present in the drop, the terminal must reply with
|
MIME type is not present in the drop, the terminal must reply with
|
||||||
``t=R ; EINVAL``. Terminals must support at least ``file://`` URIs.
|
``t=R:r=request_id ; EINVAL``. Terminals must support at least ``file://`` URIs.
|
||||||
If the client requests an entry that is not a supported URI type the
|
If the client requests an entry that is not a supported URI type the
|
||||||
terminal must reply with ``t=R ; EUNKNOWN``.
|
terminal must reply with ``t=R:r=request_id ; EUNKNOWN``.
|
||||||
|
|
||||||
Terminals must ONLY send data for regular files. Symbolic links must be
|
Terminals must ONLY send data for regular files. Symbolic links must be
|
||||||
resolved and the corresponding file read. If the terminal does not have
|
resolved and the corresponding file read. If the terminal does not have
|
||||||
permission to read the file it must reply with ``t=R ; EPERM``. Terminals
|
permission to read the file it must reply with ``t=R:r=request_id ; EPERM``. Terminals
|
||||||
must respond with ``t=R ; EINVAL`` if the file is not a regular file after
|
must respond with ``t=R:r=request_id ; EINVAL`` if the file is not a regular file after
|
||||||
resolving symlinks and ``t=R ; ENOENT`` if the file does not exist. If an
|
resolving symlinks and ``t=R:r=request_id ; ENOENT`` if the file does not exist. If an
|
||||||
I/O error occurs the terminal must send ``t=R ; EIO``.
|
I/O error occurs the terminal must send ``t=R:r=request_id ; EIO``.
|
||||||
|
|
||||||
For security reasons, terminals must reply with ``t=R ; EPERM`` if the drag
|
For security reasons, terminals must reply with ``t=R:r=request_id ; EPERM`` if the drag
|
||||||
originated in the same window as the drop, this prevents malicious programs
|
originated in the same window as the drop, this prevents malicious programs
|
||||||
from reading files on the computer by starting their own drag. This is a
|
from reading files on the computer by starting their own drag. This is a
|
||||||
defense in depth feature since drags can only be started by the terminal, but
|
defense in depth feature since drags can only be started by the terminal, but
|
||||||
it helps in case of accidental drag starts and drops into the same window.
|
it helps in case of accidental drag starts and drops into the same window.
|
||||||
|
|
||||||
|
Terminals may queue requests with different ids and respond in order, or they
|
||||||
|
may respond in any order. If too many requests are received, they must deny
|
||||||
|
the request with ``t:R:r=request_id ; EMFILE`` and end the drop.
|
||||||
|
|
||||||
|
|
||||||
Reading remote directories
|
Reading remote directories
|
||||||
+++++++++++++++++++++++++++
|
+++++++++++++++++++++++++++
|
||||||
|
|
||||||
If the file is actually a directory the terminal must respond with ``t=d:x=idx ; payload``.
|
If the file is actually a directory the terminal must respond with ``t=d:x=idx:r=request_id ; payload``.
|
||||||
Here payload is a null byte separated list of entries in the directory that are
|
Here payload is a null byte separated list of entries in the directory that are
|
||||||
either regular files, directories or symlinks. The payload must be base64
|
either regular files, directories or symlinks. The payload must be base64
|
||||||
encoded and might be chunked if the directory has a lot of entries. The first
|
encoded and might be chunked if the directory has a lot of entries. The first
|
||||||
@@ -180,10 +184,10 @@ number.
|
|||||||
|
|
||||||
``idx`` is an arbitrary 32 bit integer that acts as a handle to this
|
``idx`` is an arbitrary 32 bit integer that acts as a handle to this
|
||||||
directory. The client can now read the files in this directory using requests of the form
|
directory. The client can now read the files in this directory using requests of the form
|
||||||
``t=d:x=idx:y=num``, here ``num`` is the index into the list of
|
``t=d:x=idx:y=num:r=request_id``, here ``num`` is the index into the list of
|
||||||
directory entries previously transmitted to the client. Here, ``1`` will
|
directory entries previously transmitted to the client. Here, ``1`` will
|
||||||
correspond to the first entry in the directory. Once the client is done
|
correspond to the first entry in the directory. Once the client is done
|
||||||
reading a directory it should transmit ``t=d:x=idx`` to the terminal. The
|
reading a directory it should transmit ``t=d:x=idx:r=request_id`` to the terminal. The
|
||||||
terminal can then free any resources associated with that directory. The
|
terminal can then free any resources associated with that directory. The
|
||||||
directory handle is now invalid and terminals must return ``EINVAL`` if the
|
directory handle is now invalid and terminals must return ``EINVAL`` if the
|
||||||
client sends a request using and invalid directory handle. It is recommended
|
client sends a request using and invalid directory handle. It is recommended
|
||||||
@@ -352,7 +356,7 @@ Key Value Default Description
|
|||||||
``P`` - Change drag image or start drag
|
``P`` - Change drag image or start drag
|
||||||
``e`` - a drag offer event occurred
|
``e`` - a drag offer event occurred
|
||||||
|
|
||||||
``m`` Chunking indicator ``0`` ``0`` or ``i``
|
``m`` Chunking indicator ``0`` ``0`` or ``1``
|
||||||
|
|
||||||
``i`` Postive integer ``0`` This id is for use by multiplexers.
|
``i`` Postive integer ``0`` This id is for use by multiplexers.
|
||||||
When it is set, all responses from
|
When it is set, all responses from
|
||||||
@@ -363,6 +367,8 @@ Key Value Default Description
|
|||||||
means rejected, ``1`` means copy and
|
means rejected, ``1`` means copy and
|
||||||
``2`` means move.
|
``2`` means move.
|
||||||
|
|
||||||
|
``r`` Positive integer ``0`` The request id
|
||||||
|
|
||||||
**Keys for location**
|
**Keys for location**
|
||||||
-----------------------------------------------------------
|
-----------------------------------------------------------
|
||||||
``x`` Integer ``0`` Cell x-coordinate origin is 0, 0 at top left of screen
|
``x`` Integer ``0`` Cell x-coordinate origin is 0, 0 at top left of screen
|
||||||
|
|||||||
@@ -335,6 +335,7 @@ def parsers() -> None:
|
|||||||
'm': ('more', 'uint'),
|
'm': ('more', 'uint'),
|
||||||
'i': ('client_id', 'uint'),
|
'i': ('client_id', 'uint'),
|
||||||
'o': ('operation', 'uint'),
|
'o': ('operation', 'uint'),
|
||||||
|
'r': ('request_id', 'uint'),
|
||||||
'x': ('cell_x', 'int'),
|
'x': ('cell_x', 'int'),
|
||||||
'y': ('cell_y', 'int'),
|
'y': ('cell_y', 'int'),
|
||||||
'X': ('pixel_x', 'int'),
|
'X': ('pixel_x', 'int'),
|
||||||
|
|||||||
@@ -392,6 +392,7 @@ get_errno_name(int err) {
|
|||||||
case ENOENT: return "ENOENT";
|
case ENOENT: return "ENOENT";
|
||||||
case EIO: return "EIO";
|
case EIO: return "EIO";
|
||||||
case EINVAL: return "EINVAL";
|
case EINVAL: return "EINVAL";
|
||||||
|
case EMFILE: return "EMFILE";
|
||||||
case ENOMEM: return "ENOMEM";
|
case ENOMEM: return "ENOMEM";
|
||||||
case 0: return "OK";
|
case 0: return "OK";
|
||||||
default: return "EUNKNOWN";
|
default: return "EUNKNOWN";
|
||||||
@@ -1195,6 +1196,7 @@ parse_errno_name(const uint8_t *data, size_t sz) {
|
|||||||
if (sz >= 6 && memcmp(data, "ENOMEM", 6) == 0) return ENOMEM;
|
if (sz >= 6 && memcmp(data, "ENOMEM", 6) == 0) return ENOMEM;
|
||||||
if (sz >= 5 && memcmp(data, "EFBIG", 5) == 0) return EFBIG;
|
if (sz >= 5 && memcmp(data, "EFBIG", 5) == 0) return EFBIG;
|
||||||
if (sz >= 3 && memcmp(data, "EIO", 3) == 0) return EIO;
|
if (sz >= 3 && memcmp(data, "EIO", 3) == 0) return EIO;
|
||||||
|
if (sz >= 6 && memcmp(data, "EMFILE", 6) == 0) return EMFILE;
|
||||||
return EIO;
|
return EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ static inline void parse_dnd_code(PS *self, uint8_t *parser_buf,
|
|||||||
more = 'm',
|
more = 'm',
|
||||||
client_id = 'i',
|
client_id = 'i',
|
||||||
operation = 'o',
|
operation = 'o',
|
||||||
|
request_id = 'r',
|
||||||
cell_x = 'x',
|
cell_x = 'x',
|
||||||
cell_y = 'y',
|
cell_y = 'y',
|
||||||
pixel_x = 'X',
|
pixel_x = 'X',
|
||||||
@@ -51,6 +52,9 @@ static inline void parse_dnd_code(PS *self, uint8_t *parser_buf,
|
|||||||
case operation:
|
case operation:
|
||||||
value_state = UINT;
|
value_state = UINT;
|
||||||
break;
|
break;
|
||||||
|
case request_id:
|
||||||
|
value_state = UINT;
|
||||||
|
break;
|
||||||
case cell_x:
|
case cell_x:
|
||||||
value_state = INT;
|
value_state = INT;
|
||||||
break;
|
break;
|
||||||
@@ -156,6 +160,7 @@ static inline void parse_dnd_code(PS *self, uint8_t *parser_buf,
|
|||||||
U(more);
|
U(more);
|
||||||
U(client_id);
|
U(client_id);
|
||||||
U(operation);
|
U(operation);
|
||||||
|
U(request_id);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -207,12 +212,13 @@ static inline void parse_dnd_code(PS *self, uint8_t *parser_buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
REPORT_VA_COMMAND(
|
REPORT_VA_COMMAND(
|
||||||
"K s {sc sI sI sI si si si si ss#}", self->window_id, "dnd_command",
|
"K s {sc sI sI sI sI si si si si ss#}", self->window_id, "dnd_command",
|
||||||
|
|
||||||
"type", g.type,
|
"type", g.type,
|
||||||
|
|
||||||
"more", (unsigned int)g.more, "client_id", (unsigned int)g.client_id,
|
"more", (unsigned int)g.more, "client_id", (unsigned int)g.client_id,
|
||||||
"operation", (unsigned int)g.operation,
|
"operation", (unsigned int)g.operation, "request_id",
|
||||||
|
(unsigned int)g.request_id,
|
||||||
|
|
||||||
"cell_x", (int)g.cell_x, "cell_y", (int)g.cell_y, "pixel_x",
|
"cell_x", (int)g.cell_x, "cell_y", (int)g.cell_y, "pixel_x",
|
||||||
(int)g.pixel_x, "pixel_y", (int)g.pixel_y,
|
(int)g.pixel_x, "pixel_y", (int)g.pixel_y,
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ typedef enum ScrollTypes { SCROLL_LINE = -999999, SCROLL_PAGE, SCROLL_FULL } Scr
|
|||||||
typedef struct DnDCommand {
|
typedef struct DnDCommand {
|
||||||
char type;
|
char type;
|
||||||
unsigned more;
|
unsigned more;
|
||||||
uint32_t client_id;
|
uint32_t client_id, request_id;
|
||||||
size_t payload_sz;
|
size_t payload_sz;
|
||||||
int32_t cell_x, cell_y, pixel_x, pixel_y;
|
int32_t cell_x, cell_y, pixel_x, pixel_y;
|
||||||
uint32_t operation;
|
uint32_t operation;
|
||||||
|
|||||||
Reference in New Issue
Block a user