mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-07-03 11:12:30 +08:00
Implement finishing of drops
This commit is contained in:
@@ -113,7 +113,18 @@ getting the data, the terminal must send an escape code of the form::
|
||||
OSC _dnd_code ; t=R ; POSIX error name ST
|
||||
|
||||
Here POSIX error name is a POSIX symbolic error name such as ``ENOENT`` or
|
||||
``EIO`` or the value ``EUNKNOWN`` for an unknown error.
|
||||
``EIO`` or the value ``EUNKNOWN`` for an unknown error. Note that if a client
|
||||
sends a request for another MIME type before the data for the revious MIME type
|
||||
is completed, the terminal *must* switch over to sending data for the new MIME
|
||||
type.
|
||||
|
||||
Once the client program finishes reading all the dropped data it needs, it must
|
||||
send an escape code of the form::
|
||||
|
||||
OSC _dnd_code ; t=r ST
|
||||
|
||||
That is, it must send a request for data with no MIME type specified. The
|
||||
terminal emulator must then inform the OS that the drop is completed.
|
||||
|
||||
Metadata reference
|
||||
---------------------------
|
||||
|
||||
27
kitty/dnd.c
27
kitty/dnd.c
@@ -228,15 +228,16 @@ drop_set_status(Window *w, int operation, const char *payload, size_t payload_sz
|
||||
if (!w->drop.accept_in_progress) {
|
||||
drop_free_accepted_mimes(w); w->drop.accept_in_progress = true; w->drop.accepted_operation = 0;
|
||||
switch(operation) {
|
||||
case 1: w->drop.accepted_operation = GLFW_DRAG_OPERATION_COPY; break;
|
||||
case 2: w->drop.accepted_operation = GLFW_DRAG_OPERATION_MOVE; break;
|
||||
default: w->drop.accepted_operation = GLFW_DRAG_OPERATION_NONE; break;
|
||||
case 1: case 2: w->drop.accepted_operation = operation; break;
|
||||
default: w->drop.accepted_operation = 0; break;
|
||||
}
|
||||
}
|
||||
w->drop.accepted_mimes = realloc(w->drop.accepted_mimes, w->drop.accepted_mimes_sz + payload_sz + 2);
|
||||
if (w->drop.accepted_mimes) {
|
||||
memcpy(w->drop.accepted_mimes + w->drop.accepted_mimes_sz, payload, payload_sz);
|
||||
w->drop.accepted_mimes_sz += payload_sz;
|
||||
if (payload_sz) {
|
||||
w->drop.accepted_mimes = realloc(w->drop.accepted_mimes, w->drop.accepted_mimes_sz + payload_sz + 2);
|
||||
if (w->drop.accepted_mimes) {
|
||||
memcpy(w->drop.accepted_mimes + w->drop.accepted_mimes_sz, payload, payload_sz);
|
||||
w->drop.accepted_mimes_sz += payload_sz;
|
||||
}
|
||||
}
|
||||
if (!more) {
|
||||
w->drop.accept_in_progress = false;
|
||||
@@ -250,11 +251,21 @@ drop_set_status(Window *w, int operation, const char *payload, size_t payload_sz
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
drop_finish(Window *w) {
|
||||
OSWindow *osw = os_window_for_kitty_window(w->id);
|
||||
if (osw && osw->handle) {
|
||||
int op = GLFW_DRAG_OPERATION_GENERIC;
|
||||
if (w->drop.accepted_operation == 1) op = GLFW_DRAG_OPERATION_COPY;
|
||||
else if (w->drop.accepted_operation == 2) op = GLFW_DRAG_OPERATION_MOVE;
|
||||
glfwEndDrop(osw->handle, op);
|
||||
}
|
||||
}
|
||||
|
||||
size_t
|
||||
drop_update_mimes(Window *w, const char **allowed_mimes, size_t allowed_mimes_count) {
|
||||
if (w->drop.accept_in_progress) return allowed_mimes_count;
|
||||
if (w->drop.accepted_operation == GLFW_DRAG_OPERATION_NONE) return 0;
|
||||
if (!w->drop.accepted_operation) return 0;
|
||||
typedef struct mime_sorter { const char *m; ssize_t key; } mime_sorter;
|
||||
if (!w->drop.accepted_mimes) return allowed_mimes_count;
|
||||
RAII_ALLOC(mime_sorter, ms, malloc(sizeof(mime_sorter) * allowed_mimes_count));
|
||||
|
||||
@@ -16,3 +16,4 @@ void drop_request_data(Window *w, const char *mime);
|
||||
void drop_set_status(Window *w, int operation, const char *payload, size_t payload_sz, bool more);
|
||||
size_t drop_update_mimes(Window *w, const char **allowed_mimes, size_t allowed_mimes_count);
|
||||
void drop_dispatch_data(Window *w, const char *data, ssize_t sz);
|
||||
void drop_finish(Window *w);
|
||||
|
||||
10
kitty/glfw.c
10
kitty/glfw.c
@@ -847,10 +847,12 @@ on_drop(GLFWwindow *window, GLFWDropEvent *ev) {
|
||||
case GLFW_DROP_DATA_AVAILABLE:
|
||||
if (global_state.drop_dest.client_window_data_request) {
|
||||
if ((w = window_for_window_id(global_state.drop_dest.client_window_data_request))) {
|
||||
char buf[3072];
|
||||
ssize_t ret = ev->read_data(window, ev, buf, sizeof(buf));
|
||||
drop_dispatch_data(w, buf, ret);
|
||||
if (ret <= 0) ev->finish_drop(window, GLFW_DRAG_OPERATION_GENERIC);
|
||||
if (w->drop.getting_data_for_mime && strcmp(w->drop.getting_data_for_mime, ev->mimes[0]) == 0) {
|
||||
char buf[3072];
|
||||
ssize_t ret = ev->read_data(window, ev, buf, sizeof(buf));
|
||||
drop_dispatch_data(w, buf, ret);
|
||||
if (ret <= 0) ev->finish_drop(window, GLFW_DRAG_OPERATION_GENERIC);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!global_state.drop_dest.data) ev->finish_drop(window, GLFW_DRAG_OPERATION_GENERIC);
|
||||
|
||||
@@ -1519,7 +1519,8 @@ screen_handle_dnd_command(Screen *self, const DnDCommand *cmd, const uint8_t *pa
|
||||
case 'm': drop_set_status(w, cmd->operation, (const char*)payload, cmd->payload_sz, cmd->more); break;
|
||||
case 'r': {
|
||||
char buf[256];
|
||||
if (w && cmd->payload_sz + 1 < sizeof(buf)) {
|
||||
if (!cmd->payload_sz) drop_finish(w);
|
||||
else if (cmd->payload_sz + 1 < sizeof(buf)) {
|
||||
memcpy(buf, payload, cmd->payload_sz); buf[cmd->payload_sz] = 0;
|
||||
drop_request_data(w, buf);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user