feat: native clipboard image sync (Linux, opt-in sync_images)

This commit is contained in:
2026-08-14 09:51:25 -04:00
parent 884415c1c1
commit 147cba6d2a
15 changed files with 274 additions and 48 deletions
+27 -18
View File
@@ -5,6 +5,7 @@ import (
"bytes"
"crypto/tls"
"crypto/x509"
"encoding/base64"
"encoding/json"
"fmt"
"log"
@@ -84,8 +85,25 @@ func buildTLSConfig(opts Options) *tls.Config {
// Errors are logged but not returned — a single unreachable peer should not
// block other peers or the daemon loop.
func (b *Broadcaster) Broadcast(text string) {
body, ok := b.marshalPayload(text)
if !ok {
b.BroadcastPayload(dedup.Payload{Text: text})
}
// BroadcastImage sends an image (base64-encoded) to all peers in parallel.
func (b *Broadcaster) BroadcastImage(mime string, data []byte) {
b.BroadcastPayload(dedup.Payload{
Mime: mime,
Data: base64.StdEncoding.EncodeToString(data),
})
}
// BroadcastPayload sends an arbitrary payload to all peers in parallel.
func (b *Broadcaster) BroadcastPayload(p dedup.Payload) {
p.Ts = time.Now().UnixNano()
p.Origin = b.origin
body, err := json.Marshal(p)
if err != nil {
log.Printf("peer: marshal payload: %v", err)
return
}
@@ -99,8 +117,13 @@ func (b *Broadcaster) Broadcast(text string) {
// has completed (or failed). Used by the one-shot mode so the process does not
// exit before the payload is on the wire.
func (b *Broadcaster) BroadcastSync(text string) {
body, ok := b.marshalPayload(text)
if !ok {
body, err := json.Marshal(dedup.Payload{
Text: text,
Ts: time.Now().UnixNano(),
Origin: b.origin,
})
if err != nil {
log.Printf("peer: marshal payload: %v", err)
return
}
@@ -116,20 +139,6 @@ func (b *Broadcaster) BroadcastSync(text string) {
wg.Wait()
}
func (b *Broadcaster) marshalPayload(text string) ([]byte, bool) {
payload := dedup.Payload{
Text: text,
Ts: time.Now().UnixNano(),
Origin: b.origin,
}
body, err := json.Marshal(payload)
if err != nil {
log.Printf("peer: marshal payload: %v", err)
return nil, false
}
return body, true
}
// snapshot returns a copy of the current peer list under read lock.
func (b *Broadcaster) snapshot() []config.PeerConfig {
b.mu.RLock()