在开发落格输入法 macOS 版本的时候,我遇到了这么一个难题,那就是窗口优先级的问题。在之前 如何让 NSWindow 显示在不同的 Space 或者 Screen 中 这篇文章中我提到了自己实现了落格输入法的候选栏,其实是用一个 NSWindow 实现的。那么既然是一个普通(经过魔改)的 Window ,它就和其他的窗口一样拥有一个优先级,也就是 window.level 它决定了你桌面上显示的窗口之间的层叠关系,简而言之,就是两个窗口重叠的话,优先级高的会显示给你看,而优先级低的则被“挡”在后边。
那么问题就来了,这个 level 该设置为多少呢?现在 Swift 中是不显示实际的值的,具体声明如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
extension NSWindow.Level { public static let normal: NSWindow.Level public static let floating: NSWindow.Level public static let submenu: NSWindow.Level public static let tornOffMenu: NSWindow.Level public static let mainMenu: NSWindow.Level public static let statusBar: NSWindow.Level @available(OSX, introduced: 10.0, deprecated: 10.13) public static let dock: NSWindow.Level public static let modalPanel: NSWindow.Level public static let popUpMenu: NSWindow.Level public static let screenSaver: NSWindow.Level } |
那我们可以根据名字来猜测 ——当然实践证明 screenSaver 是最高级的,也就是屏保级别,这样就已经可以让输入法的候选栏显示在比如 Spotlight 条条上面了。
不过,有一个问题,如果用户是在玩一个全屏游戏呢?
这时候这个游戏可能也用的是这个 screenSaver 级别,那你就 GG 了,我们必须寻求更高的级别,比如这个是 1000 的话,那么我们来个 99999999 岂不妙哉?
当然,这就不能通过普通的窗口优先级里获取了,我们用到这个 API:
1 2 3 4 5 |
/* Returns the window level of the shield window for the captured display `display'. */ @available(OSX 10.0, *) public func CGShieldingWindowLevel() -> CGWindowLevel |
这样候选条就始终会在所有窗口上方了。
那么具体的实现就是这样的:
1 |
window.level = NSWindow.Level(rawValue: NSWindow.Level.RawValue(CGShieldingWindowLevel())) |
本文由 落格博客 原创撰写:落格博客 » 避免输入法 候选条 被其他窗口挡住
转载请保留出处和原文链接:https://www.logcg.com/archives/2854.html
搜嘎!怪不得这么快就修复了呢~
虽然只有一行代码,但背后的努力可不止一分钟~