mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-28 03:01:57 +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
|
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 {
|
if len(data) > 0 {
|
||||||
for chunk, derr := range d.b64_decoder.Decode(data, output_buf) {
|
for chunk, derr := range d.b64_decoder.Decode(data, output_buf) {
|
||||||
if derr != nil {
|
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.Close()
|
||||||
d.dest = nil
|
d.dest = nil
|
||||||
d.base_dir = d.base_dir.unref()
|
d.base_dir = d.base_dir.unref()
|
||||||
parent.num_children_finished++
|
|
||||||
}()
|
}()
|
||||||
if dest, ok := d.dest.(*bufferWriteCloser); ok {
|
if dest, ok := d.dest.(*bufferWriteCloser); ok {
|
||||||
if d.item_type == 1 {
|
if d.item_type == 1 {
|
||||||
@@ -199,9 +198,9 @@ type drop_status struct {
|
|||||||
reading_data bool
|
reading_data bool
|
||||||
is_remote_client bool
|
is_remote_client bool
|
||||||
|
|
||||||
root_remote_dir *remote_dir_entry
|
root_remote_dir *remote_dir_entry
|
||||||
open_remote_dir *remote_dir_entry
|
open_remote_dir *remote_dir_entry
|
||||||
pending_remote_dirs []*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}
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var current_remote_entry *remote_dir_entry
|
|
||||||
var drop_buf []byte
|
var drop_buf []byte
|
||||||
|
|
||||||
func (dnd *dnd) on_remote_drop_data(cmd DC) (err error) {
|
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")
|
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 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")
|
return fmt.Errorf("got a remote data response form the terminal without a current remote entry")
|
||||||
}
|
}
|
||||||
} else {
|
} 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) {
|
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")
|
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 {
|
e := drop_status.current_remote_entry
|
||||||
current_remote_entry.item_type = cmd.Xp
|
if e.dest == nil {
|
||||||
|
e.item_type = cmd.Xp
|
||||||
switch cmd.Xp {
|
switch cmd.Xp {
|
||||||
case 0:
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
current_remote_entry.dest = f
|
e.dest = f
|
||||||
default:
|
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 {
|
if sz := max(4096, len(cmd.Payload)+4); len(drop_buf) < sz {
|
||||||
drop_buf = make([]byte, 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
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,20 +51,22 @@ type DC = loop.DndCommand
|
|||||||
|
|
||||||
type dir_handle struct {
|
type dir_handle struct {
|
||||||
handle *os.File
|
handle *os.File
|
||||||
refcnt int32
|
refcnt atomic.Int32
|
||||||
}
|
}
|
||||||
|
|
||||||
func new_dir_handle(x *os.File) *dir_handle {
|
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 {
|
func (d *dir_handle) newref() *dir_handle {
|
||||||
atomic.AddInt32(&d.refcnt, 1)
|
d.refcnt.Add(1)
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *dir_handle) unref() *dir_handle {
|
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.Close()
|
||||||
d.handle = nil
|
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;
|
p = eol + 1;
|
||||||
while (*p == '\r' || *p == '\n') p++;
|
while (*p == '\r' || *p == '\n') p++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found_line) { *error_out = "ENOENT"; return false; }
|
if (!found_line) { *error_out = "ENOENT"; return false; }
|
||||||
|
|
||||||
/* Must be a file:// URL */
|
/* 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];
|
char resolved[PATH_MAX];
|
||||||
if (!realpath(path, resolved)) {
|
if (!realpath(path, resolved)) {
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
case ENOENT: case ENOTDIR: *error_out = "ENOENT"; break;
|
case ENOENT: case ENOTDIR: case ELOOP: *error_out = "ENOENT"; break;
|
||||||
case EACCES: case EPERM: *error_out = "EPERM"; break;
|
case EACCES: case EPERM: *error_out = "EPERM"; break;
|
||||||
case ELOOP: *error_out = "ENOENT"; break;
|
default: *error_out = "EINVAL"; break;
|
||||||
default: *error_out = "EINVAL"; break;
|
|
||||||
}
|
}
|
||||||
return false;
|
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);
|
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. */
|
* Returns true if completed synchronously, false if async file I/O started. */
|
||||||
static bool
|
static bool
|
||||||
do_drop_request_uri_data(Window *w, int32_t mime_idx, int32_t file_idx) {
|
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)
|
f.write(b'x' * sz)
|
||||||
os.makedirs(join('d1', 'sd', 'ssd'))
|
os.makedirs(join('d1', 'sd', 'ssd'))
|
||||||
os.mkdir(join('d2'))
|
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('d1', join('sd'))
|
||||||
os.symlink('/', join('sr'))
|
os.symlink('/', join('sr'))
|
||||||
os.symlink('../d1', join('d1', 'sr'))
|
os.symlink('../d1', join('d1', 'sr'))
|
||||||
|
|||||||
Reference in New Issue
Block a user