feat: Windows (CF_DIB) and macOS (AppleScript) clipboard image sync
This commit is contained in:
@@ -4,6 +4,7 @@ package clipboard
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
@@ -43,3 +44,55 @@ func (c *darwinClipboard) Write(text string) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReadImage reads a PNG image from the clipboard via AppleScript, writing it to
|
||||
// a temporary file and reading it back.
|
||||
func (c *darwinClipboard) ReadImage() (string, []byte, error) {
|
||||
tmp, err := os.CreateTemp("", "clip-sync-*.png")
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
tmpPath := tmp.Name()
|
||||
tmp.Close()
|
||||
defer os.Remove(tmpPath)
|
||||
|
||||
// AppleScript type code PNGf, wrapped in the chevron quotes AppleScript uses.
|
||||
script := `set f to (open for access POSIX file "` + tmpPath + `" with write permission)
|
||||
set eof f to 0
|
||||
write (the clipboard as «class PNGf») to f
|
||||
close access f`
|
||||
if err := exec.Command("osascript", "-e", script).Run(); err != nil {
|
||||
return "", nil, ErrNoImage
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(tmpPath)
|
||||
if err != nil || len(data) == 0 {
|
||||
return "", nil, ErrNoImage
|
||||
}
|
||||
return "image/png", data, nil
|
||||
}
|
||||
|
||||
// WriteImage writes a PNG image to the clipboard via AppleScript.
|
||||
func (c *darwinClipboard) WriteImage(mime string, data []byte) error {
|
||||
if mime != "" && mime != "image/png" {
|
||||
return fmt.Errorf("clipboard: unsupported image mime %q (only PNG)", mime)
|
||||
}
|
||||
tmp, err := os.CreateTemp("", "clip-sync-*.png")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := tmp.Write(data); err != nil {
|
||||
tmp.Close()
|
||||
os.Remove(tmp.Name())
|
||||
return err
|
||||
}
|
||||
tmpPath := tmp.Name()
|
||||
tmp.Close()
|
||||
defer os.Remove(tmpPath)
|
||||
|
||||
script := `set the clipboard to (read (POSIX file "` + tmpPath + `") as «class PNGf»)`
|
||||
if err := exec.Command("osascript", "-e", script).Run(); err != nil {
|
||||
return fmt.Errorf("clipboard write image (osascript): %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user