Skip to content

Commit 8e412a2

Browse files
committed
Fix AI chat internal link focus
1 parent 2385920 commit 8e412a2

3 files changed

Lines changed: 85 additions & 2 deletions

File tree

Planet/Views/Articles/ArticleAIChatView.swift

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4750,7 +4750,62 @@ struct ArticleAIChatView: View {
47504750
fallbackArticle: linkedArticle
47514751
)
47524752
}
4753-
// Keep the chat window open after navigating to a linked article
4753+
// Keep the chat window open after navigating to a linked article,
4754+
// but return focus to the main window so the article is visible.
4755+
focusMainPlanetWindow()
4756+
}
4757+
4758+
@MainActor
4759+
private func focusMainPlanetWindow() {
4760+
guard let mainWindow = mainPlanetWindow() else {
4761+
debugLog("focusMainPlanetWindow skipped: main Planet window not found")
4762+
return
4763+
}
4764+
focus(window: mainWindow)
4765+
DispatchQueue.main.asyncAfter(deadline: .now() + 0.15) {
4766+
focus(window: mainWindow)
4767+
}
4768+
}
4769+
4770+
@MainActor
4771+
private func mainPlanetWindow() -> NSWindow? {
4772+
if let window = PlanetMainWindowFocus.shared.window {
4773+
return window
4774+
}
4775+
4776+
let candidateWindows = NSApp.windows.filter { window in
4777+
guard window.delegate is ArticleAIChatWindowController == false,
4778+
window is PlanetAIChatWindow == false,
4779+
window.windowController is ArticleAIChatWindowController == false,
4780+
window.windowController is PlanetAIChatWindowController == false
4781+
else {
4782+
return false
4783+
}
4784+
return true
4785+
}
4786+
4787+
if let window = candidateWindows.first(where: { $0.identifier?.rawValue == "planetMainWindow" }) {
4788+
return window
4789+
}
4790+
4791+
if let window = candidateWindows.first(where: { $0.className == "SwiftUI.AppKitWindow" }) {
4792+
return window
4793+
}
4794+
4795+
return candidateWindows.first(where: { $0.title == "Planet" })
4796+
}
4797+
4798+
@MainActor
4799+
private func focus(window: NSWindow) {
4800+
if window.isMiniaturized {
4801+
window.deminiaturize(nil)
4802+
}
4803+
if #available(macOS 14.0, *) {
4804+
NSApp.activate()
4805+
} else {
4806+
NSApp.activate(ignoringOtherApps: true)
4807+
}
4808+
window.makeKeyAndOrderFront(nil)
47544809
}
47554810

47564811
private func encodeToDictionary<T: Encodable>(_ value: T) throws -> [String: Any] {

Planet/Views/PlanetMainView.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,33 @@
77

88
import SwiftUI
99

10+
@MainActor
11+
final class PlanetMainWindowFocus {
12+
static let shared = PlanetMainWindowFocus()
13+
14+
weak var window: NSWindow?
15+
16+
private init() {}
17+
}
18+
19+
private struct PlanetMainWindowReader: NSViewRepresentable {
20+
func makeNSView(context: Context) -> PlanetMainWindowReaderView {
21+
PlanetMainWindowReaderView()
22+
}
23+
24+
func updateNSView(_ nsView: PlanetMainWindowReaderView, context: Context) {
25+
if let window = nsView.window {
26+
PlanetMainWindowFocus.shared.window = window
27+
}
28+
}
29+
}
30+
31+
private final class PlanetMainWindowReaderView: NSView {
32+
override func viewDidMoveToWindow() {
33+
super.viewDidMoveToWindow()
34+
PlanetMainWindowFocus.shared.window = window
35+
}
36+
}
1037

1138
struct PlanetMainView: View {
1239
@EnvironmentObject var planetStore: PlanetStore
@@ -26,6 +53,7 @@ struct PlanetMainView: View {
2653
ArticleView()
2754
.edgesIgnoringSafeArea(.vertical)
2855
}
56+
.background(PlanetMainWindowReader())
2957
.alert(isPresented: $planetStore.isShowingAlert) {
3058
Alert(
3159
title: Text(planetStore.alertTitle),

Planet/versioning.xcconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
CURRENT_PROJECT_VERSION = 2754
1+
CURRENT_PROJECT_VERSION = 2755

0 commit comments

Comments
 (0)