diff --git a/kittens/dnd/drop.go b/kittens/dnd/drop.go index 5c9647ee6..392a632f1 100644 --- a/kittens/dnd/drop.go +++ b/kittens/dnd/drop.go @@ -423,6 +423,10 @@ func (d *drop_dest) reset() { } func (dnd *dnd) reset_drop() { + if dnd.drop_status.root_remote_dir != nil { + dnd.drop_status.root_remote_dir.close_tree() + dnd.drop_status.root_remote_dir = nil + } dnd.drop_status.reset() for _, x := range dnd.drop_dests { x.reset() @@ -438,24 +442,31 @@ func (root *remote_dir_entry) close_tree() { } } -func (dnd *dnd) end_drop() { - dnd.lp.QueueDnDData(DC{Type: 'r'}) // end drop - if dnd.drop_status.root_remote_dir != nil { - dnd.drop_status.root_remote_dir.close_tree() - dnd.drop_status.root_remote_dir = nil +func (dnd *dnd) end_drop(success bool) { + if dnd.drop_status.reading_data { + dnd.lp.QueueDnDData(DC{ + Type: 'r', Operation: utils.IfElse(success, dnd.drop_status.action, 0)}) // end drop } dnd.reset_drop() - dnd.render_screen() } -func (dnd *dnd) all_drop_data_received() error { +func (dnd *dnd) all_drop_data_received() (err error) { dnd.data_has_been_dropped = true var staging_dir *os.File if dnd.drop_status.dropping_to != nil { staging_dir = dnd.drop_status.dropping_to.handle dnd.drop_status.dropping_to = nil } - defer dnd.end_drop() + defer func() { + if err == nil { + if len(dnd.confirm_drop.overwrites) == 0 { + dnd.end_drop(true) + } + err = dnd.render_screen() + } else { + dnd.end_drop(false) + } + }() if staging_dir != nil { if dnd.opts.ConfirmDropOverwrite { overwrites, err := find_overwrites(staging_dir, dnd.drop_output_dir) @@ -473,7 +484,7 @@ func (dnd *dnd) all_drop_data_received() error { if err != nil { return err } - return dnd.render_screen() + return nil } return nil } @@ -505,8 +516,8 @@ func (dnd *dnd) all_mime_data_dropped() (err error) { drop_status := &dnd.drop_status if len(drop_status.uri_list) == 0 { dnd.data_has_been_dropped = true - dnd.end_drop() - return + dnd.end_drop(true) + return dnd.render_screen() } f, err := dnd.new_tdir() if err != nil { @@ -608,7 +619,7 @@ func (dnd *dnd) on_drop_move(cell_x, cell_y int, has_more bool, offered_mimes st if is_drop { needs_rerender = true if dnd.drop_status.action == 0 || len(dnd.drop_status.accepted_mimes) == 0 || dnd.drag_started { - dnd.end_drop() + dnd.end_drop(false) return } dnd.drop_status.reading_data = true @@ -743,8 +754,12 @@ func (dnd *dnd) drop_confirm(accepted bool) error { dnd.data_has_been_dropped = accepted if accepted { if err := rename_contents(staging_dir, dnd.drop_output_dir); err != nil { + dnd.end_drop(false) return err } + dnd.end_drop(true) + } else { + dnd.end_drop(false) } return dnd.render_screen() } diff --git a/kittens/dnd/main.go b/kittens/dnd/main.go index fe9278894..0f12cccb9 100644 --- a/kittens/dnd/main.go +++ b/kittens/dnd/main.go @@ -372,7 +372,7 @@ func dnd_main(cmd *cli.Command, opts *Options, args []string) (rc int, err error } dnd := dnd{opts: opts, drop_dests: drop_dests, drag_sources: drag_sources} defer func() { - dnd.reset_drop() + dnd.end_drop(false) if dnd.confirm_drop.staging_dir != nil { dnd.confirm_drop.staging_dir.Close() dnd.confirm_drop.staging_dir = nil diff --git a/kitty/dnd.c b/kitty/dnd.c index f52b37e28..65f63cc32 100644 --- a/kitty/dnd.c +++ b/kitty/dnd.c @@ -1148,10 +1148,13 @@ drop_process_queue(Window *w) { } } +static GLFWDragOperationType last_drop_finish_operation = GLFW_DRAG_OPERATION_NONE; + void drop_enqueue_request(Window *w, int32_t cell_x, int32_t cell_y, int32_t pixel_y, uint32_t operation) { if (cell_x == 0 && cell_y == 0 && pixel_y == 0) { // drop finished w->drop.accepted_operation = drop_operation_to_enum(operation); + last_drop_finish_operation = w->drop.accepted_operation; drop_finish_and_clear_queue(w); reset_drop(w); return; @@ -2210,6 +2213,9 @@ dnd_test_probe_state(PyObject *self UNUSED, PyObject *args) { if (strcmp(q, "drop_action") == 0) { return PyLong_FromLong((long)w->drop.accepted_operation); } + if (strcmp(q, "last_drop_action") == 0) { + return PyLong_FromLong((long)last_drop_finish_operation); + } if (strcmp(q, "drop_mimes") == 0) { if (w->drop.accepted_mimes == NULL) return PyUnicode_FromString(""); return PyUnicode_FromStringAndSize(w->drop.accepted_mimes, w->drop.accepted_mimes_sz); diff --git a/kitty_tests/dnd_kitten.py b/kitty_tests/dnd_kitten.py index 79b40aecd..34831efeb 100644 --- a/kitty_tests/dnd_kitten.py +++ b/kitty_tests/dnd_kitten.py @@ -265,6 +265,7 @@ def send_file_in_chunks(f, mime, sz=3072): if remote_client: pass else: + self.wait_for_state('last_drop_action', GLFW_DRAG_OPERATION_COPY) self.wait_for_state('drop_action', 0) def assert_files_have_same_content(self, a, b):