在開發落格輸入法 macOS 版本的時候,我遇到了這麼一個難題,那就是窗口優先級的問題。在之前 如何讓 NSWindow 顯示在不同的 Space 或者 Screen 中 這篇文章中我提到了自己實現了落格輸入法的候選欄,其實是用一個 NSWindow 實現的。那麼既然是一個普通(經過魔改)的 窗口 ,它就和其他的窗口一樣擁有一個優先級,也就是 窗口.水平 它決定了你桌面上顯示的窗口之間的層疊關係,簡而言之,就是兩個窗口重疊的話,優先級高的會顯示給你看,而優先級低的則被“擋”在後邊。
那麼問題就來了,這個 水平 該設置為多少呢?現在 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 } |
那我們可以根據名字來猜測 ——當然實踐證明 屏幕保護 是最高級的,也就是屏保級別,這樣就已經可以讓輸入法的候選欄顯示在比如 Spotlight 條條上面了。
不過,有一個問題,如果用戶是在玩一個全屏遊戲呢?
這時候這個遊戲可能也用的是這個 屏幕保護 級別,那你就 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
搜嘎!怪不得這麼快就修復了呢~
雖然只有一行代碼,但背後的努力可不止一分鐘~