Mac 后台常驻(隐藏 Dock + 关窗续跑):引擎 / 监听上移 App 级
实现②隐藏 Dock 图标 + ③可靠后台刷新,交付单窗口、可后台常驻的 App。 - 新增 MacBackgroundController(@MainActor App 级单例):持有 engine + auth(脱离窗口 @State,生命周期与 App 一致)。把引擎离屏 WebView 挂常驻隐藏 NSWindow(始终在窗口层级、避 WebKit 无窗口挂起,且脱离主窗口生命周期——关主窗口引擎不销毁,SSE / presence / 传输 / 剪贴板续跑)+ App 级 ProcessInfo.beginActivity 防 App Nap + 按登录态启停剪贴板 monitor / 全局热键。observeAuth(withObservationTracking 桥 Observation→命令式)观察 auth.session 驱动 start/stop - 新增 MacAppDelegate(@NSApplicationDelegateAdaptor):applicationDidFinishLaunching 应用 Dock 策略 + bootstrap 后台运行时;applicationShouldTerminateAfterLastWindowClosed=false——关最后一个窗口不退出,菜单栏常驻续跑 - CommilitiaDropMacApp:engine / auth 改由 MacBackgroundController 持有(不再窗口 @State);MacAppRoot 只做登录门界面切换、不挂引擎生命周期。MacRootView 移除内嵌 EngineWebView + 移除窗口 onAppear/onDisappear 的 monitor/hotkey(全上移 controller)——关窗引擎 / 同步 / 热键不再停 - 设置加「后台」区:隐藏 Dock 图标开关(@AppStorage macHideDock → NSApp.setActivationPolicy .accessory/.regular,默认 regular 显示)+ 后台常驻说明;剪贴板自动同步开关改调 controller.refreshClipboardMonitor;登出只 auth.logout(引擎复位交 controller 随会话变 nil 统一处理)。菜单栏「打开主窗口」先 NSApp.activate 再 openWindow(accessory / 关窗后窗口可前置可见) - 三项能力齐备:①菜单栏图标(既有 MenuBarExtra)②隐藏 Dock(新增,可设置切换)③可靠后台刷新(新增:引擎 / monitor / 热键 App 级持有 + 隐藏窗口托 WebView + App 级 App Nap 防护 + 关窗不退出续跑) - 验证:just mac-build(CommilitiaDropMac.app)+ iOS 模拟器(CommilitiaDrop.app)均 BUILD SUCCEEDED;ad-hoc 启动冒烟通过(进程存活、无崩溃报告、干净退出)。运行期后台同步须用户登录后自测(Broker OAuth 需账号)
This commit is contained in:
@@ -1,15 +1,19 @@
|
||||
#if os(macOS)
|
||||
import SwiftUI
|
||||
|
||||
// 原生 macOS 客户端入口。单窗口 + 菜单栏常驻,桌面壳(MacRootView)替代 iOS 的标签栏。复用 iOS 引擎
|
||||
// (EngineController:离屏 WKWebView 跑 JS 引擎 + 原生 libwebrtc 数据面)与鉴权(AuthManager:Broker
|
||||
// 登录);引擎 WebView 挂在 MacRootView 背景保活(登录后才启)。iOS 入口另见 CDropApp。桌面专属功能
|
||||
// (剪贴板自动同步 / 全局热键 / 原生通知)随后续阶段并入。
|
||||
// 原生 macOS 客户端入口。单窗口 + 菜单栏常驻。桌面壳(MacRootView)替代 iOS 的标签栏。引擎(离屏
|
||||
// WKWebView 跑 JS 引擎 + 原生 libwebrtc 数据面)与鉴权(Broker 登录)由 App 级 MacBackgroundController
|
||||
// 持有并驱动后台续跑——引擎 WebView 挂常驻隐藏窗口,关主窗口仍在菜单栏后台同步(见 MacAppDelegate /
|
||||
// MacBackgroundController)。iOS 入口另见 CDropApp。
|
||||
@main
|
||||
struct CommilitiaDropMacApp: App
|
||||
{
|
||||
@State private var auth = AuthManager()
|
||||
@State private var engine = EngineController()
|
||||
@NSApplicationDelegateAdaptor(MacAppDelegate.self) private var appDelegate
|
||||
|
||||
// engine / auth 由 App 级 MacBackgroundController 持有(生命周期与 App 一致、不随窗口显隐,以支持
|
||||
// 关窗后台续跑);此处仅引用、经 .environment 注入视图观察。
|
||||
private var engine: EngineController { MacBackgroundController.shared.engine }
|
||||
private var auth: AuthManager { MacBackgroundController.shared.auth }
|
||||
|
||||
var body: some Scene
|
||||
{
|
||||
@@ -40,8 +44,8 @@ struct CommilitiaDropMacApp: App
|
||||
}
|
||||
}
|
||||
|
||||
// 登录门:有会话进桌面壳(引擎随 MacRootView 背景 WebView 启动),无会话进原生 Broker 登录页。逻辑
|
||||
// 对齐 iOS 的 AppRoot(CDropApp):注入 auth 源、会话激活即按 userId 加载持久记录。
|
||||
// 登录门:有会话进桌面壳,无会话进原生 Broker 登录页。引擎的启停 / 记录加载 / 后台常驻由
|
||||
// MacBackgroundController 统一管(观察 auth.session),故本视图只做界面切换、不挂引擎生命周期。
|
||||
struct MacAppRoot: View
|
||||
{
|
||||
let auth: AuthManager
|
||||
@@ -63,16 +67,6 @@ struct MacAppRoot: View
|
||||
.environment(auth)
|
||||
}
|
||||
}
|
||||
.onAppear
|
||||
{
|
||||
engine.auth = auth
|
||||
// 冷启已有会话:立即按 userId 加载该用户的持久记录(reset 只清内存不动盘)。
|
||||
if let uid = auth.session?.user.id { engine.activateRecords(userId: uid) }
|
||||
}
|
||||
.onChange(of: auth.session?.user.id)
|
||||
{ _, uid in
|
||||
if let uid { engine.activateRecords(userId: uid) }
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user