137 lines
4.9 KiB
Swift
137 lines
4.9 KiB
Swift
import SwiftUI
|
|
import AppKit
|
|
|
|
class WindowManager: NSObject {
|
|
static let shared = WindowManager()
|
|
|
|
private static let mainWindowIdentifier = NSUserInterfaceItemIdentifier("com.prakashjoshipax.voiceink.mainWindow")
|
|
private static let onboardingWindowIdentifier = NSUserInterfaceItemIdentifier("com.prakashjoshipax.voiceink.onboardingWindow")
|
|
private static let mainWindowAutosaveName = NSWindow.FrameAutosaveName("VoiceInkMainWindowFrame")
|
|
|
|
private weak var mainWindow: NSWindow?
|
|
private var didApplyInitialPlacement = false
|
|
|
|
private override init() {
|
|
super.init()
|
|
}
|
|
|
|
func configureWindow(_ window: NSWindow) {
|
|
if let existingWindow = NSApplication.shared.windows.first(where: { $0.identifier == Self.mainWindowIdentifier && $0 != window }) {
|
|
window.close()
|
|
existingWindow.makeKeyAndOrderFront(nil)
|
|
return
|
|
}
|
|
|
|
let requiredStyleMask: NSWindow.StyleMask = [.titled, .closable, .miniaturizable, .resizable, .fullSizeContentView]
|
|
window.styleMask.formUnion(requiredStyleMask)
|
|
window.titlebarAppearsTransparent = true
|
|
window.titleVisibility = .hidden
|
|
window.backgroundColor = .windowBackgroundColor
|
|
window.isReleasedWhenClosed = false
|
|
window.title = "VoiceInk"
|
|
window.collectionBehavior = [.fullScreenPrimary]
|
|
window.level = .normal
|
|
window.isOpaque = true
|
|
window.isMovableByWindowBackground = false
|
|
window.minSize = NSSize(width: 0, height: 0)
|
|
window.setFrameAutosaveName(Self.mainWindowAutosaveName)
|
|
applyInitialPlacementIfNeeded(to: window)
|
|
registerMainWindowIfNeeded(window)
|
|
window.orderFrontRegardless()
|
|
}
|
|
|
|
func configureOnboardingPanel(_ window: NSWindow) {
|
|
if window.identifier == nil || window.identifier != Self.onboardingWindowIdentifier {
|
|
window.identifier = Self.onboardingWindowIdentifier
|
|
}
|
|
|
|
let requiredStyleMask: NSWindow.StyleMask = [.titled, .fullSizeContentView, .resizable]
|
|
window.styleMask.formUnion(requiredStyleMask)
|
|
window.titlebarAppearsTransparent = true
|
|
window.titleVisibility = .hidden
|
|
window.isMovableByWindowBackground = true
|
|
window.level = .normal
|
|
window.backgroundColor = .clear
|
|
window.isReleasedWhenClosed = false
|
|
window.collectionBehavior = [.canJoinAllSpaces, .fullScreenAuxiliary]
|
|
window.title = "VoiceInk Onboarding"
|
|
window.isOpaque = false
|
|
window.minSize = NSSize(width: 900, height: 780)
|
|
window.makeKeyAndOrderFront(nil)
|
|
}
|
|
|
|
func registerMainWindow(_ window: NSWindow) {
|
|
mainWindow = window
|
|
window.identifier = Self.mainWindowIdentifier
|
|
window.delegate = self
|
|
}
|
|
|
|
func showMainWindow() -> NSWindow? {
|
|
guard let window = resolveMainWindow() else {
|
|
return nil
|
|
}
|
|
|
|
window.makeKeyAndOrderFront(nil)
|
|
NSApplication.shared.activate(ignoringOtherApps: true)
|
|
return window
|
|
}
|
|
|
|
func hideMainWindow() {
|
|
guard let window = resolveMainWindow() else {
|
|
return
|
|
}
|
|
window.orderOut(nil)
|
|
}
|
|
|
|
func currentMainWindow() -> NSWindow? {
|
|
resolveMainWindow()
|
|
}
|
|
|
|
private func registerMainWindowIfNeeded(_ window: NSWindow) {
|
|
// Only register the primary content window, identified by the hidden title bar style
|
|
if window.identifier == nil || window.identifier != Self.mainWindowIdentifier {
|
|
registerMainWindow(window)
|
|
}
|
|
}
|
|
|
|
private func applyInitialPlacementIfNeeded(to window: NSWindow) {
|
|
guard !didApplyInitialPlacement else { return }
|
|
// Attempt to restore previous frame if one exists; otherwise fall back to a centered placement
|
|
if !window.setFrameUsingName(Self.mainWindowAutosaveName) {
|
|
window.center()
|
|
}
|
|
didApplyInitialPlacement = true
|
|
}
|
|
|
|
private func resolveMainWindow() -> NSWindow? {
|
|
if let window = mainWindow {
|
|
return window
|
|
}
|
|
|
|
if let window = NSApplication.shared.windows.first(where: { $0.identifier == Self.mainWindowIdentifier }) {
|
|
mainWindow = window
|
|
window.delegate = self
|
|
return window
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|
|
|
|
extension WindowManager: NSWindowDelegate {
|
|
func windowWillClose(_ notification: Notification) {
|
|
guard let window = notification.object as? NSWindow else { return }
|
|
if window.identifier == Self.mainWindowIdentifier {
|
|
window.orderOut(nil)
|
|
mainWindow = nil
|
|
didApplyInitialPlacement = false
|
|
}
|
|
}
|
|
|
|
func windowDidBecomeKey(_ notification: Notification) {
|
|
guard let window = notification.object as? NSWindow,
|
|
window.identifier == Self.mainWindowIdentifier else { return }
|
|
NSApplication.shared.activate(ignoringOtherApps: true)
|
|
}
|
|
}
|