34f0db215c
实现②隐藏 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 需账号)
73 lines
2.4 KiB
Swift
73 lines
2.4 KiB
Swift
#if os(macOS)
|
||
import SwiftUI
|
||
|
||
// 原生 macOS 客户端入口。单窗口 + 菜单栏常驻。桌面壳(MacRootView)替代 iOS 的标签栏。引擎(离屏
|
||
// WKWebView 跑 JS 引擎 + 原生 libwebrtc 数据面)与鉴权(Broker 登录)由 App 级 MacBackgroundController
|
||
// 持有并驱动后台续跑——引擎 WebView 挂常驻隐藏窗口,关主窗口仍在菜单栏后台同步(见 MacAppDelegate /
|
||
// MacBackgroundController)。iOS 入口另见 CDropApp。
|
||
@main
|
||
struct CommilitiaDropMacApp: App
|
||
{
|
||
@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
|
||
{
|
||
Window("Commilitia Drop", id: "main")
|
||
{
|
||
MacAppRoot(auth: auth, engine: engine)
|
||
.frame(minWidth: 820, minHeight: 560)
|
||
}
|
||
.defaultLaunchBehavior(.presented)
|
||
.windowResizability(.contentMinSize)
|
||
.commands
|
||
{
|
||
// 单窗口应用:移除「新建」(⌘N),对本应用无意义。
|
||
CommandGroup(replacing: .newItem) {}
|
||
}
|
||
|
||
MenuBarExtra
|
||
{
|
||
MacMenuContent()
|
||
.environment(engine)
|
||
.environment(auth)
|
||
}
|
||
label:
|
||
{
|
||
Image(systemName: "paperplane")
|
||
}
|
||
.menuBarExtraStyle(.window)
|
||
}
|
||
}
|
||
|
||
// 登录门:有会话进桌面壳,无会话进原生 Broker 登录页。引擎的启停 / 记录加载 / 后台常驻由
|
||
// MacBackgroundController 统一管(观察 auth.session),故本视图只做界面切换、不挂引擎生命周期。
|
||
struct MacAppRoot: View
|
||
{
|
||
let auth: AuthManager
|
||
let engine: EngineController
|
||
|
||
var body: some View
|
||
{
|
||
Group
|
||
{
|
||
if auth.session != nil
|
||
{
|
||
MacRootView()
|
||
.environment(engine)
|
||
.environment(auth)
|
||
}
|
||
else
|
||
{
|
||
MacLoginView()
|
||
.environment(auth)
|
||
}
|
||
}
|
||
}
|
||
}
|
||
#endif
|