Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 0 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ clipboard-sync/
- X11:使用 `xclip`
- Wayland:使用 `wl-copy` / `wl-paste`

部分旧版 GNOME / Nautilus 环境(例如 Rocky Linux 8 / Nautilus 3.28)可能无法识别 `xclip` 写入的文件剪贴板。此时可以启用可选的 GTK 文件剪贴板后端,见 `clipboard_file_writer` 配置项。

### Windows 要求

- Windows 10 / Windows 11
Expand Down Expand Up @@ -159,20 +157,6 @@ which wl-paste
which fusermount3
```

如果需要启用 GTK 文件剪贴板后端,还需要安装 GTK Python 绑定:

Debian / Ubuntu:

```bash
sudo apt-get install -y python3-gi gir1.2-gtk-3.0
```

Rocky / RHEL / CentOS:

```bash
sudo dnf install -y python3-gobject gtk3
```

### 4. Windows 环境准备

PowerShell 中确认 Go:
Expand Down Expand Up @@ -211,7 +195,6 @@ cache_dir: ""
download_dir: ""
mount_dir: ""
log_level: "error"
clipboard_file_writer: "native"
```

### 配置项说明
Expand Down Expand Up @@ -253,18 +236,6 @@ clipboard_file_writer: "native"
日志级别,可选 `debug`、`info`、`warn`、`error`
默认建议 `error`,仅保留错误和异常日志

- `clipboard_file_writer`
Linux 文件剪贴板写入后端,可选 `native`、`gtk`、`auto`
留空或 `native` 时保持原有 `xclip` / `wl-clipboard` 行为
`gtk` 用于兼容旧版 GNOME / Nautilus 文件粘贴
`auto` 会优先尝试 GTK 后端,不可用时回退原生后端

GTK 后端配置示例:

```yaml
clipboard_file_writer: "gtk"
```

### 推荐配置示例

Linux 设备:
Expand All @@ -280,7 +251,6 @@ cache_dir: "/tmp/clipboard-sync/cache"
download_dir: "/tmp/clipboard-sync/downloads"
mount_dir: "/tmp/clipboard-sync/mount"
log_level: "error"
clipboard_file_writer: "native"
```

Windows 设备:
Expand Down Expand Up @@ -343,8 +313,6 @@ netstat -ano | findstr 4222

### Linux 运行

Linux agent 应以当前桌面用户身份运行,不建议用 root 运行。否则可能无法访问当前用户的 X11 / Wayland 剪贴板,或导致 FUSE 挂载权限不正确。

启动 agent:

```bash
Expand Down Expand Up @@ -527,8 +495,6 @@ Linux 检查:
- 是否是在文件管理器中粘贴,而不是纯文本输入框
- FUSE 挂载是否成功
- 剪切板里是否已变成虚拟文件路径
- 如果是 Rocky Linux 8 / Nautilus 3.28 等旧版 GNOME 环境,可在配置中启用 `clipboard_file_writer: "gtk"`
- 使用 GTK 后端时,确认已安装 `python3-gobject` / GTK3,并且 agent 是以桌面用户身份运行

Windows 检查:

Expand Down
95 changes: 0 additions & 95 deletions clipboard/gtk.go

This file was deleted.

54 changes: 0 additions & 54 deletions clipboard/gtk_helper.py

This file was deleted.

77 changes: 2 additions & 75 deletions clipboard/linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
type linuxClipboard struct {
pollInterval time.Duration
backend linuxBackend
gtkWriter *gtkFileWriter
last string
}

Expand All @@ -31,27 +30,12 @@ const (
backendWayland
)

