mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-23 00:38:10 +02:00
More work on dnd kitten
This commit is contained in:
@@ -321,7 +321,7 @@ operation, it indicates the drag should be started by sending ``t=P:x=-1``. At
|
|||||||
this time if the user has already cancelled the drag or the terminal determines
|
this time if the user has already cancelled the drag or the terminal determines
|
||||||
the drag operation is not allowed, it must respond with ``t=E ; EPERM``. If any
|
the drag operation is not allowed, it must respond with ``t=E ; EPERM``. If any
|
||||||
other error occurs starting the drag operation, it must respond with the appropriate
|
other error occurs starting the drag operation, it must respond with the appropriate
|
||||||
POSIX error code. If it determines that the image data after conversion to
|
POSIX error name. If it determines that the image data after conversion to
|
||||||
display format is too large, it must respond with ``t=E ; EFBIG``. If the drag
|
display format is too large, it must respond with ``t=E ; EFBIG``. If the drag
|
||||||
operation is successfully started, it must respond with ``t=E ; OK``.
|
operation is successfully started, it must respond with ``t=E ; OK``.
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,57 @@ package dnd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"maps"
|
||||||
|
"slices"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/kovidgoyal/kitty/tools/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = fmt.Print
|
var _ = fmt.Print
|
||||||
|
|
||||||
type drag_status struct {
|
type drag_status struct {
|
||||||
active bool
|
active bool
|
||||||
|
terminal_accepted_drag bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dnd *dnd) on_potential_drag_start(cell_x, cell_y int) (err error) {
|
||||||
|
if !dnd.allow_drags || dnd.drag_status.active {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mimes := slices.Collect(maps.Keys(dnd.drag_sources))
|
||||||
|
actions := 3
|
||||||
|
if dnd.copy_button_region.has(cell_x, cell_y) {
|
||||||
|
actions = 1
|
||||||
|
} else if dnd.move_button_region.has(cell_x, cell_y) {
|
||||||
|
actions = 2
|
||||||
|
}
|
||||||
|
dnd.lp.QueueDnDData(DC{Type: 'o', Operation: actions, Payload: utils.UnsafeStringToBytes(strings.Join(mimes, " "))})
|
||||||
|
total_preloaded_data_sz := 0
|
||||||
|
for i, mt := range mimes {
|
||||||
|
s := dnd.drag_sources[mt]
|
||||||
|
if len(s.data) > 0 && len(s.data)+total_preloaded_data_sz < 64*1024*1024 {
|
||||||
|
total_preloaded_data_sz += len(s.data)
|
||||||
|
dnd.lp.QueueDnDData(DC{Type: 'p', X: i, Operation: actions, Payload: utils.UnsafeStringToBytes(strings.Join(mimes, " "))})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// TODO: set the drag image
|
||||||
|
dnd.lp.QueueDnDData(DC{Type: 'P', X: -1}) // start drag
|
||||||
|
dnd.drag_status.active = true
|
||||||
|
|
||||||
|
return dnd.render_screen()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dnd *dnd) on_drag_error(cmd DC) (err error) {
|
||||||
|
payload := string(cmd.Payload)
|
||||||
|
switch payload {
|
||||||
|
case "OK":
|
||||||
|
if dnd.drag_status.active && !dnd.drag_status.terminal_accepted_drag {
|
||||||
|
dnd.drag_status.terminal_accepted_drag = true
|
||||||
|
err = dnd.render_screen()
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
err = fmt.Errorf("terminal responded with drag source error: %s", payload)
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,6 +240,12 @@ func (dnd *dnd) run_loop() (err error) {
|
|||||||
return fmt.Errorf("error from the terminal while reading dropped data: %s", string(cmd.Payload))
|
return fmt.Errorf("error from the terminal while reading dropped data: %s", string(cmd.Payload))
|
||||||
case 'r':
|
case 'r':
|
||||||
return dnd.on_drop_data(cmd)
|
return dnd.on_drop_data(cmd)
|
||||||
|
|
||||||
|
// Drag source
|
||||||
|
case 'o':
|
||||||
|
return dnd.on_potential_drag_start(cmd.X, cmd.Y)
|
||||||
|
case 'E':
|
||||||
|
return dnd.on_drag_error(cmd)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -305,8 +311,13 @@ func dnd_main(cmd *cli.Command, opts *Options, args []string) (rc int, err error
|
|||||||
}
|
}
|
||||||
s := drag_source{human_name: src, mime_type: mime}
|
s := drag_source{human_name: src, mime_type: mime}
|
||||||
if src == "-" || src == "/dev/stdin" {
|
if src == "-" || src == "/dev/stdin" {
|
||||||
s.human_name = "STDIN"
|
data, err := io.ReadAll(os.Stdin)
|
||||||
s.file = os.Stdin
|
if err != nil {
|
||||||
|
return 1, err
|
||||||
|
}
|
||||||
|
if len(data) > 0 {
|
||||||
|
drag_sources["text/plain"] = drag_source{human_name: "STDIN", mime_type: "text/plain", data: data}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
path, err := filepath.Abs(src)
|
path, err := filepath.Abs(src)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user