mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-04 08:10:55 +00:00
60 lines
2.3 KiB
Swift
60 lines
2.3 KiB
Swift
import Cocoa
|
|
import FlutterMacOS
|
|
import desktop_multi_window
|
|
import window_manager
|
|
|
|
class MainFlutterWindow: NSWindow {
|
|
private var childWindowCloseObservers: [ObjectIdentifier: NSObjectProtocol] = [:]
|
|
|
|
override func awakeFromNib() {
|
|
let flutterViewController = FlutterViewController()
|
|
let windowFrame = self.frame
|
|
self.contentViewController = flutterViewController
|
|
self.setFrame(windowFrame, display: true)
|
|
|
|
RegisterGeneratedPlugins(registry: flutterViewController)
|
|
FlutterMultiWindowPlugin.setOnWindowCreatedCallback { [weak self] controller in
|
|
RegisterGeneratedPlugins(registry: controller)
|
|
self?.releaseChildEngineOnClose(controller)
|
|
}
|
|
|
|
super.awakeFromNib()
|
|
}
|
|
|
|
// desktop_multi_window removes closed windows from its registry, but plugin
|
|
// channels can still retain the window/controller/engine cycle. NSWindow.close
|
|
// alone therefore leaves each child Dart isolate and its heap running.
|
|
private func releaseChildEngineOnClose(_ controller: FlutterViewController) {
|
|
guard let window = controller.view.window else { return }
|
|
let key = ObjectIdentifier(window)
|
|
childWindowCloseObservers[key] = NotificationCenter.default.addObserver(
|
|
forName: NSWindow.willCloseNotification, object: window, queue: .main
|
|
) { [weak self, weak controller, weak window] _ in
|
|
if let observer = self?.childWindowCloseObservers.removeValue(forKey: key) {
|
|
NotificationCenter.default.removeObserver(observer)
|
|
}
|
|
// Let close notifications and the plugin's registry removal finish before
|
|
// tearing down the engine that delivered the close request.
|
|
DispatchQueue.main.async { [weak controller, weak window] in
|
|
// window_manager's onEvent closure retains its plugin, which retains
|
|
// the manager and NSWindow even after the engine has stopped.
|
|
(window?.delegate as? WindowManager)?.onEvent = nil
|
|
window?.delegate = nil
|
|
controller?.engine.shutDownEngine()
|
|
window?.contentViewController = nil
|
|
}
|
|
}
|
|
}
|
|
|
|
deinit {
|
|
for observer in childWindowCloseObservers.values {
|
|
NotificationCenter.default.removeObserver(observer)
|
|
}
|
|
}
|
|
|
|
override public func order(_ place: NSWindow.OrderingMode, relativeTo otherWin: Int) {
|
|
super.order(place, relativeTo: otherWin)
|
|
hiddenWindowAtLaunch()
|
|
}
|
|
}
|