我有一个必须一直运行的应用程序(如果用户同意这个)。
当用户退出应用程序时,我将前台应用程序转换为LSUIElement(应用程序只有一个菜单栏图标,停靠栏图标和菜单消失)。
我在菜单项中有一个选项可以正常运行并将LSUIElement转换为前台应用程序(我使用函数[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]
和[NSApp activateIgnoringOtherApps:YES]
)。
用户双击应用时出现我的问题。我再次使用委托方法[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]
中的applicationWillUnhide:(NSNotification *)notification
,除了没有出现的菜单外,一切正常。如果我去另一个应用程序,然后我回来了菜单出现。我尝试了不同的方法,但我找不到好的方法。
我想知道的是当用户双击应用程序时调用的委托方法,或者当时调用NSApplication
的函数是什么,因为我认为使用{{1} } setActivationPolicy:
函数是迟到的。
答案 0 :(得分:1)
要将普通应用程序转换为LSUIElement,请使用
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToUIElementApplication);
并将其更改回前景:
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
答案 1 :(得分:0)
这是答案。在找到这个问题之前,我已经完成了隐藏/显示。这个问题启发了我最终的答案。
这是以下代码的作用:
我删除了其他不直接相关的代码。
您可能会注意到的其他事项:
代码:
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
private let statusItem = NSStatusBar.system.statusItem(withLength:NSStatusItem.squareLength)
weak private var window:NSWindow? = nil
func applicationDidFinishLaunching(_ aNotification: Notification) {
setupMenubarTray()
self.window = NSApp.orderedWindows.first
NotificationCenter.default.addObserver(self, selector: #selector(windowWillClose(_:)), name: NSWindow.willCloseNotification, object: self.window!)
}
func applicationShouldHandleReopen(_ sender: NSApplication, hasVisibleWindows flag: Bool) -> Bool {
if !window!.isVisible {
activeApp()
return false
}
return true
}
}
extension AppDelegate {
@objc func windowWillClose(_ noti:Notification) {
removeFromDock()
}
private func showInDock() {
NSApp.setActivationPolicy(.regular)
}
private func removeFromDock() {
NSApp.setActivationPolicy(.accessory)
}
}
// MARK: - setup menubar button
extension AppDelegate {
private func setupMenubarTray() {
guard let button = statusItem.button else {
fatalError()
}
setTrayIcon(for:button)
button.action = #selector(mouseLeftButtonClicked)
}
private func setTrayIcon(for button:NSStatusBarButton) {
let useMonochromeIcon = UserDefaults.standard.bool(forKey: DefaultsKey.useMonochromeIcon.key)
button.image = NSImage(imageLiteralResourceName: useMonochromeIcon ? "MonochromeIcon" : "TrayIcon")
}
@objc private func mouseLeftButtonClicked() {
if NSApp.isHidden || !window!.isKeyWindow {
self.activeApp()
} else {
self.hide()
}
}
private func activeApp() {
showInDock()
window?.makeKeyAndOrderFront(nil)
NSApp.activate(ignoringOtherApps: true)
checker.sendNotification()
}
private func hide() {
removeFromDock()
NSApp.hide(nil)
}
}