MenuBarExtraAccess

repository·main·Indexed 42 days ago

https://github.com/orchetect/menubarextraaccess

A library providing extended programmatic control over SwiftUI's MenuBarExtra. It allows developers to toggle visibility, enable or disable the extra, and access underlying NSStatusItem and NSWindow instances via the .menuBarExtraAccess and .introspectMenuBarExtraWindow modifiers.

Tokens
1.1K
Snippets
4
Records
5
Agent score
3%

What's inside MenuBarExtraAccess

  1. How MenuBarExtraAccess works with different styles

    main

    The library supports both menu and window based styles, but they behave differently due to SwiftUI limitations:

    • Provides access to the NSWindow via .introspectMenuBarExtraWindow.
    • Status items remain highlighted while the window is open, providing a native feel.
    • Known Limitation: When using the .menu style, SwiftUI causes the popup menu to block the runloop while open.
    • Consequences:
      • Observing the isPresented binding will not work as expected.
      • Setting isPresented to false while the menu is open has no effect.
      • The user must manually dismiss the menu to allow event flow to continue.
  2. Complete usage example for MenuBarExtraAccess

    main

    This example demonstrates how to combine visibility control, enablement control, status item access, and window introspection in a single App struct.

    @main struct MyApp: App {
        @State var isMenuPresented: Bool = false
        @State var isMenuEnabled: Bool = true
        @State var statusItem: NSStatusItem?
    
        var body: some Scene {
            MenuBarExtra("My App") {
                MenuView()
                    .introspectMenuBarExtraWindow { window in
                        // if using `.window` MenuBarExtra style, optionally set up NSWindow
                    }
            }
            .menuBarExtraAccess(
                isPresented: $isMenuPresented, 
                isEnabled: $isMenuEnabled // if omitted, defaults to `.constant(true)`
            ) { statusItem in
                // optionally set up NSStatusItem, or store its reference in a state var
                self.statusItem = statusItem
            }
            .menuBarExtraStyle(.window)
        }
    }
  3. Use the .menuBarExtraAccess scene modifier

    main

    The .menuBarExtraAccess modifier provides programmatic control over a MenuBarExtra scene. It allows you to:

    • Toggle visibility: Use the isPresented binding to hide, show, or toggle the menu.
    • Enable/Disable: Use the isEnabled binding to enable or disable the menubar extra. If omitted, it defaults to .constant(true).
    • Access NSStatusItem: The trailing closure provides direct access to the underlying NSStatusItem instance.

    This modifier is Mac App Store safe as it does not use private APIs.

    @State var isMenuPresented: Bool = false
    @State var isMenuEnabled: Bool = true
    @State var statusItem: NSStatusItem?
    
    // ... inside body ...
    MenuBarExtra("My App") {
        MenuView()
    }
    .menuBarExtraAccess(
        isPresented: $isMenuPresented, 
        isEnabled: $isMenuEnabled
    ) { statusItem in
        self.statusItem = statusItem
    }
  4. Access the NSWindow using .introspectMenuBarExtraWindow

    main

    When using the .menuBarExtraStyle(.window) style for a MenuBarExtra, you can access the underlying NSWindow instance by applying the .introspectMenuBarExtraWindow view modifier to the content inside the MenuBarExtra block.

    MenuBarExtra("My App") {
        MenuView()
            .introspectMenuBarExtraWindow { window in
                // Use the NSWindow reference here
            }
    }
    .menuBarExtraStyle(.window)