Skip to content

Commit a6e62be

Browse files
committed
Improve WindowOverlay
1 parent 125eee9 commit a6e62be

File tree

2 files changed

+50
-20
lines changed

2 files changed

+50
-20
lines changed

Sources/Intermodular/Helpers/AppKit or UIKit/AppKitOrUIKitHostingWindow.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ final class AppKitOrUIKitHostingWindow<Content: View>: AppKitOrUIKitWindow {
3939
}
4040
}
4141
#endif
42-
43-
var isKeyAndVisible: Binding<Bool> = .constant(true)
4442

43+
var _canBecomeKey: Bool = true
44+
var isVisible: Binding<Bool> = .constant(true)
4545
var allowTouchesToPassThrough: Bool = false
4646

4747
var windowPosition: CGPoint? {
@@ -110,6 +110,14 @@ final class AppKitOrUIKitHostingWindow<Content: View>: AppKitOrUIKitWindow {
110110

111111
return result
112112
}
113+
114+
override func makeKey() {
115+
guard _canBecomeKey else {
116+
return
117+
}
118+
119+
super.makeKey()
120+
}
113121
#endif
114122

115123
private func setWindowOrigin() {
@@ -205,7 +213,7 @@ fileprivate struct AppKitOrUIKitHostingWindowContent<Content: View>: View {
205213
window?.isHidden = true
206214
#endif
207215

208-
window?.isKeyAndVisible.wrappedValue = false
216+
window?.isVisible.wrappedValue = false
209217
}
210218
}
211219
}

Sources/Intramodular/Window/WindowOverlay.swift

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,25 @@ import SwiftUI
1010
/// A window overlay for SwiftUI.
1111
struct WindowOverlay<Content: View>: AppKitOrUIKitViewControllerRepresentable {
1212
private let content: Content
13-
private let isKeyAndVisible: Binding<Bool>
14-
15-
init(content: Content, isKeyAndVisible: Binding<Bool>) {
13+
private let canBecomeKey: Bool
14+
private let isVisible: Binding<Bool>
15+
16+
init(
17+
content: Content,
18+
canBecomeKey: Bool,
19+
isVisible: Binding<Bool>
20+
) {
1621
self.content = content
17-
self.isKeyAndVisible = isKeyAndVisible
22+
self.canBecomeKey = canBecomeKey
23+
self.isVisible = isVisible
1824
}
1925

2026
func makeAppKitOrUIKitViewController(context: Context) -> AppKitOrUIKitViewControllerType {
21-
.init(content: content, isKeyAndVisible: isKeyAndVisible)
27+
.init(content: content, canBecomeKey: canBecomeKey, isVisible: isVisible)
2228
}
2329

2430
func updateAppKitOrUIKitViewController(_ viewController: AppKitOrUIKitViewControllerType, context: Context) {
25-
viewController.isKeyAndVisible = isKeyAndVisible
31+
viewController.isVisible = isVisible
2632
viewController.content = content
2733

2834
viewController.updateWindow()
@@ -59,16 +65,18 @@ extension WindowOverlay {
5965
}
6066
}
6167

62-
var isKeyAndVisible: Binding<Bool>
68+
var canBecomeKey: Bool
69+
var isVisible: Binding<Bool>
6370
var contentWindow: AppKitOrUIKitHostingWindow<Content>?
6471
#if os(macOS)
6572
var contentWindowController: NSWindowController?
6673
#endif
6774

68-
init(content: Content, isKeyAndVisible: Binding<Bool>) {
75+
init(content: Content, canBecomeKey: Bool, isVisible: Binding<Bool>) {
6976
self.content = content
70-
self.isKeyAndVisible = isKeyAndVisible
71-
77+
self.canBecomeKey = canBecomeKey
78+
self.isVisible = isVisible
79+
7280
super.init(nibName: nil, bundle: nil)
7381

7482
#if os(macOS)
@@ -77,11 +85,11 @@ extension WindowOverlay {
7785
}
7886

7987
func updateWindow() {
80-
if let contentWindow = contentWindow, contentWindow.isHidden == !isKeyAndVisible.wrappedValue {
88+
if let contentWindow = contentWindow, contentWindow.isHidden == !isVisible.wrappedValue {
8189
return
8290
}
8391

84-
if isKeyAndVisible.wrappedValue {
92+
if isVisible.wrappedValue {
8593
#if !os(macOS)
8694
guard let window = view?.window, let windowScene = window.windowScene else {
8795
return
@@ -109,7 +117,8 @@ extension WindowOverlay {
109117
#endif
110118

111119
contentWindow.rootView = content
112-
contentWindow.isKeyAndVisible = isKeyAndVisible
120+
contentWindow._canBecomeKey = canBecomeKey
121+
contentWindow.isVisible = isVisible
113122

114123
#if os(macOS)
115124
contentWindow.title = ""
@@ -119,7 +128,7 @@ extension WindowOverlay {
119128
contentWindow.isHidden = false
120129
contentWindow.isUserInteractionEnabled = true
121130
contentWindow.windowLevel = .init(rawValue: window.windowLevel.rawValue + 1)
122-
131+
123132
contentWindow.makeKeyAndVisible()
124133

125134
contentWindow.rootViewController?.view.setNeedsDisplay()
@@ -155,7 +164,7 @@ extension WindowOverlay {
155164
@objc
156165
public func windowWillClose(_ notification: Notification?) {
157166
if (notification?.object as? AppKitOrUIKitHostingWindow<Content>) === contentWindow {
158-
isKeyAndVisible.wrappedValue = false
167+
isVisible.wrappedValue = false
159168
}
160169
}
161170
#endif
@@ -165,15 +174,28 @@ extension WindowOverlay {
165174
// MARK: - Helpers -
166175

167176
extension View {
168-
/// Makes a window key and visible when a given condition is true
177+
/// Makes a window visible when a given condition is true.
178+
///
179+
/// - Parameters:
180+
/// - isVisible: A binding to whether the window is visible.
181+
/// - content: A closure returning the content of the window.
182+
public func windowOverlay<Content: View>(
183+
isVisible: Binding<Bool>,
184+
@ViewBuilder _ content: () -> Content
185+
) -> some View {
186+
background(WindowOverlay(content: content(), canBecomeKey: false, isVisible: isVisible))
187+
}
188+
189+
/// Makes a window key and visible when a given condition is true.
190+
///
169191
/// - Parameters:
170192
/// - isKeyAndVisible: A binding to whether the window is key and visible.
171193
/// - content: A closure returning the content of the window.
172194
public func windowOverlay<Content: View>(
173195
isKeyAndVisible: Binding<Bool>,
174196
@ViewBuilder _ content: () -> Content
175197
) -> some View {
176-
background(WindowOverlay(content: content(), isKeyAndVisible: isKeyAndVisible))
198+
background(WindowOverlay(content: content(), canBecomeKey: true, isVisible: isKeyAndVisible))
177199
}
178200
}
179201

0 commit comments

Comments
 (0)