SwiftUI-WindowManagement

The WindowManagement package allows you to control window behaviors of SwiftUI Scenes without doing weird tricks. Views can also access the NSWindow through the Environment.

Scene Modifiers

View Modifiers

Example

Scherm­afbeelding 2023-01-06 om 21 45 28

Notice

This package uses and modifies some internals of SwiftUI. As SwiftUI changes frequently, implementations might break.

Note: DocumentGroup is not supported (yet)

Compatibility

  • macOS 12.0 (Untested, but should work)
  • macOS 13.0+

Available Scene modifiers

register

This modifier enables the modification of the underlying NSWindow for this scene. It should always be called before any of the other modifiers. The identifier must be the same as the one set in the Scene initializer. For the Settings Scene, use registerSettingsWindow.

func register(_ identifier: String)

func registerSettingsWindow()

movableByBackground

Indicates whether the window can be moved by clicking and dragging its background.

func movableByBackground(_ value: Bool)

movable

Indicates whether the view can be moved.

func movable(_ value: Bool)

styleMask

Apply a certain stylemask to the window. Note that NSWindow.StyleMask.titled is always included, otherwise SwiftUI will crash.

func styleMask(_ styleMask: NSWindow.StyleMask)

windowButton

Indicated whether a window button should be enabled or not. If disabled, the button will be greyed out but still visible. The keyboard shortcut of the button won’t be active. Use windowButton(_:hidden:) to hide a window button.

func windowButton(_ button: NSWindow.ButtonType, enabled: Bool)

Indicated whether a window button should be hidden or not. A hidden button can still be triggered with it’s keyboard shortcut, e.g. Cmd+w for closing a window. Use windowButton(_:hidden:) to disable a window button.

func windowButton(_ button: NSWindow.ButtonType, hidden: Bool)

collectionBehavior

Apply a certain collectionBehavior to the window.

func collectionBehavior(_ behavior: NSWindow.CollectionBehavior)

tabbingMode

Set the tabbingMode for the window. If set to preferred, new windows will be opened as tabs.

func tabbingMode(_ mode: NSWindow.TabbingMode)

backgroundColor

Sets the background color of the window.

func backgroundColor(_ color: NSColor)

titlebarAppearsTransparent

Makes the titlebar transparent.

func titlebarAppearsTransparent(_ value: Bool)

disableRestoreOnLaunch

This will stop windows from relaunching if they were open in the last active app state.

Note: While this should work fine, I can’t guarantee it.

func disableRestoreOnLaunch()

Available View modifiers

Inject the current window into the environment.

func injectWindow(_ identifier: String)

Inject the settings window into the environment.

func injectSettingsWindow()

Get the NSWindow from a View.

@Environment(\.window) var window

Example

The following code shows the implementation of the window shown above.

import SwiftUI
import WindowManagement

@main
struct MyApp: App {

    var body: some Scene {
        WindowGroup(id: "MyWindow") {
            ContentView()
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(.regularMaterial)
            .injectWindow("MyWindow")
        }
        .register("MyWindow")
        .titlebarAppearsTransparent(true)
        .windowToolbarStyle(.unifiedCompact(showsTitle: false))
        .movableByBackground(true)
        .backgroundColor(.systemGray.withAlphaComponent(0.001)) // Don't use .clear, causes glitches.
        .styleMask([.closable, .fullSizeContentView, .resizable])
        .windowButton(.miniaturizeButton, hidden: true)
        .windowButton(.zoomButton, hidden: true)
    }
}

struct ContentView: View {
    @Environment(\.window) var window
    var body: some View {
        Text("This windows identifier is \(window.identifier?.rawValue ?? "")")
        Button("Hide this window") {
            window.orderOut(nil)
        }
    }
}

GitHub

View Github