简体   繁体   中英

macOS NSPopover menu bar app how to prioritize order app is displayed

I have a macOS menu bar app. I like to know can we prioritize the order that the app shows in the status bar.

//
//  AppDelegate.swift
//  elmc_midi_deck-macOS
//
//  Created by Jerry Seigle on 6/23/22.
//

import Foundation
import Cocoa

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
  var popover: NSPopover!
  var window: NSWindow!
  var statusBarItem: NSStatusItem!

  func applicationDidFinishLaunching(_ aNotification: Notification) {
    let jsCodeLocation: URL

    #if DEBUG
      jsCodeLocation = RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index", fallbackResource:nil)
    #else
      jsCodeLocation = Bundle.main.url(forResource: "main", withExtension: "jsbundle")!
    #endif
    let rootView = RCTRootView(bundleURL: jsCodeLocation, moduleName: "elmc_midi_deck", initialProperties: nil, launchOptions: nil)
    let rootViewController = NSViewController()
    rootViewController.view = rootView

    popover = NSPopover()

    popover.contentSize = NSSize(width: 400, height: 600)
    popover.animates = true
    popover.behavior = .transient
    popover.contentViewController = rootViewController

    statusBarItem = NSStatusBar.system.statusItem(withLength: CGFloat(60))

    if let button = self.statusBarItem.button {
      button.action = #selector(togglePopover(_:))
      button.title = "elmc_midi_deck"
    }

    #if DEBUG
    window = NSWindow(
      contentRect: NSRect(x: 0, y: 0, width: 1, height: 1),
      styleMask: [.titled, .closable, .miniaturizable, .resizable],
      backing: .buffered,
      defer: false)

    window.contentViewController = rootViewController
    window.center()
    window.setFrameAutosaveName("ELMC Midi Deck")
    window.isReleasedWhenClosed = false
    window.makeKeyAndOrderFront(self)
    let screen: NSScreen = NSScreen.main!
    let midScreenX = screen.frame.midX
    let posScreenY = 200
    let origin = CGPoint(x: Int(midScreenX), y: posScreenY)
    let size = CGSize(width: 400, height: 600)
    let frame = NSRect(origin: origin, size: size)
    window.setFrame(frame, display: true)
    #endif
  }

  @objc func togglePopover(_ sender: AnyObject?) {
    if let button = self.statusBarItem.button {
      if self.popover.isShown {
        self.popover.performClose(sender)
      } else {
        self.popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)

        self.popover.contentViewController?.view.window?.becomeKey()
      }
    }
  }
}


Currently the app will show at the far left once started. Of course you can command click and drag left to right but I like to make the app show after Apple's default apps like show in the photo

在此处输入图像描述

As mentioned in this post , you can use this library to do this. The library allows defining the position for an NSStatusBarItem inside the NSStatusBar . It is written in Objective-C and available via CocoaPods, you probably have to create a bridging header or manually convert it in order to use it in Swift. Refer to this post for details on how to do this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM