eleven / ocho Public

mac: the frosted band must never eat composer clicks — hitTest nil on the glass (#1023)

Diagnosed live with a click-logging build: during the dead spells every
click on the input row resolved to the band's NSVisualEffectView (its
PlatformViewHost had landed above the field's scroll view in NSView
order, which SwiftUI does not keep in step with the SwiftUI stack), so
the click did nothing and resigned the caret to the window — 'the
composer goes unclickable for a while'. A decorative backdrop takes no
mouse events, whatever the subview order.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell 976a15317aff497a8f4f88ebf4fb30989f30f64e parent 222cdcd
1 file changed, +13 −1
  • ios/LChatMac/FrostedBand.swift +13 −1
diff --git a/ios/LChatMac/FrostedBand.swift b/ios/LChatMac/FrostedBand.swift
index c14efd6..4ae4476 100644
--- a/ios/LChatMac/FrostedBand.swift
+++ b/ios/LChatMac/FrostedBand.swift
@@ -21,8 +21,20 @@ struct FrostedBand: View {
}
private struct WithinWindowBlur: NSViewRepresentable {
+ // Decoration must be transparent to the mouse. This AppKit view lives in
+ // its own PlatformViewHost, and SwiftUI does not keep representable
+ // NSViews' z-order in step with the SwiftUI stack — after a composer-row
+ // re-mount the band's host could land ABOVE the field's scroll view in
+ // NSView order, and every click on the input died on the glass (and
+ // resigned the caret to the window): the "composer goes unclickable for
+ // a while" bug. hitTest nil = clicks always fall through to whatever the
+ // band is dressing, whatever the subview order.
+ private final class ClickThroughEffectView: NSVisualEffectView {
+ override func hitTest(_ point: NSPoint) -> NSView? { nil }
+ }
+
func makeNSView(context: Context) -> NSVisualEffectView {
- let v = NSVisualEffectView()
+ let v = ClickThroughEffectView()
v.blendingMode = .withinWindow
v.material = .headerView
v.state = .active