在 macOS 上,安裝輸入法一直是一個噩夢,要打開系統輸入法目錄,要把輸入法拖拽進這個目錄,過程中還要輸入密碼,全手動也就罷了,還得重啟後系統才能識別,真的是讓人頭疼的不行。
後來大家逐漸意識到這個問題,落格輸入法也提供了 macOS 標準的 pkg 安裝包。
說是這麼說,但實際上似乎還是有辦法讓系統自動加載輸入法的,比如搜狗就做到了免重啟,安裝後不光不需要重啟系統就能識別,甚至安裝包還能幫你自動選好搜狗輸入法!
他們究竟是怎麼做到的不得而知,我也對此進行了我自己的研究。
配置文件
總之,一切都是從配置文件開始的,首先我找到了系統要讀取的配置文件,這個文件決定了用戶當前激活哪些輸入法,選中的是哪個輸入法:
1 |
~/Library/Preferences/com.apple.HIToolbox.plist |
在這個 plist 中,有 Appleanbledinputsourches 字段,這裡邊包含了當前都啟用了哪些輸入法,比如搜狗輸入法、落格輸入法、系統拼音等等; AppleInputSourceHistory 字段則包含了用戶的切換歷史,似乎和自動切換有關; AppleSelectedInputSources 字段則表明了當前用戶選中的輸入法,比如你當前用落格輸入法在打字,那麼這裡就是落格輸入法,如果你切換到了英文鍵盤,那麼這裡就會變成英文鍵盤。
理論上,我們編輯這個文件,就可以改變系統的配置,但顯然,這個配置文件不是實時讀取的,我們編輯該文件後,用終端命令重啟偏好管理系統和 Finder: killall cfprefsd && killall Finder
運氣好的話,就已經 ok 了。
——-事實上,一般你不會運氣好。
顯然,想要保險的話,還是重啟一下才行。總之,這已經是一個進步了,畢竟重啟完不需要用戶手動添加輸入法了對吧?
系統級別 API
那麼,能不能有其他更優雅的方案呢?最終我在 碳 框架找到了答案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
/* *=============================================================================== * Install/register an input source *=============================================================================== */ /* * TISRegisterInputSource() * * Summary: * Registers the new input source(s) in a file or bundle so that a * TISInputSourceRef can immediately be obtained for each of the new * input source(s). * * Discussion: * This allows an installer for an input method bundle or a keyboard * layout file or bundle to notify the system that these new input * sources should be registered. The system can then locate the * specified file or bundle and perform any necessary cache rebuilds * so that the installer can immediately call * TISCreateInputSourceList with appropriate properties (e.g. * BundleID or InputSourceID) in order to get TISInputSourceRefs for * one or more of the newly registered input sources. * * This can only be used to register the following: * * - Keyboard layout files or bundles in "/Library/Keyboard * Layouts/" or "~/Library/Keyboard Layouts/" (available to all * users or current user, respectively). Such keyboard layouts, once * enabled, are selectable. * * - Input method bundles in the new "/Library/Input Methods/" or * "~/Library/Input Methods/" directories (available to all users or * current user, respectively). * * Note: Input method bundles can include private non-selectable * keyboard layouts for use with * TISSetInputMethodKeyboardLayoutOverride. These are registered * automatically when the input method is registered, and do not * need to be separately registered. * * Security: Any code that calls TISRegisterInputSource is part of * an application or service that has already been validated in some * way (e.g. by the user). * * Parameters: * * location: * CFURLRef for the location of the input source(s), a file or * bundle. * * Result: * Error code: paramErr if location is invalid or the input * source(s) in the specified location cannot be registered; * otherwise noErr. * * Availability: * Mac OS X: in version 10.5 and later in Carbon.framework * CarbonLib: not available * Non-Carbon CFM: not available */ extern OSStatus TISRegisterInputSource(CFURLRef location) AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER; |
對於 Swift 來說,也能無痛調用,我們在安裝好輸入法後,只需要將輸入法 app 文件地址傳給這個函數,它就可以在系統中註冊輸入法,這下無需重啟就能讓系統識別到輸入法了:
1 2 3 |
let url = URL(fileURLWithPath: "/Library/Input Methods/LogInputMac2.app") let err = TISRegisterInputSource(url as CFURL) guard err != paramErr else {return} |
記得 import Carbon
接下來,我還想讓系統自動把我的輸入法添加的切換列表裡(即激活輸入法):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
/* * TISEnableInputSource() * * Summary: * Enables the specified input source. * * Discussion: * TISEnableInputSource is mainly intended for input methods, or for * applications that supply their own input sources (e.g. * applications that provide keyboard layouts or palette input * methods, and keyboard input methods that provide their own * keyboard layouts and/or input modes). It makes the specified * input source available in UI for selection. * * For TISEnableInputSource to succeed, the input source must be * capable of being enabled (kTISPropertyInputSourceIsEnableCapable * must be true). Furthermore, if the input source is an input mode, * its parent must already be enabled for the mode to become enabled. * * Result: * Returns an error code: paramErr if the input source cannot be * enabled, else noErr. * * Availability: * Mac OS X: in version 10.5 and later in Carbon.framework * CarbonLib: not available * Non-Carbon CFM: not available */ extern OSStatus TISEnableInputSource(TISInputSourceRef inputSource) AVAILABLE_MAC_OS_X_VERSION_10_5_AND_LATER; |
這個函數調用起來就沒那麼容易了,主要的難點就是這個 TISInputSource 沒辦法直接創建,所以要用到另一個函數來搜索,我們已經在系統中註冊了落格輸入法,接下來就是在所有的可用輸入法中找到落格輸入法這個輸入源,如果直接窮舉所有可用輸入源,會很慢(API 原話),我們需要加入條件搜索:
1 2 3 4 5 6 |
let conditions = NSMutableDictionary() conditions.setValue(“落格输入法id”, forKey: kTISPropertyBundleID as String) guard let array = TISCreateInputSourceList (conditions, true)?.takeRetainedValue() as? [TISInputSource] else { return } |
如無意外,我們就可以拿到落格輸入法的輸入源了,這裡有兩個,一個是輸入法,一個是用來真正給用戶能輸入的輸入模式(在用戶角度來看這兩者是同一個,因為落格輸入法就只有一個輸入模式——中英文模式是這個唯一模式的兩個不同狀態)。
接下來就是添加了:
1 2 |
TISEnableInputSource(source) TISSelectInputSource(source) |
這下,用戶就可以在安裝完成後立即在右上角點擊切換到落格輸入法——運氣好的話,連切換都不需要。
討論
這個方法看上去很美好,似乎從 macOS 10.5 開始就能用,但實際測試來看只有最新的 macOS Mojave 10.14 是有效的,我在 10.13 上測試無效,不論是改配置還是調用系統 API,全都無動於衷,我傾向於是我這個特定係統版本的 bug,因為 API 調用後右上角的圖標已經時落個輸入法的圖標,但選擇列表中並沒有落格輸入法,甚至註冊都失敗了。
總之,對於 10.14 的新用戶來說,安裝落格輸入法的體驗變得極佳。
本文由 落格博客 原創撰寫:落格博客 » 落格輸入法 macOS 2 是如何實現免重啟激活輸入法的
轉載請保留出處和原文鏈接:https://www.logcg.com/archives/3263.html