mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-06 01:05:48 +02:00
More work on the dnd kitten
This commit is contained in:
@@ -121,7 +121,7 @@ func uniqify_child_names(names []string, is_case_sensitive_filesystem bool) []st
|
||||
return names
|
||||
}
|
||||
|
||||
func (d *remote_dir_entry) add_remote_data(data []byte, output_buf []byte, has_more bool, parent *remote_dir_entry, is_case_sensitive_filesystem bool) error {
|
||||
func (d *remote_dir_entry) add_remote_data(data []byte, output_buf []byte, has_more bool, is_case_sensitive_filesystem bool) error {
|
||||
if len(data) > 0 {
|
||||
for chunk, derr := range d.b64_decoder.Decode(data, output_buf) {
|
||||
if derr != nil {
|
||||
@@ -143,7 +143,6 @@ func (d *remote_dir_entry) add_remote_data(data []byte, output_buf []byte, has_m
|
||||
d.dest.Close()
|
||||
d.dest = nil
|
||||
d.base_dir = d.base_dir.unref()
|
||||
parent.num_children_finished++
|
||||
}()
|
||||
if dest, ok := d.dest.(*bufferWriteCloser); ok {
|
||||
if d.item_type == 1 {
|
||||
@@ -199,9 +198,9 @@ type drop_status struct {
|
||||
reading_data bool
|
||||
is_remote_client bool
|
||||
|
||||
root_remote_dir *remote_dir_entry
|
||||
open_remote_dir *remote_dir_entry
|
||||
pending_remote_dirs []*remote_dir_entry
|
||||
root_remote_dir *remote_dir_entry
|
||||
open_remote_dir *remote_dir_entry
|
||||
current_remote_entry *remote_dir_entry // used for m=1 only
|
||||
}
|
||||
|
||||
var reset_drop_status = drop_status{cell_x: -1, cell_y: -1}
|
||||
@@ -357,7 +356,6 @@ func (dnd *dnd) on_drop_move(cell_x, cell_y int, has_more bool, offered_mimes st
|
||||
return
|
||||
}
|
||||
|
||||
var current_remote_entry *remote_dir_entry
|
||||
var drop_buf []byte
|
||||
|
||||
func (dnd *dnd) on_remote_drop_data(cmd DC) (err error) {
|
||||
@@ -366,7 +364,7 @@ func (dnd *dnd) on_remote_drop_data(cmd DC) (err error) {
|
||||
return fmt.Errorf("got a remote data response form the terminal without an open remote dir")
|
||||
}
|
||||
if cmd.X == 0 && cmd.Y == 0 && cmd.Yp == 0 {
|
||||
if current_remote_entry == nil {
|
||||
if drop_status.current_remote_entry == nil {
|
||||
return fmt.Errorf("got a remote data response form the terminal without a current remote entry")
|
||||
}
|
||||
} else {
|
||||
@@ -374,27 +372,34 @@ func (dnd *dnd) on_remote_drop_data(cmd DC) (err error) {
|
||||
if num < 0 || num >= len(drop_status.open_remote_dir.children) {
|
||||
return fmt.Errorf("got a remote data response from the terminal for an entry that does not exist")
|
||||
}
|
||||
current_remote_entry = drop_status.open_remote_dir.children[num]
|
||||
drop_status.current_remote_entry = drop_status.open_remote_dir.children[num]
|
||||
}
|
||||
if current_remote_entry.dest == nil {
|
||||
current_remote_entry.item_type = cmd.Xp
|
||||
e := drop_status.current_remote_entry
|
||||
if e.dest == nil {
|
||||
e.item_type = cmd.Xp
|
||||
switch cmd.Xp {
|
||||
case 0:
|
||||
f, err := utils.CreateAt(drop_status.open_remote_dir.base_dir.handle, current_remote_entry.name)
|
||||
f, err := utils.CreateAt(e.base_dir.handle, e.name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
current_remote_entry.dest = f
|
||||
e.dest = f
|
||||
default:
|
||||
current_remote_entry.dest = &bufferWriteCloser{&bytes.Buffer{}}
|
||||
e.dest = &bufferWriteCloser{&bytes.Buffer{}}
|
||||
}
|
||||
}
|
||||
if sz := max(4096, len(cmd.Payload)+4); len(drop_buf) < sz {
|
||||
drop_buf = make([]byte, sz)
|
||||
}
|
||||
if err = current_remote_entry.add_remote_data(cmd.Payload, drop_buf, cmd.Has_more, drop_status.open_remote_dir, dnd.is_case_sensitive_filesystem); err != nil {
|
||||
if err = e.add_remote_data(cmd.Payload, drop_buf, cmd.Has_more, dnd.is_case_sensitive_filesystem); err != nil {
|
||||
return err
|
||||
}
|
||||
if e.dest == nil { // this entry is finished
|
||||
drop_status.open_remote_dir.num_children_finished++
|
||||
if e.item_type != 0 && e.item_type != 1 {
|
||||
// TODO: request the children
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -51,20 +51,22 @@ type DC = loop.DndCommand
|
||||
|
||||
type dir_handle struct {
|
||||
handle *os.File
|
||||
refcnt int32
|
||||
refcnt atomic.Int32
|
||||
}
|
||||
|
||||
func new_dir_handle(x *os.File) *dir_handle {
|
||||
return &dir_handle{x, 1}
|
||||
ans := dir_handle{x, atomic.Int32{}}
|
||||
ans.refcnt.Store(1)
|
||||
return &ans
|
||||
}
|
||||
|
||||
func (d *dir_handle) newref() *dir_handle {
|
||||
atomic.AddInt32(&d.refcnt, 1)
|
||||
d.refcnt.Add(1)
|
||||
return d
|
||||
}
|
||||
|
||||
func (d *dir_handle) unref() *dir_handle {
|
||||
if atomic.AddInt32(&d.refcnt, -1) <= 0 {
|
||||
if d.refcnt.Add(-1) <= 0 {
|
||||
d.handle.Close()
|
||||
d.handle = nil
|
||||
}
|
||||
|
||||
10
kitty/dnd.c
10
kitty/dnd.c
@@ -668,7 +668,6 @@ get_nth_file_url(const char *uri_list, size_t uri_list_sz, int n, char **path_ou
|
||||
p = eol + 1;
|
||||
while (*p == '\r' || *p == '\n') p++;
|
||||
}
|
||||
|
||||
if (!found_line) { *error_out = "ENOENT"; return false; }
|
||||
|
||||
/* Must be a file:// URL */
|
||||
@@ -695,10 +694,9 @@ get_nth_file_url(const char *uri_list, size_t uri_list_sz, int n, char **path_ou
|
||||
char resolved[PATH_MAX];
|
||||
if (!realpath(path, resolved)) {
|
||||
switch (errno) {
|
||||
case ENOENT: case ENOTDIR: *error_out = "ENOENT"; break;
|
||||
case EACCES: case EPERM: *error_out = "EPERM"; break;
|
||||
case ELOOP: *error_out = "ENOENT"; break;
|
||||
default: *error_out = "EINVAL"; break;
|
||||
case ENOENT: case ENOTDIR: case ELOOP: *error_out = "ENOENT"; break;
|
||||
case EACCES: case EPERM: *error_out = "EPERM"; break;
|
||||
default: *error_out = "EINVAL"; break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -951,7 +949,7 @@ drop_send_dir_listing(Window *w, const char *path) {
|
||||
queue_payload_to_child(w->id, w->drop.client_id, &w->drop.pending, hdr, hdr_sz, NULL, 0, true);
|
||||
}
|
||||
|
||||
/* Handle a t=s request: send the file/directory at URI-list index idx.
|
||||
/* Send the file/directory at URI-list index idx.
|
||||
* Returns true if completed synchronously, false if async file I/O started. */
|
||||
static bool
|
||||
do_drop_request_uri_data(Window *w, int32_t mime_idx, int32_t file_idx) {
|
||||
|
||||
@@ -42,7 +42,7 @@ def create_fs(base):
|
||||
f.write(b'x' * sz)
|
||||
os.makedirs(join('d1', 'sd', 'ssd'))
|
||||
os.mkdir(join('d2'))
|
||||
os.symlink('/does-not-exist', join('s1'))
|
||||
# os.symlink('/does-not-exist', join('s1'))
|
||||
os.symlink('d1', join('sd'))
|
||||
os.symlink('/', join('sr'))
|
||||
os.symlink('../d1', join('d1', 'sr'))
|
||||
|
||||
Reference in New Issue
Block a user