如何讓 NSWindow 顯示在不同的 Space 或者 Screen 中

在寫落格輸入法 Mac 版的過程當中,我遇到了這麼一個問題,系統的候選條 API 年久失修,很多功能 API 存在但根本無效,比如:

這個方法是用來設置候選條風格的,裡邊除了默認的 IMKCandidatesSendServerKeyEventFirst 這個能生效外,其他的一概無視。

這就尷尬了,現在平明動輒高分4k要么就視網膜,默認的16號候選字體看上去眼睛還不得瞎了。

所以,最後我還是得自己來實現這個候選條,怎麼佈局以後再說,不過這裡有一個很有意思的點可以講講,那就是怎麼讓這個 NSWindow 能跟著用戶的輸入點走,而不是被“困在”第一個屏幕裡。

首先,我是這樣設計的

用一個 NSWindow 加適當的改造,然後作為候選欄,調用它的 makeKeyAndOrderFront 來顯示,然後用 來關閉,然後我就遇到了第一個問題:調用 後,這個窗口被釋放了!導致程序執行強行遇到空指針,儘管在 Swift 中我是這樣聲明的 candidatesWindow:CandidateController

所以,我開始想到吸取 OC 裡的老一輩寶貴經驗,用 .ALPHAVALUE 來搞定這件事情。

透明度

畢竟,透明了就等於隱藏了,也不能交互,在我重寫了一系列方法後,看起來工作良好。不過,很快就有用戶報告問題,說候選欄有時候會丟失,就是說能打字但是沒有候選欄……我一開始以為是插入光標的坐標獲取錯誤……最終在我意外切換 Space 後重現了這一問題,原來候選欄並沒有跑偏,只是它顯示在了另一個屏幕空間裡。

所以我開始尋找怎麼把 NSWindow 移動到目標屏幕的辦法——其實後很多,但遺憾的是還真的是沒有移動 NSWindow 到目標 Space 的辦法——這就尷尬了。

於是在3個小時之後,我放棄了這條路,回到了原點。

NSWindowController

既然回到原點,那麼我一開始的設計理念其實還是比較正確的,那麼矛盾就在於如何讓這個窗口不自動釋放。遺憾的是網上找了一圈,大家竟然都是在問如何能讓窗口正確釋放——好吧,我看它就自己釋放的挺積極的……………………

總之,這個時候我想到了這個 Controller,畢竟它不會自己把自己給釋放了——那麼問題來了,如果我 NSWindowController ,它會被釋放嗎?

——幸好,也應該是顯然,不會。所以,我就改為了使用 NSWindowController ,然後在初始化的時候來初始化這個窗口。那麼當我需要顯示候選欄,我就可以這麼做:

當我需要關閉的時候,就這麼做:

這樣,整個的窗口管理就由 NSWindowController 自動安排了,然後重點來了:

由於每次窗口不再是單純的移動位置和修改透明度,窗口的出現和消失是真正的添加和移除,這就天生支持了在任意屏幕位置顯示,這下,候選欄可以支持多屏幕、多 Space 了。

本文由 落格博客 原創撰寫:落格博客 » 如何讓 NSWindow 顯示在不同的 Space 或者 Screen 中

轉載請保留出處和原文鏈接:https://www.logcg.com/archives/2769.html

關於作者

R0uter

如非聲明,本人所著文章均為原創手打,轉載請註明本頁面鏈接和我的名字。

註釋

發表評論

您的電子郵件地址不會被公開. 必填字段標 *