From 62c60900eb9398eac08f6045a5d8195c4f8af8b4 Mon Sep 17 00:00:00 2001 From: bbedward Date: Fri, 27 Mar 2026 13:54:23 -0400 Subject: [PATCH] fix(clipboard): wait for forked child to register Wayland source before returning --- core/internal/clipboard/clipboard.go | 53 +++++++++++++++++++--------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/core/internal/clipboard/clipboard.go b/core/internal/clipboard/clipboard.go index 939aa4ca..c758a973 100644 --- a/core/internal/clipboard/clipboard.go +++ b/core/internal/clipboard/clipboard.go @@ -52,35 +52,53 @@ func copyFork(data io.Reader, mimeType string, pasteOnce bool) error { args = append(args, "--type", mimeType) cmd := exec.Command(args[0], args[1:]...) - cmd.Stdout = nil cmd.Stderr = nil cmd.SysProcAttr = &syscall.SysProcAttr{Setsid: true} + cmd.Env = append(os.Environ(), "DMS_CLIP_FORKED=1") - if stdinSource, ok := data.(*os.File); ok { - cmd.Stdin = stdinSource - return cmd.Start() - } - - stdin, err := cmd.StdinPipe() + stdout, err := cmd.StdoutPipe() if err != nil { - return fmt.Errorf("stdin pipe: %w", err) + return fmt.Errorf("stdout pipe: %w", err) } - if err := cmd.Start(); err != nil { - return fmt.Errorf("start: %w", err) + switch src := data.(type) { + case *os.File: + cmd.Stdin = src + if err := cmd.Start(); err != nil { + return fmt.Errorf("start: %w", err) + } + + default: + stdin, err := cmd.StdinPipe() + if err != nil { + return fmt.Errorf("stdin pipe: %w", err) + } + if err := cmd.Start(); err != nil { + return fmt.Errorf("start: %w", err) + } + if _, err := io.Copy(stdin, data); err != nil { + stdin.Close() + return fmt.Errorf("write stdin: %w", err) + } + if err := stdin.Close(); err != nil { + return fmt.Errorf("close stdin: %w", err) + } } - if _, err := io.Copy(stdin, data); err != nil { - stdin.Close() - return fmt.Errorf("write stdin: %w", err) + var buf [1]byte + if _, err := stdout.Read(buf[:]); err != nil { + return fmt.Errorf("waiting for clipboard ready: %w", err) } - if err := stdin.Close(); err != nil { - return fmt.Errorf("close stdin: %w", err) - } - return nil } +func signalReady() { + if os.Getenv("DMS_CLIP_FORKED") == "" { + return + } + os.Stdout.Write([]byte{1}) +} + func copyServeReader(data io.Reader, mimeType string, pasteOnce bool) error { cachedData, err := createClipboardCacheFile() if err != nil { @@ -242,6 +260,7 @@ func copyServeWithWriter(writeTo func(io.Writer) error, mimeType string, pasteOn } display.Roundtrip() + signalReady() for { select {