Commit cb8d11b3 authored by Kourser's avatar Kourser
Browse files

fix(macos): reopen the main window from the Fenêtre menu and the Dock

Replacing the .newItem command group to free ⌘N also dropped SwiftUI's
"Nouvelle fenêtre" item — the only way back once the main window was
closed, since the Fenêtre menu merely lists already-open windows. The app
stayed alive in the Dock with no reachable UI (App Review, guideline 4).

Give the WindowGroup an id, list it in the Fenêtre menu (⌘0), and handle
applicationShouldHandleReopen so the Dock icon brings the window back.

Co-Authored-By: default avatarClaude Opus 5 <noreply@anthropic.com>
parent 46f169ca
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -10,6 +10,8 @@ import PlaybackKit
final class MacAppDelegate: NSObject, NSApplicationDelegate {
    /// Wired by the app once the playback controller exists.
    static weak var playback: PlaybackController?
    /// Wired by the app; re-opens the main window scene.
    static var openMainWindow: (() -> Void)?
    /// Keeps the Touch Bar controller (and its data sources) alive.
    private static var touchBarController: TouchBarController?
    private var spaceKeyMonitor: Any?
@@ -33,6 +35,13 @@ final class MacAppDelegate: NSObject, NSApplicationDelegate {
        }
    }

    /// Clicking the Dock icon with every window closed must bring the app
    /// back, not just activate an empty menu bar.
    func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
        if !flag { Self.openMainWindow?() }
        return true
    }

    func applicationDockMenu(_ sender: NSApplication) -> NSMenu? {
        guard let playback = Self.playback, playback.currentEpisode != nil else { return nil }
        let menu = NSMenu()
+29 −1
Original line number Diff line number Diff line
@@ -12,8 +12,13 @@ struct SkingomzApp: App {
    @State private var nowPlaying: NowPlayingCoordinator?
    @State private var didConfigure = false

    /// Identifies the single main window, so the Fenêtre menu (and the Dock
    /// icon) can re-open it once the user has closed it.
    static let mainWindowID = "main"

    #if os(macOS)
    @NSApplicationDelegateAdaptor(MacAppDelegate.self) private var appDelegate
    @Environment(\.openWindow) private var openWindow
    #endif

    init() {
@@ -22,7 +27,7 @@ struct SkingomzApp: App {
    }

    var body: some Scene {
        WindowGroup {
        WindowGroup(id: Self.mainWindowID) {
            RootView()
                .environment(model)
                .environment(playback)
@@ -46,6 +51,7 @@ struct SkingomzApp: App {
                    nowPlaying = NowPlayingCoordinator(controller: playback, settings: playbackSettings)
                    #if os(macOS)
                    MacAppDelegate.playback = playback
                    MacAppDelegate.openMainWindow = { openWindow(id: Self.mainWindowID) }
                    MacAppDelegate.installTouchBar(
                        TouchBarController(model: model, playback: playback,
                                           settings: playbackSettings, commands: commandCenter)
@@ -64,6 +70,14 @@ struct SkingomzApp: App {
            CommandGroup(replacing: .newItem) {
                AddCommands(commands: commandCenter)
            }
            #if os(macOS)
            // Replacing .newItem above removed "Nouvelle fenêtre", which was
            // the only way back once the main window is closed — the Fenêtre
            // menu merely lists the windows that are already open.
            CommandGroup(after: .windowList) {
                MainWindowCommand(id: Self.mainWindowID)
            }
            #endif
            CommandMenu("Lecture") {
                // A child view, so the menu observes the playback state
                // (labels and enabled/disabled update live).
@@ -93,6 +107,20 @@ struct SkingomzApp: App {

}

#if os(macOS)
/// Re-opens the main window from the Fenêtre menu. A child view so the
/// openWindow action is resolved from the environment.
private struct MainWindowCommand: View {
    let id: String
    @Environment(\.openWindow) private var openWindow

    var body: some View {
        Button("Skingomz") { openWindow(id: id) }
            .keyboardShortcut("0")
    }
}
#endif

/// Fichier menu additions (⌘N, ⇧⌘N, ⌘O), bridged to RootView's sheets.
private struct AddCommands: View {
    let commands: CommandCenter