From 20597e6e8888efba059f02cf1393032c30a1553f Mon Sep 17 00:00:00 2001 From: cdricms <36056008+cdricms@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:19:26 +0200 Subject: [PATCH] fix(apple): enforce a single window on macOS and iPadOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit macOS uses a single-instance `Window` scene instead of `WindowGroup`, which otherwise lets the app open multiple windows (via ⌘N). iPadOS sets `UIApplicationSupportsMultipleScenes = false` to block a second scene via Stage Manager / split view. (`LSMultipleInstancesProhibited` only blocks a second process, not a second window.) --- apple/VniDrop/App/VniDropApp.swift | 15 ++++++++++++++- apple/VniDrop/Resources/Info.plist | 4 ++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/apple/VniDrop/App/VniDropApp.swift b/apple/VniDrop/App/VniDropApp.swift index 0119980..3882b17 100644 --- a/apple/VniDrop/App/VniDropApp.swift +++ b/apple/VniDrop/App/VniDropApp.swift @@ -1,5 +1,8 @@ import SwiftUI +/// Scene identifier for the single main window. +private let mainWindowId = "main" + /// Native app entry point for iOS, iPadOS, and macOS. /// Opens `.vnd` invitations via `onOpenURL` and routes them to the receive flow. @main @@ -7,11 +10,21 @@ struct VniDropApp: App { @StateObject private var externalInvitations = ExternalInvitationController() var body: some Scene { - WindowGroup { + #if os(macOS) + // A single-instance `Window` (not `WindowGroup`): the app must never open a + // second window. `Window` also drops the ⌘N "New Window" command. + Window(Text(verbatim: "VniDrop"), id: mainWindowId) { RootView(dependencies: makeAppDependencies(externalInvitations: externalInvitations)) .ignoresSafeArea() .onOpenURL(perform: openInvitation) } + #else + WindowGroup(id: mainWindowId) { + RootView(dependencies: makeAppDependencies(externalInvitations: externalInvitations)) + .ignoresSafeArea() + .onOpenURL(perform: openInvitation) + } + #endif } /// Reads a `.vnd` invitation document under a security scope, enforcing the diff --git a/apple/VniDrop/Resources/Info.plist b/apple/VniDrop/Resources/Info.plist index 9ef9fc8..a2613e4 100644 --- a/apple/VniDrop/Resources/Info.plist +++ b/apple/VniDrop/Resources/Info.plist @@ -67,6 +67,10 @@ VniDrop uses the camera to scan transfer QR codes. NSLocalNetworkUsageDescription VniDrop needs local network access to send to other local devices if needed. + + UIApplicationSupportsMultipleScenes + UIBackgroundModes fetch