diff --git a/ios/CDrop/Sources/Engine/EngineController.swift b/ios/CDrop/Sources/Engine/EngineController.swift index 51e1c74..fdab65d 100644 --- a/ios/CDrop/Sources/Engine/EngineController.swift +++ b/ios/CDrop/Sources/Engine/EngineController.swift @@ -1012,20 +1012,29 @@ extension EngineController: WKScriptMessageHandler if logs.count > Self.logsCap { logs.removeLast(logs.count - Self.logsCap) } } case "clipboard": - // 引擎拉回的云剪贴板内容 → 写入本机 UIPasteboard。 - if let p = payload as? [String: Any], let content = p["content"] as? String, !content.isEmpty + // 云剪贴板内容 → 写入本机剪贴板。auto=true 为远端自动下行(JS 在 isIOSShell 时对 clipboard:update + // 附加):iOS 不自动写系统剪贴板(后台受限 + 隐私,仍走控制中心手动拉取),故忽略 auto;macOS 写入 + // 且不弹提示(避免每次远端变化刷屏)。auto=false 为用户手动拉取:两端都写并提示。 + let clip = payload as? [String: Any] + let clipContent = clip?["content"] as? String ?? "" + let clipAuto = (clip?["auto"] as? Bool) ?? false + if !clipContent.isEmpty { #if os(macOS) - // 先武装自写守卫(令剪贴板自动同步 monitor 认出刚拉取写入的内容为自身回声、不再上传),再写。 - MacClipboardMonitor.shared.armSelfWrite(content) + // 先武装自写守卫(令自动同步 monitor 认出刚写入的内容为自身回声、不再上传),再写。 + MacClipboardMonitor.shared.armSelfWrite(clipContent) NSPasteboard.general.clearContents() - NSPasteboard.general.setString(content, forType: .string) + NSPasteboard.general.setString(clipContent, forType: .string) + if !clipAuto { notify(t("ios.clipboard.pulled"), kind: .success) } #else - UIPasteboard.general.string = content + if !clipAuto + { + UIPasteboard.general.string = clipContent + notify(t("ios.clipboard.pulled"), kind: .success) + } #endif - notify(t("ios.clipboard.pulled"), kind: .success) } - else + else if !clipAuto { notify(t("ios.clipboard.empty"), kind: .info) } diff --git a/web/src/features/clipboard/clipboard.ts b/web/src/features/clipboard/clipboard.ts index 6852490..b849664 100644 --- a/web/src/features/clipboard/clipboard.ts +++ b/web/src/features/clipboard/clipboard.ts @@ -1,5 +1,6 @@ import { apiFetch } from "../../net/api"; import { writeNativeClipboard } from "../../net/desktop"; +import { isIOSShell, notifyNative } from "../../net/ios"; import { useAppStore, type ClipboardState } from "../../store"; import { t } from "../../i18n"; @@ -181,6 +182,16 @@ export function applyRemoteClipboard(state: ClipboardState): void if (!selfDevice || state.sourceDevice !== selfDevice) { writeNativeClipboard(state.content, state.sourceDevice); + // 原生壳(iOS/Mac WebView 引擎):远端剪贴板更新过桥给原生(下行自动同步)。平台差异由原生侧 + // 处理——macOS 静默写系统剪贴板,iOS 忽略 auto(后台受限 + 隐私,仍走控制中心手动拉取)。 + if (isIOSShell()) + { + notifyNative("clipboard", { + content: state.content, + sourceDevice: state.sourceDevice, + auto: true, + }); + } } }