func New(pollInterval time.Duration, fileWriter string) (Clipboard, error) {
func New(pollInterval time.Duration) (Clipboard, error) {
backend, err := detectLinuxBackend()
if err != nil {
return nil, err
}
clip := &linuxClipboard{pollInterval: pollInterval, backend: backend}
// Older file managers (Nautilus 3.x) only honour file paste from a
// GTK-owned clipboard. Optionally route file writes through a GTK helper.
switch fileWriter {
case "gtk":
writer, gerr := detectGTKFileWriter()
if gerr != nil {
return nil, fmt.Errorf("gtk file writer requested but unavailable: %w", gerr)
}
clip.gtkWriter = writer
case "auto":
if writer, gerr := detectGTKFileWriter(); gerr == nil {
clip.gtkWriter = writer
}
}
return clip, nil
return &linuxClipboard{pollInterval: pollInterval, backend: backend}, nil
}

func (c *linuxClipboard) Read() (Data, error) {
Expand Down Expand Up @@ -174,9 +158,6 @@ func (c *linuxClipboard) readFileListPayload() (string, error) {
return string(out), nil
}
}
if payload, ok := c.readNautilusClipboardText(); ok {
return payload, nil
}
return "", errors.New("no file mime type in clipboard")
}

Expand All @@ -187,52 +168,9 @@ func (c *linuxClipboard) readFileListPayload() (string, error) {
return string(out), nil
}
}
if payload, ok := c.readNautilusClipboardText(); ok {
return payload, nil
}
return "", errors.New("no file payload in clipboard")
}

// readNautilusClipboardText reads a text target and returns it when it carries
// an "x-special/" file list (the nautilus-clipboard / gnome-copied-files text
// form). This is a fallback so that clipboards owned by GTK programs — which
// only expose text targets — are still recognised as file lists, letting our
// own GTK file writes round-trip back as files and avoid an echo loop.
func (c *linuxClipboard) readNautilusClipboardText() (string, bool) {
var candidates []string
if c.backend == backendWayland {
mimeTypes, err := exec.Command("wl-paste", "--list-types").Output()
if err != nil {
return "", false
}
for _, target := range []string{"text/plain;charset=utf-8", "text/plain", "UTF8_STRING"} {
if bytes.Contains(mimeTypes, []byte(target)) {
candidates = append(candidates, target)
}
}
} else {
candidates = []string{"text/plain;charset=utf-8", "text/plain", "UTF8_STRING"}
}
for _, target := range candidates {
var (
out []byte
err error
)
if c.backend == backendWayland {
out, err = exec.Command("wl-paste", "--type", target, "--no-newline").Output()
} else {
out, err = exec.Command("xclip", "-selection", "clipboard", "-t", target, "-o").Output()
}
if err != nil || len(out) == 0 {
continue
}
if s := string(out); strings.Contains(s, "x-special/") {
return s, true
}
}
return "", false
}

func parseClipboardFileList(payload string) ([]string, error) {
var files []string
scanner := bufio.NewScanner(strings.NewReader(payload))
Expand Down Expand Up @@ -287,17 +225,6 @@ func (c *linuxClipboard) writeFiles(files []string) error {
return fmt.Errorf("stat %s: %w", path, err)
}
}
if c.gtkWriter != nil {
uris := make([]string, 0, len(files))
for _, path := range files {
uris = append(uris, pathToFileURI(path))
}
payload := "x-special/nautilus-clipboard\ncopy\n" + strings.Join(uris, "\n") + "\n"
if err := c.gtkWriter.writeFiles(payload); err != nil {
return fmt.Errorf("write gtk files: %w", err)
}
return nil
}
lines := make([]string, 0, len(files)+1)
lines = append(lines, "copy")
for _, path := range files {
Expand Down
2 changes: 1 addition & 1 deletion clipboard/windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ type bitmapInfoHeader struct {
ClrImportant uint32
}

func New(pollInterval time.Duration, fileWriter string) (Clipboard, error) {
func New(pollInterval time.Duration) (Clipboard, error) {
remoteFormatOnce.Do(func() {
name, _ := windows.UTF16PtrFromString("ClipboardSyncRemoteMarker")
ret, _, _ := procAddClipboardFormat.Call(uintptr(unsafe.Pointer(name)))
Expand Down
2 changes: 1 addition & 1 deletion cmd/agent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func bootstrap(configPath string) (*app.Agent, func(), error) {
return nil, nil, err
}
logger := logx.New(cfg.LogLevel)
clip, err := clipboard.New(cfg.PollInterval(), cfg.ClipboardFileWriter)
clip, err := clipboard.New(cfg.PollInterval())
if err != nil {
return nil, nil, err
}
Expand Down
Loading