mirror of
https://github.com/abue-ammar/tinycast.git
synced 2026-10-02 08:14:38 +08:00
fix flick issue
This commit is contained in:
@@ -152,33 +152,27 @@ final class AppCore: ObservableObject {
|
||||
showPalette(mode: .launcher, restoreAnyMode: true)
|
||||
}
|
||||
|
||||
/// Settings runs in its own window (the SwiftUI `Settings` scene is unreliable for accessory apps), raised via the same controller as About.
|
||||
func showSettings() {
|
||||
auxWindows.show(
|
||||
/// Settings runs in its own window (the SwiftUI `Settings` scene is unreliable for accessory apps). A fresh window mounts directly on `tab` (no first-frame flicker); an already-open one is switched in place.
|
||||
func showSettings(tab: SettingsTab = .general) {
|
||||
let isNew = auxWindows.show(
|
||||
id: "settings", title: "Settings", size: CGSize(width: 720, height: 650),
|
||||
seamlessTitleBar: true
|
||||
) {
|
||||
SettingsRootView()
|
||||
SettingsRootView(initialTab: tab)
|
||||
.environmentObject(self.appIndex)
|
||||
.environmentObject(self.visibility)
|
||||
}
|
||||
if !isNew {
|
||||
NotificationCenter.default.post(name: .tinycastSelectSettingsTab, object: tab)
|
||||
}
|
||||
}
|
||||
|
||||
/// Open Settings on the Backup pane (used by the "Import from Raycast" command, which needs the passphrase field).
|
||||
func showBackupSettings() {
|
||||
showSettings()
|
||||
// Post on the next runloop so the freshly-mounted pane's observer is already listening.
|
||||
DispatchQueue.main.async {
|
||||
NotificationCenter.default.post(name: .tinycastShowBackupSettings, object: nil)
|
||||
}
|
||||
showSettings(tab: .backup)
|
||||
}
|
||||
|
||||
/// About lives as a pane inside Settings now, so this opens Settings and switches to it.
|
||||
func showAbout() {
|
||||
showSettings()
|
||||
DispatchQueue.main.async {
|
||||
NotificationCenter.default.post(name: .tinycastShowAbout, object: nil)
|
||||
}
|
||||
showSettings(tab: .about)
|
||||
}
|
||||
|
||||
/// The first-run wizard: palette shortcut, Accessibility, Raycast import. Also re-runnable from Settings.
|
||||
|
||||
@@ -112,14 +112,19 @@ private struct AboutLinkButton: View {
|
||||
final class AuxWindowController: NSObject, NSWindowDelegate {
|
||||
private var windows: [String: NSWindow] = [:]
|
||||
|
||||
/// Returns `true` when a new window was created, `false` when an existing one was re-raised.
|
||||
@discardableResult
|
||||
func show<Content: View>(
|
||||
id: String, title: String, size: CGSize, seamlessTitleBar: Bool = false,
|
||||
@ViewBuilder content: () -> Content
|
||||
) {
|
||||
) -> Bool {
|
||||
let window: NSWindow
|
||||
let isNew: Bool
|
||||
if let existing = windows[id] {
|
||||
window = existing
|
||||
isNew = false
|
||||
} else {
|
||||
isNew = true
|
||||
var style: NSWindow.StyleMask = [.titled, .closable]
|
||||
if seamlessTitleBar { style.insert(.fullSizeContentView) }
|
||||
window = NSWindow(
|
||||
@@ -153,6 +158,7 @@ final class AuxWindowController: NSObject, NSWindowDelegate {
|
||||
DispatchQueue.main.async {
|
||||
window.makeKeyAndOrderFront(nil)
|
||||
}
|
||||
return isNew
|
||||
}
|
||||
|
||||
/// Re-focus an open aux window on reopen (Dock-icon click); returns false when none is open. `windows` only holds live windows (`windowWillClose` prunes them).
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import SwiftUI
|
||||
|
||||
extension Notification.Name {
|
||||
static let tinycastShowSettings = Notification.Name("TinycastShowSettings")
|
||||
static let tinycastShowBackupSettings = Notification.Name("TinycastShowBackupSettings")
|
||||
static let tinycastShowAbout = Notification.Name("TinycastShowAbout")
|
||||
/// Switch an already-open Settings window to a pane (object: the target `SettingsTab`).
|
||||
static let tinycastSelectSettingsTab = Notification.Name("TinycastSelectSettingsTab")
|
||||
}
|
||||
|
||||
private enum SettingsTab: Int, CaseIterable, Identifiable {
|
||||
enum SettingsTab: Int, CaseIterable, Identifiable {
|
||||
case general, clipboard, emoji, permissions, shortcuts, backup, about
|
||||
var id: Int { rawValue }
|
||||
|
||||
@@ -49,7 +48,11 @@ private enum SettingsTab: Int, CaseIterable, Identifiable {
|
||||
}
|
||||
|
||||
struct SettingsRootView: View {
|
||||
@State private var tab: SettingsTab = .general
|
||||
@State private var tab: SettingsTab
|
||||
|
||||
init(initialTab: SettingsTab = .general) {
|
||||
_tab = State(initialValue: initialTab)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 0) {
|
||||
@@ -75,14 +78,8 @@ struct SettingsRootView: View {
|
||||
)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||
.onReceive(NotificationCenter.default.publisher(for: .tinycastShowSettings)) { _ in
|
||||
tab = .general
|
||||
}
|
||||
.onReceive(NotificationCenter.default.publisher(for: .tinycastShowBackupSettings)) { _ in
|
||||
tab = .backup
|
||||
}
|
||||
.onReceive(NotificationCenter.default.publisher(for: .tinycastShowAbout)) { _ in
|
||||
tab = .about
|
||||
.onReceive(NotificationCenter.default.publisher(for: .tinycastSelectSettingsTab)) { note in
|
||||
if let target = note.object as? SettingsTab { tab = target }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user