mirror of
https://github.com/kovidgoyal/kitty
synced 2026-06-08 14:18:26 +02:00
Refactor dnd cmd queueing API
This commit is contained in:
@@ -11,7 +11,7 @@ programs.
|
||||
|
||||
There is one central escape code used for this protocol, which is of the form::
|
||||
|
||||
OSC _dnd_code ; metadata ; base64 encoded payload ST
|
||||
OSC _dnd_code ; metadata ; payload ST
|
||||
|
||||
Here, ``OSC`` is the bytes ``ESC ] (0x1b 0x5b)`` and ST is ``ESC \\ (0x1b 0x5c)``.
|
||||
The ``metadata`` is a colon separated list of ``key=value`` pairs.
|
||||
|
||||
@@ -354,11 +354,7 @@ func Run(args []string) (rc int, err error) {
|
||||
// Request this file via the protocol.
|
||||
dnd.file_read_size = 0
|
||||
dnd.collecting = "file"
|
||||
lp.QueueDnDData(map[string]string{
|
||||
"t": "r",
|
||||
"x": strconv.Itoa(dnd.uri_list_mime_idx),
|
||||
"y": strconv.Itoa(dnd.file_read_idx + 1),
|
||||
}, "", false)
|
||||
lp.QueueDnDData(loop.DndCommand{Type: 'r', X: dnd.uri_list_mime_idx, Y: dnd.file_read_idx + 1})
|
||||
return
|
||||
}
|
||||
// Non-file URI: record as-is with no size info.
|
||||
@@ -367,7 +363,7 @@ func Run(args []string) (rc int, err error) {
|
||||
}
|
||||
// All files processed; finish the drop.
|
||||
dnd.collecting = ""
|
||||
lp.QueueDnDData(map[string]string{"t": "r"}, "", false)
|
||||
lp.QueueDnDData(loop.DndCommand{Type: 'r'})
|
||||
dnd.has_drop_data = true
|
||||
draw_screen()
|
||||
}
|
||||
@@ -402,11 +398,11 @@ func Run(args []string) (rc int, err error) {
|
||||
}
|
||||
}
|
||||
if len(accepted_mimes) > 0 {
|
||||
lp.QueueDnDData(map[string]string{"t": "m", "o": "1"}, strings.Join(accepted_mimes, " "), false)
|
||||
lp.QueueDnDData(loop.DndCommand{Type: 'm', Operation: 1, Payload: []byte(strings.Join(accepted_mimes, " "))})
|
||||
}
|
||||
} else {
|
||||
// Not over drop region; reject the drag.
|
||||
lp.QueueDnDData(map[string]string{"t": "m", "o": "0"}, "", false)
|
||||
lp.QueueDnDData(loop.DndCommand{Type: 'm'})
|
||||
}
|
||||
draw_screen()
|
||||
case 'M':
|
||||
@@ -427,17 +423,17 @@ func Run(args []string) (rc int, err error) {
|
||||
for idx, m := range mimes {
|
||||
if m == "text/plain" {
|
||||
dnd.collecting = "text/plain"
|
||||
lp.QueueDnDData(map[string]string{"t": "r", "x": strconv.Itoa(idx + 1)}, "", false)
|
||||
lp.QueueDnDData(loop.DndCommand{Type: 'r', X: idx + 1})
|
||||
return nil
|
||||
}
|
||||
}
|
||||
if dnd.uri_list_mime_idx > 0 {
|
||||
dnd.collecting = "text/uri-list"
|
||||
lp.QueueDnDData(map[string]string{"t": "r", "x": strconv.Itoa(dnd.uri_list_mime_idx)}, "", false)
|
||||
lp.QueueDnDData(loop.DndCommand{Type: 'r', X: dnd.uri_list_mime_idx})
|
||||
return nil
|
||||
}
|
||||
// Nothing to collect; signal done.
|
||||
lp.QueueDnDData(map[string]string{"t": "r"}, "", false)
|
||||
lp.QueueDnDData(loop.DndCommand{Type: 'r'})
|
||||
dnd.has_drop_data = true
|
||||
draw_screen()
|
||||
case 'r':
|
||||
@@ -451,7 +447,7 @@ func Run(args []string) (rc int, err error) {
|
||||
if cmd.Xp > 1 {
|
||||
// Directory: close the handle.
|
||||
fi.is_dir = true
|
||||
lp.QueueDnDData(map[string]string{"t": "r", "Y": strconv.Itoa(cmd.Xp)}, "", false)
|
||||
lp.QueueDnDData(loop.DndCommand{Type: 'r', Yp: cmd.Xp})
|
||||
} else if cmd.Xp == 1 {
|
||||
fi.is_link = true
|
||||
fi.size = dnd.file_read_size
|
||||
@@ -487,7 +483,8 @@ func Run(args []string) (rc int, err error) {
|
||||
// Now request text/uri-list if available.
|
||||
if dnd.uri_list_mime_idx > 0 {
|
||||
dnd.collecting = "text/uri-list"
|
||||
lp.QueueDnDData(map[string]string{"t": "r", "x": strconv.Itoa(dnd.uri_list_mime_idx)}, "", false)
|
||||
lp.QueueDnDData(
|
||||
loop.DndCommand{Type: 'r', X: dnd.uri_list_mime_idx})
|
||||
return nil
|
||||
}
|
||||
case "text/uri-list":
|
||||
@@ -512,7 +509,7 @@ func Run(args []string) (rc int, err error) {
|
||||
}
|
||||
}
|
||||
dnd.collecting = ""
|
||||
lp.QueueDnDData(map[string]string{"t": "r"}, "", false)
|
||||
lp.QueueDnDData(loop.DndCommand{Type: 'r'})
|
||||
dnd.has_drop_data = true
|
||||
draw_screen()
|
||||
} else {
|
||||
@@ -537,7 +534,7 @@ func Run(args []string) (rc int, err error) {
|
||||
} else if !is_file_response {
|
||||
// Error getting MIME data; finish the drop with what we have.
|
||||
dnd.collecting = ""
|
||||
lp.QueueDnDData(map[string]string{"t": "r"}, "", false)
|
||||
lp.QueueDnDData(loop.DndCommand{Type: 'r'})
|
||||
dnd.has_drop_data = true
|
||||
draw_screen()
|
||||
}
|
||||
|
||||
@@ -669,15 +669,22 @@ func (self *Loop) DrawSizedText(text string, spec SizedText) {
|
||||
self.QueueWriteString(b.String())
|
||||
}
|
||||
|
||||
func (self *Loop) QueueDnDData(metadata map[string]string, payload string, as_base64 bool) IdType {
|
||||
func (self *Loop) QueueDnDData(cmd DndCommand) IdType {
|
||||
b := strings.Builder{}
|
||||
b.Grow(64)
|
||||
fmt.Fprintf(&b, "\x1b]%d;", kitty.DndCode)
|
||||
sep := ""
|
||||
for key, val := range metadata {
|
||||
fmt.Fprintf(&b, "%s%s=%s", sep, key, val)
|
||||
sep = ":"
|
||||
as_base64 := cmd.Type == 'r'
|
||||
fmt.Fprintf(&b, "\x1b]%d;t=%c", kitty.DndCode, cmd.Type)
|
||||
add := func(key byte, val int) {
|
||||
if val != 0 {
|
||||
fmt.Fprintf(&b, ":%c=%d", key, val)
|
||||
}
|
||||
}
|
||||
add('o', cmd.Operation)
|
||||
add('x', cmd.X)
|
||||
add('y', cmd.Y)
|
||||
add('X', cmd.Xp)
|
||||
add('Y', cmd.Yp)
|
||||
payload := utils.UnsafeBytesToString(cmd.Payload)
|
||||
payload_sz := len(payload)
|
||||
if payload_sz == 0 {
|
||||
b.WriteString("\x1b\\")
|
||||
@@ -696,7 +703,7 @@ func (self *Loop) QueueDnDData(metadata map[string]string, payload string, as_ba
|
||||
is_last := end >= len(payload)
|
||||
end = min(end, len(payload))
|
||||
if i == 0 {
|
||||
fmt.Fprintf(&b, "%sm=%d;", sep, utils.IfElse(is_last, 0, 1))
|
||||
fmt.Fprintf(&b, ":m=%d;", utils.IfElse(is_last, 0, 1))
|
||||
self.QueueWriteString(b.String())
|
||||
} else {
|
||||
self.QueueWriteString(fmt.Sprintf("\x1b]%d;m=%d;", kitty.DndCode, utils.IfElse(is_last, 0, 1)))
|
||||
@@ -722,14 +729,14 @@ func effective_machine_id(m string) string {
|
||||
}
|
||||
|
||||
func (self *Loop) StartAcceptingDrops(machine_id string, mime_types ...string) {
|
||||
self.QueueDnDData(map[string]string{"t": "a"}, strings.Join(mime_types, " "), false)
|
||||
self.QueueDnDData(DndCommand{Type: 'a', Payload: []byte(strings.Join(mime_types, " "))})
|
||||
if m := effective_machine_id(machine_id); m != "" {
|
||||
self.QueueDnDData(map[string]string{"t": "a", "x": "1"}, m, false)
|
||||
self.QueueDnDData(DndCommand{Type: 'a', X: 1, Payload: []byte(m)})
|
||||
}
|
||||
}
|
||||
|
||||
func (self *Loop) StopAcceptingDrops() {
|
||||
self.QueueDnDData(map[string]string{"t": "A"}, "", false)
|
||||
self.QueueDnDData(DndCommand{Type: 'A'})
|
||||
}
|
||||
|
||||
func (self *Loop) StartOfferingDrags(machine_id string) {
|
||||
@@ -737,9 +744,9 @@ func (self *Loop) StartOfferingDrags(machine_id string) {
|
||||
if m := effective_machine_id(machine_id); m != "" {
|
||||
payload = m
|
||||
}
|
||||
self.QueueDnDData(map[string]string{"t": "o", "x": "1"}, payload, false)
|
||||
self.QueueDnDData(DndCommand{Type: 'o', X: 1, Payload: []byte(payload)})
|
||||
}
|
||||
|
||||
func (self *Loop) StopOfferingDrags() {
|
||||
self.QueueDnDData(map[string]string{"t": "o", "x": "2"}, "", false)
|
||||
self.QueueDnDData(DndCommand{Type: 'o', X: 2})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user