diff --git a/kitty/dnd.c b/kitty/dnd.c index b5bd0748c..da4629211 100644 --- a/kitty/dnd.c +++ b/kitty/dnd.c @@ -884,20 +884,30 @@ drag_free_offer(Window *w) { ds.images_sent_total_sz = 0; } +static void +drag_send_error(Window *w, int error_code) { + char buf[128]; + const char *e = get_errno_name(error_code); + int header_size = snprintf(buf, sizeof(buf), "\x1b]%d;t=R", DND_CODE); + queue_payload_to_child( + w->id, w->drag_source.client_id, &w->drag_source.pending, buf, header_size, e, strlen(e), false); +} + static void cancel_drag(Window *w, int error_code) { - if (error_code) drop_send_error(w, error_code); + if (error_code) drag_send_error(w, error_code); if (global_state.drag_source.is_active && global_state.drag_source.from_window == w->id) cancel_current_drag_source(); drag_free_offer(w); } void -drag_add_mimes(Window *w, int allowed_operations, const char *data, size_t sz, bool has_more) { +drag_add_mimes(Window *w, int allowed_operations, uint32_t client_id, const char *data, size_t sz, bool has_more) { #define abrt(code) { cancel_drag(w, code); return; } if (allowed_operations && ds.state != DRAG_SOURCE_NONE) cancel_drag(w, 0); if (allowed_operations && !ds.allowed_operations) ds.allowed_operations = allowed_operations; if (!ds.allowed_operations) { abrt(EINVAL); } ds.state = DRAG_SOURCE_BEING_BUILT; + ds.client_id = client_id; size_t new_sz = ds.bufsz + sz; if (new_sz > MIME_LIST_SIZE_CAP) abrt(EFBIG); ds.mimes_buf = realloc(ds.mimes_buf, ds.bufsz + sz + 1); @@ -1038,7 +1048,7 @@ drag_start(Window *w) { } else { drag_free_built_data(w); ds.state = DRAG_SOURCE_STARTED; - drop_send_error(w, 0); // send OK + drag_send_error(w, 0); // send OK } } diff --git a/kitty/dnd.h b/kitty/dnd.h index 43e01b181..6bb059f92 100644 --- a/kitty/dnd.h +++ b/kitty/dnd.h @@ -24,7 +24,7 @@ void dnd_set_test_write_func(PyObject *func); void drag_free_offer(Window *w); -void drag_add_mimes(Window *w, int allowed_operations, const char *data, size_t sz, bool has_more); +void drag_add_mimes(Window *w, int allowed_operations, uint32_t client_id, const char *data, size_t sz, bool has_more); void drag_add_pre_sent_data(Window *w, unsigned idx, const uint8_t *payload, size_t sz); void drag_add_image(Window *w, unsigned idx_, int fmt, int width, int height, const uint8_t *payload, size_t sz); void drag_change_image(Window *w, unsigned idx); diff --git a/kitty/screen.c b/kitty/screen.c index 74cb532d2..cecaf438d 100644 --- a/kitty/screen.c +++ b/kitty/screen.c @@ -1548,7 +1548,7 @@ screen_handle_dnd_command(Screen *self, const DnDCommand *cmd, const uint8_t *pa else drop_send_einval(w); } break; case 'o': { - if (cmd->payload_sz > 0) drag_add_mimes(w, (int)cmd->operation, (const char*)payload, cmd->payload_sz, cmd->more); + if (cmd->payload_sz > 0) drag_add_mimes(w, (int)cmd->operation, cmd->client_id, (const char*)payload, cmd->payload_sz, cmd->more); else w->drag_source.can_offer = true; } break; case 'O': { diff --git a/kitty/state.h b/kitty/state.h index eeb4c4e2a..bf56f421a 100644 --- a/kitty/state.h +++ b/kitty/state.h @@ -304,6 +304,8 @@ typedef struct Window { unsigned img_idx; int allowed_operations; DragSourceState state; + PendingData pending; + uint32_t client_id; } drag_source; } Window;