From fc14364016aecf95db3031db391e46674cc9713e Mon Sep 17 00:00:00 2001 From: Stefan Ceriu Date: Fri, 10 Nov 2023 12:57:19 +0200 Subject: [PATCH] =?UTF-8?q?Fix=20alerts=20presented=20by=20the=20user=20in?= =?UTF-8?q?dicator=20controller=20not=20being=20inter=E2=80=A6=20(#2056)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix alerts presented by the user indicator controller not being interactive * Add back attribution --- .../Application/Windowing/WindowManager.swift | 18 +++++++++++++----- .../Mocks/Generated/GeneratedMocks.swift | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/ElementX/Sources/Application/Windowing/WindowManager.swift b/ElementX/Sources/Application/Windowing/WindowManager.swift index db75d69ac..7eb77e462 100644 --- a/ElementX/Sources/Application/Windowing/WindowManager.swift +++ b/ElementX/Sources/Application/Windowing/WindowManager.swift @@ -25,6 +25,7 @@ protocol WindowManagerDelegate: AnyObject { @MainActor /// A window manager that supports switching between a main app window with an overlay and /// an alternate window to switch contexts whilst also preserving the main view hierarchy. +/// Heavily inspired by https://www.fivestars.blog/articles/swiftui-windows/ class WindowManager { weak var delegate: WindowManagerDelegate? @@ -40,13 +41,9 @@ class WindowManager { mainWindow = windowScene.keyWindow mainWindow.tintColor = .compound.textActionPrimary - overlayWindow = UIWindow(windowScene: windowScene) + overlayWindow = PassthroughWindow(windowScene: windowScene) overlayWindow.tintColor = .compound.textActionPrimary overlayWindow.backgroundColor = .clear - // We don't support user interaction on our indicators so disable interaction, to pass - // touches through to the main window. If this changes, there's another solution here: - // https://www.fivestars.blog/articles/swiftui-windows/ - overlayWindow.isUserInteractionEnabled = false overlayWindow.isHidden = false alternateWindow = UIWindow(windowScene: windowScene) @@ -74,3 +71,14 @@ class WindowManager { mainWindow.endEditing(true) } } + +private class PassthroughWindow: UIWindow { + override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + guard let hitView = super.hitTest(point, with: event) else { + return nil + } + + // If the returned view is the `UIHostingController`'s view, ignore. + return rootViewController?.view == hitView ? nil : hitView + } +} diff --git a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift index 5983abca2..9a62c6ce7 100644 --- a/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift +++ b/ElementX/Sources/Mocks/Generated/GeneratedMocks.swift @@ -1,4 +1,4 @@ -// Generated using Sourcery 2.1.1 — https://github.com/krzysztofzablocki/Sourcery +// Generated using Sourcery 2.1.2 — https://github.com/krzysztofzablocki/Sourcery // DO NOT EDIT // swiftlint:disable all