首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将LSUIElement转换为前台应用程序

将LSUIElement转换为前台应用程序
EN

Stack Overflow用户
提问于 2012-10-15 21:58:34
回答 2查看 1K关注 0票数 1

我有一个应用程序,必须运行所有的时间(如果用户同意这一点)。

当用户退出应用程序时,我将前台应用程序转换为LSUIElement (应用程序只有一个菜单栏图标,停靠图标和菜单消失)。

我在菜单项中有一个选项,可以正常工作,并将LSUIElement转换为前台应用程序(我使用函数[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular][NSApp activateIgnoringOtherApps:YES])。

当用户双击应用程序时,我的问题就出现了。我再次使用了委托方法applicationWillUnhide:(NSNotification *)notification中的[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular],除了没有出现的菜单之外,其他的都工作得很好。如果我转到另一个应用程序,然后我回来了,菜单就会出现。我尝试了不同的方法,但我找不到一个好的。

我想知道的是当用户双击应用程序时调用的委托方法,或者在那一刻调用的NSApplication函数是什么,因为我认为在applicationWillUnhide函数中使用setActivationPolicy:为时已晚。

EN

回答 2

Stack Overflow用户

发布于 2012-10-15 23:50:44

为了将普通应用程序转换为LSUIElement,我使用了

代码语言:javascript
复制
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToUIElementApplication);

并将其改回前台:

代码语言:javascript
复制
ProcessSerialNumber psn = { 0, kCurrentProcess };
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
票数 0
EN

Stack Overflow用户

发布于 2020-01-05 09:35:09

这就是答案。在我找到这个问题之前,我已经做了隐藏/显示。这个问题让我得到了最终的答案。

下面的代码实现了以下功能:

  1. 当应用程序启动时,应用程序将显示在停靠中,并显示菜单栏项目。
  2. 当用户单击菜单栏项目时,应用程序将隐藏并从停靠中删除。
  3. 当用户再次单击时,应用程序将重新显示为停靠状态。
  4. 如果应用程序处于隐藏状态,并且用户通过双击或启动面板再次打开应用程序,则应用程序将再次显示在停靠状态。
  5. 如果应用程序不是隐藏的,而是被其他应用程序遮挡的,则单击菜单栏项目或重新启动它将使应用程序显示在最前面。当用户单击窗口上的关闭按钮时,应用程序已从dock中删除。
  6. 当用户通过cmd+q或从文件菜单退出应用程序时,应用程序将退出,菜单栏项目也将退出。

我已经删除了其他不直接相关的代码。

你可能会注意到的其他事情:

my Info.plist的

  1. LSUIElement未设置或设置为NO。如果您想要设置为yes。你需要在故事板中设置没有初始化视图控制器,并从窗口控制器中构造yourself.
  2. You也将处理从鼠标左键点击菜单栏项目开始的逻辑,因为你从一开始就没有窗口。

代码:

代码语言:javascript
复制
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)
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12897214

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档