| | |
| | | import SwiftUI |
| | | |
| | | final class OverlayPanel: NSPanel { |
| | | var handleOverlayKeyEvent: ((NSEvent) -> Bool)? |
| | | |
| | | override var canBecomeKey: Bool { true } |
| | | override var canBecomeMain: Bool { true } |
| | | |
| | | override func sendEvent(_ event: NSEvent) { |
| | | if event.type == .keyDown, |
| | | handleOverlayKeyEvent?(event) == true { |
| | | return |
| | | } |
| | | super.sendEvent(event) |
| | | } |
| | | |
| | | override func constrainFrameRect(_ frameRect: NSRect, to screen: NSScreen?) -> NSRect { |
| | | frameRect |
| | |
| | | let currentOverlayLevel: () -> NSWindow.Level |
| | | let overlayLevel: (_ initialQuickSearchSource: String?) -> NSWindow.Level |
| | | let makeContentView: (_ initialQuickSearchSource: String?) -> NSView |
| | | let handleOverlayKeyEvent: (NSEvent) -> Bool |
| | | let installOverlayKeyMonitor: () -> Void |
| | | let removeOverlayKeyMonitor: () -> Void |
| | | let removeQuickSearchMouseMonitor: () -> Void |
| | |
| | | initialQuickSearchSource: initialQuickSearchSource |
| | | ) |
| | | generation &+= 1 |
| | | let showGeneration = generation |
| | | window = newWindow |
| | | dependencies.installOverlayKeyMonitor() |
| | | if shouldStageAsAccessory { |
| | |
| | | let placementFrame = placement.frame |
| | | let finishForegroundClaim: () -> Void = { [weak self, weak newWindow] in |
| | | guard let self, let newWindow, self.window === newWindow else { return } |
| | | guard self.generation == showGeneration, newWindow.isVisible else { return } |
| | | self.dependencies.refreshChromeState(!shouldAvoidSpaceSwitch, shouldAvoidSpaceSwitch) |
| | | if newWindow.frame != placementFrame { |
| | | newWindow.setFrame(placementFrame, display: true) |
| | | self.orderFront(newWindow) |
| | | } |
| | | for delay in [0.2, 0.5] { |
| | | DispatchQueue.main.asyncAfter(deadline: .now() + delay) { [weak self, weak newWindow] in |
| | | guard let self, let newWindow, self.window === newWindow else { return } |
| | | guard self.generation == showGeneration, newWindow.isVisible else { return } |
| | | guard newWindow.frame != placementFrame else { return } |
| | | newWindow.setFrame(placementFrame, display: true) |
| | | self.orderFront(newWindow) |
| | | } |
| | | } |
| | | if let settingsWindow = self.dependencies.settingsWindow(), settingsWindow.isVisible { |
| | | self.dependencies.prepareSettingsWindow(settingsWindow) |
| | |
| | | if let settingsWindow = dependencies.settingsWindow(), settingsWindow.parent == window { |
| | | dependencies.detachSettingsWindow(settingsWindow) |
| | | } |
| | | window?.orderOut(nil) |
| | | let windowToHide = window |
| | | windowToHide?.ignoresMouseEvents = true |
| | | windowToHide?.alphaValue = 0 |
| | | windowToHide?.orderOut(nil) |
| | | dependencies.removeOverlayKeyMonitor() |
| | | dependencies.removeQuickSearchMouseMonitor() |
| | | windowToHide?.contentView = nil |
| | | windowToHide?.close() |
| | | if window === windowToHide { |
| | | window = nil |
| | | } |
| | | avoidsSpaceSwitch = false |
| | | dependencies.refreshChromeState(false, false) |
| | | dependencies.onDidHide() |
| | | if discardWindow { |
| | | window = nil |
| | | } |
| | | } |
| | | |
| | | func screenUnderMouse() -> NSScreen? { |
| | |
| | | panel.titlebarAppearsTransparent = true |
| | | panel.titleVisibility = .hidden |
| | | panel.isReleasedWhenClosed = false |
| | | panel.handleOverlayKeyEvent = dependencies.handleOverlayKeyEvent |
| | | panel.contentView = dependencies.makeContentView(initialQuickSearchSource) |
| | | return panel |
| | | } |