From b49bf20c2cc85d074706f9834a606c7989ab1b05 Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Mon, 9 Feb 2026 15:29:38 +0200 Subject: [PATCH] Make the PassthroughWindow work correctly on iOS 26 As opposed to passing through all the touches; as per https://stackoverflow.com/a/79768998/730924 --- .../Application/Windowing/WindowManager.swift | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/ElementX/Sources/Application/Windowing/WindowManager.swift b/ElementX/Sources/Application/Windowing/WindowManager.swift index df7d3f55c..2808488bc 100644 --- a/ElementX/Sources/Application/Windowing/WindowManager.swift +++ b/ElementX/Sources/Application/Windowing/WindowManager.swift @@ -120,19 +120,35 @@ class WindowManager: SecureWindowManagerProtocol { private class PassthroughWindow: UIWindow { override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { - guard let hitView = super.hitTest(point, with: event) else { + if #available(iOS 26, *) { + // Passthrough UIWindow using SwiftUI in iOS 26 + // https://stackoverflow.com/a/79835964/730924 + guard let rootView = rootViewController?.view else { + return nil + } + + // Special handling for glass buttons + // ".glass has a layer name of "@1" and and .glassProminent has a layer name of "@2"" + guard let name = rootView.layer.hitTest(point)?.name, !name.starts(with: "@") else { + return rootView + } + return nil + } else { + guard let hitView = super.hitTest(point, with: event) else { + return nil + } + + guard let rootViewController else { + return nil + } + + guard hitView != self else { + return nil + } + + // If the returned view is the `UIHostingController`'s view, ignore. + return rootViewController.view == hitView ? nil : hitView } - - guard let rootViewController else { - return nil - } - - guard hitView != self else { - return nil - } - - // If the returned view is the `UIHostingController`'s view, ignore. - return rootViewController.view == hitView ? nil : hitView } }