[英]Transform LSUIElement to foreground application
我有一個必須一直運行的應用程序(如果用戶同意這一點)。
當用戶退出應用程序時,我將前台應用程序轉換為 LSUIElement(應用程序只有一個菜單欄圖標,停靠欄圖標和菜單消失)。
我在菜單項中有一個選項可以正常工作並將 LSUIElement 轉換為前台應用程序(我使用功能[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]
和[NSApp activateIgnoringOtherApps:YES]
)。
當用戶雙擊應用程序時出現我的問題。 我再次使用委托方法applicationWillUnhide:(NSNotification *)notification
的[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]
,除了沒有出現的菜單外,一切正常。 如果我去另一個應用程序,然后我回來了菜單出現。 我嘗試了不同的方法,但找不到好的方法。
我想知道是在用戶雙擊應用程序時調用的委托方法,或者在那一刻調用的NSApplication
函數是什么,因為我認為在applicationWillUnhide
函數中使用setActivationPolicy:
已晚。
要將普通應用程序轉換為我使用的 LSUIElement
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToUIElementApplication);
並將其改回前台:
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
這是答案。 在找到這個問題之前,我已經完成了隱藏/顯示。 這個問題激發了我的最終答案。
以下代碼的作用如下:
我已經刪除了其他不直接相關的代碼。
您可能會注意到的其他事項:
代碼:
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)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.