From 92e2d550d24e9ca09e867ee7ffc528dd209e8642 Mon Sep 17 00:00:00 2001 From: commilitia Date: Wed, 8 Jul 2026 00:10:52 +0800 Subject: [PATCH] =?UTF-8?q?Mac=20=E5=89=AA=E8=B4=B4=E6=9D=BF=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E4=B8=8B=E8=A1=8C=EF=BC=88=E8=BF=9C=E7=AB=AF=E2=86=92?= =?UTF-8?q?=E6=9C=AC=E6=9C=BA=EF=BC=89+=20iOS=20=E5=BF=BD=E7=95=A5=20auto?= =?UTF-8?q?=EF=BC=88Phase=204b=C2=B72=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 共享引擎 JS(web/src/features/clipboard/clipboard.ts):applyRemoteClipboard(SSE clipboard:update / fetchClipboard)在原生壳(isIOSShell)时对远端更新附加 notifyNative("clipboard", { content, sourceDevice, auto:true }),把下行同步过桥给原生。平台差异交原生侧处理,JS 不读 device_type(surface 更小、iOS 无回归) - 原生 handleNotify("clipboard"):读 auto 标志。macOS 写系统剪贴板(先 armSelfWrite 防自动上行回环)且 auto 时不弹提示(避免远端每次变化刷屏);iOS 忽略 auto(后台受限 + 隐私,不自动写系统剪贴板),仅手动拉取(auto=false)写入并提示。手动拉取两端行为不变 - 至此 Mac 剪贴板双向自动同步齐全:上行(MacClipboardMonitor 监听本机复制 → 上传)+ 下行(远端 SSE → 自动写本机) - **须 prod 部署 web 引擎**方在正式包生效(Mac 从 drop.commilitia.net 加载 engine.html);本地 CDROP_ENGINE_URL 指向本机 web dev server 可即时验证 - 验证:just typecheck-front(tsc 通过)+ just mac-build(CommilitiaDropMac.app)+ iOS 模拟器(CommilitiaDrop.app)均 BUILD SUCCEEDED --- .../Sources/Engine/EngineController.swift | 25 +++++++++++++------ web/src/features/clipboard/clipboard.ts | 11 ++++++++ 2 files changed, 28 insertions(+), 8 deletions(-) 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, + }); + } } }