Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Sources/COpenSwiftUI/Shims/UIKit/_UIHitTestContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ NS_HEADER_AUDIT_BEGIN(nullability, sendability)
@end

OPENSWIFTUI_EXPORT
_UIHitTestContext * _Nullable _UICurrentHitTestContext(void) OPENSWIFTUI_SWIFT_NAME(getter:_UIHitTestContext.current);
_UIHitTestContext * _Nullable _UICurrentHitTestContext(void) OPENSWIFTUI_SWIFT_NAME(getter:_UIHitTestContext.current());

NS_HEADER_AUDIT_END(nullability, sendability)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ open class NSHostingView<Content>: NSView, XcodeViewDebugDataProvider where Cont

package let eventBindingManager = EventBindingManager()

private var hitTestEventMonitor: Any?

private lazy var eventBindingSource = BindingSource(hostingView: self)

private lazy var eventBridge = AppKitEventBindingBridge(
Expand Down Expand Up @@ -284,7 +286,20 @@ open class NSHostingView<Content>: NSView, XcodeViewDebugDataProvider where Cont
eventBindingManager.delegate = self
}
HostingViewRegistry.shared.add(self)
// TODO
if _eventDebugTriggers.contains(.hitTest) {
hitTestEventMonitor = NSEvent.addLocalMonitorForEvents(matching: .leftMouseDown) { [weak self] event in
guard let self, event.window === self.window else {
return event
}
guard sequence(first: self as NSView, next: { $0.superview })
.dropFirst().first(ofType: HostingViewProtocol.self) == nil else {
return event
}
let point = self.convert(event.locationInWindow, from: nil)
self.printHitTest(point)
return event
}
}
Update.end()
// TODO
setNeedsUpdate()
Expand All @@ -307,6 +322,9 @@ open class NSHostingView<Content>: NSView, XcodeViewDebugDataProvider where Cont
updateRemovedState()
// TODO
HostingViewRegistry.shared.remove(self)
if let hitTestEventMonitor {
NSEvent.removeMonitor(hitTestEventMonitor)
}
}

/// The renderer configuration of the hosting view.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,45 @@ open class _UIHostingView<Content>: UIView, XcodeViewDebugDataProvider where Con
foreignSubviews.remove(subview)
}

// Audited for 6.5.4
override dynamic open func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
printHitTestIfNeeded(at: point, with: event)
let result = super.hitTest(point, with: event)
guard GestureContainerFeature.isEnabled,
_UIHitTestContext.current != nil || CoreTesting.isRunning
else {
return result
}
if let result, foreignSubviews.allObjects.contains(where: { result.isDescendant(of: $0) }) {
return result
}
currentEvent = event
guard !UIViewIgnoresTouchEvents(self), self.point(inside: point, with: event) else {
return nil
}
return self
}

// Audited for 6.5.4
private func printHitTestIfNeeded(at point: CGPoint, with event: UIEvent?) {
guard _eventDebugTriggers.contains(.hitTest), let event, event.type == .touches else {
return
}
guard sequence(first: self as UIView, next: { $0.superview })
.dropFirst().first(ofType: HostingViewProtocol.self) == nil
else {
return
}
let usesGestureContainer = GestureContainerFeature.isEnabled
let context = _UIHitTestContext.current
if usesGestureContainer {
guard let context else { return }
printHitTest(point, radius: context.radius)
} else {
guard context == nil else { return }
printHitTest(point)
}
}

/// The UIKit notion of the safe area insets.
open override var safeAreaInsets: UIEdgeInsets {
Expand Down
Loading