Overview
Starting with macOS 26 beta 1, a new NSGlassContainerView is added inside NSToolbarView. This view intercepts mouse events, so any SwiftUI Button (or other interactive view) overlaid on the title‑bar / toolbar area no longer receives clicks. (The same code works fine on macOS 15 and earlier.)
Filed as FB18201935 via Feedback Assistant.
Reproduction (minimal project)
- macOS 15 or earlier → button is clickable
- macOS 26 beta → button cannot be clicked (no highlight, no action call)
@main
struct Test_macOS26App: App {
init() {
// Uncomment to work around the issue (see next section)
// enableToolbarClickThrough()
}
var body: some Scene {
WindowGroup {
ContentView()
}
.windowStyle(.hiddenTitleBar) // ⭐️ hide the title bar
}
}
struct ContentView: View {
var body: some View {
NavigationSplitView {
List { Text("sidebar") }
} detail: {
HSplitView {
listWithOverlay
listWithOverlay
}
}
}
private var listWithOverlay: some View {
List(0..<30) { Text("item: \($0)") }
.overlay(alignment: .topTrailing) { // ⭐️ overlay in the toolbar area
Button("test") { print("test") }
.glassEffect()
.ignoresSafeArea()
}
}
}
Investigation
-
- In Xcode View Hierarchy Debugger, a layer chain
-
- -[NSView hitTest:] on NSGlassContainerView returns itself, so the event never reaches the SwiftUI layer.
-
- Swizzling hitTest: to return nil when the result is the view itself makes the click go through:
func enableToolbarClickThrough() {
guard let cls = NSClassFromString("NSGlassContainerView"),
let m = class_getInstanceMethod(cls, #selector(NSView.hitTest(_:))) else { return }
typealias Fn = @convention(c)(AnyObject, Selector, NSPoint) -> Unmanaged<NSView>?
let origIMP = unsafeBitCast(method_getImplementation(m), to: Fn.self)
let block: @convention(block)(AnyObject, NSPoint) -> NSView? = { obj, pt in
guard let v = origIMP(obj, #selector(NSView.hitTest(_:)), pt)?.takeUnretainedValue()
else { return nil }
return v === (obj as AnyObject) ? nil : v // ★ make the container transparent
}
method_setImplementation(m, imp_implementationWithBlock(block))
}
Questions / Call for Feedback
- Is this an intentional behavioral change?
- If so, what is the recommended public API or pattern for allowing clicks to reach views overlaid behind the toolbar?
Any additional data points or confirmations are welcome—please reply if you can reproduce the issue or know of an official workaround.
Thanks in advance!