根因:window_manager 的 setPreventClose 依赖把 WindowManager 挂为 NSWindowDelegate 来拦 windowShouldClose,在 xib 创建的窗口上该 delegate 挂载时机不可靠(会被 xib 原有 delegate/AppKit 流程绕过),preventClose 形同虚设,红点直接关窗。 修复:MainFlutterWindow 重写 performClose(_:)(红点与 Cmd+W 的 target-action 必经之路),直接 orderOut 隐藏窗口,进程/HTTP 服务/托盘保持运行;不依赖 window_manager 的 delegate 是否挂上。真正退出只走托盘菜单 → window_manager.destroy() → NSApp.terminate(不经过 performClose,无冲突); Cmd+Q 系统标准退出保留。window_manager 的 onWindowClose→hide 路径保留 (若 delegate 生效则幂等)。
27 lines
1.1 KiB
Swift
27 lines
1.1 KiB
Swift
import Cocoa
|
||
import FlutterMacOS
|
||
|
||
class MainFlutterWindow: NSWindow {
|
||
override func awakeFromNib() {
|
||
let flutterViewController = FlutterViewController()
|
||
let windowFrame = self.frame
|
||
self.contentViewController = flutterViewController
|
||
self.setFrame(windowFrame, display: true)
|
||
self.minSize = NSSize(width: 860, height: 560)
|
||
|
||
RegisterGeneratedPlugins(registry: flutterViewController)
|
||
|
||
super.awakeFromNib()
|
||
}
|
||
|
||
/// 关窗不退出(双保险):红点按钮与 Cmd+W 的 target 都是 performClose:,
|
||
/// 这里直接 orderOut 隐藏窗口,进程/服务/托盘保持运行;
|
||
/// 真正退出只走托盘菜单 → window_manager.destroy() → NSApp.terminate(不经过此处)。
|
||
/// window_manager 的 setPreventClose/delegate 拦截在 xib 窗口上挂载时机不可靠,
|
||
/// 不能作为关窗拦截的唯一依赖(实测会被绕过导致整窗关闭)。
|
||
override func performClose(_ sender: Any?) {
|
||
print("MainFlutterWindow: performClose 拦截,窗口隐藏到托盘(服务继续运行)")
|
||
orderOut(sender)
|
||
}
|
||
}
|