4

Three operating modes of macOS application

 2 years ago
source link: https://www.logcg.com/archives/3531.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
最近更新:9th 11月, 2021

通常,你不会遇到这个问题,直到你需要写一个后台程序……

我们都知道 macOS 有一个全局的 Dock,这个东西上会显示所有正在运行的程序,但如果你的程序是一个菜单栏小程序,或者是一个……输入法,那你肯定不想让这个 app 的图标显示的 Dock 上,因为这类 app 是要持续在后台运行的。

这时候我们就可以在 Info.plist 中写 LSBackgroundOnly 字段,这样这个 app 就会在后台运行,没有 Dock 图标,也不会在 cmd+tab 的切换选项中显示出来了。落格输入法就是这么做的,这也是苹果官方示例中的配置——但这么做长久以来伴随着一个问题,那就是如果你这个 app 还是需要显示必要的设置界面的话,那这个界面会永远在所有窗口的最下方,也就是说,窗口一弹出就立即被挡住了。甚至,除了标准窗口,其他任何警告弹窗,都是无法显示的,除非先有一个标准窗口出现,且用户点击了一下该窗口的任何位置……

上文这些前提导致了很多问题,我不得不内嵌另外一个 app 来作为落格输入法的专门设置软件,然后两者之间使用 xpc 通信,真的是令人绝望。

直到今天 TIL,我发现原来可以使用 NSApplication.shared.setActivationPolicy(.accessory) 在程序中动态改变自己的运行级别,可以动态修改自己为普通 regular 模式,或者是后台 prohibited 模式。显然,通过看代码名称也明白了,原来这个后台模式,是故意不允许弹出窗口的。

/* The application does not appear in the Dock and may not create windows or be activated.  This corresponds to LSBackgroundOnly=1 in the Info.plist.  This is also the default for unbundled executables that do not have Info.plists. */
        case prohibited = 2

显然,如果你声明程序是后台程序,那它的一切窗口都是不能获得焦点的,这个问题我一直以来以为是 macOS 的Bug😅

那么,有没有别的方案呢?还真的有,除了上文的两种模式外,macOS 其实还提供了介于两者中间的模式,既像后台程序那样不显示图标,又能在必要的时候获取焦点和类似普通程序那样弹窗:

/* The application does not appear in the Dock and does not have a menu bar, but it may be activated programmatically or by clicking on one of its windows.  This corresponds to LSUIElement=1 in the Info.plist. */
        case accessory = 1

在必要的时候动态切换程序的运行模式为 accessory 即可。


当然,如果用代码太麻烦,我们也可以直接改 Info.plist,把 LSBackgroundOnly ,改为 LSUIElement ,即可。

本文由 落格博客 原创撰写:落格博客 » macOS application 的三种运行模式

转载请保留出处和原文链接:https://www.logcg.com/archives/3531.html


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK