Mac第三方IME下如何將大寫鎖定鍵改為IME切換鍵

來源:互聯網
上載者:User

   Mac第三方IME下如何將大寫鎖定鍵改為IME切換鍵

  根據個人習慣,我最終決定將大寫鎖定鍵更改為IME切換鍵,一是因為作為一個中國人IME切換是使用最多的一個快速鍵之一;另一個原因是因為如此一來鍵上的指示燈還可作為IME指示燈,簡直完美。

  更改鍵綁定

  開啟系統喜好設定-鍵盤-鍵盤-修飾鍵,將 CAPS LOCK 鍵設為“無操作”

  下載 Seil(良心軟體,良心作者),開啟後將 CAPS LOCK 鍵映射為 Key Code 80(或者其他一個不存在的鍵,80代表F19)

  開啟系統喜好設定-鍵盤-快速鍵-輸入源,將切換IME的快速鍵設定為F19(通過選擇後按一下Caps Lock)

  Done! 但是現在問題來了:大寫鎖定的燈永遠不亮,這不優美!我們希望指示燈也更改為能夠指示IME狀態,即在英文狀態下不亮,在拼音/五筆等IME狀態下亮。經過 Google 發現,OS X 提供了修飾鍵盤燈的底層 API,可以手動控制其狀態,詳見 MacLight。這就好辦了,於是我依次嘗試了以下幾種解決方案:

  寫一段 Shell 指令碼來切換IME(通過 AppleScript 類比 Keystroke)+切換指示燈狀態,通過 Automator 建立一個“服務”然後將大寫鎖定鍵綁定為運行該指令碼。但是經過測試發現延時太大(~200ms),放棄。

  用 Objective-C 寫一個調用底層 API 的程式來切換IME(通過TISSelectInputSource系列API)+切換指示燈狀態,發現調用 API 切換IME後需要切換到下一個輸入視窗才會生效,並且延時依然很大,放棄。

  用 Objective-C 寫一個後台應用,通過NSDistributedNotificationCenter接收IME變更事件,根據狀態改變指示燈。科學!

  最終採用了最後這種科學的方法。當然,這個後台應用只需要是命令列應用就可以了,通過launchctl等方式開機自動啟動即可。不過由於強迫症什麼的(方便啟動、退出,方便加為登入啟動項)還是寫成了佔領在狀態列的應用,並取名為IMLight,如下圖:

  Update for macOS Sierra

  升級 macOS Sierra 後,Seil 無法正常使用了(IMLight 不影響),詳見 Github 上的這個 issue,並且由於是系統介面的大改動,一時半會兒可能不會有修複更新。

  Issue 中也有人提到,可以使用作者正在開發的另一個針對 Sierra 的項目 Karabiner-Elements,但是這個項目對我來說有幾個問題:

  與 IMLight 衝突(雖然不一定是他的問題,但是我暫時也不知道怎麼修複…)

  會使得系統喜好設定中的針對多個鍵盤的修飾鍵設定失效(比如無法把外接鍵盤的 alt 和 ⌘ 互換),作者表示無法修複

  另外的解決方案是在系統喜好設定中把 Caps Lock 設定為 Ctrl(或者其他),然後用其他軟體重新對應,比如 Keyboard Maestro(更改 Caps Lock 這件事情比較底層,需要核心層級的修改,而監聽 Ctrl 等鍵這件事情就很簡單了)。我使用免費的 hammerspoon 來實現:

  local M = {}

  local events = hs.eventtap.event.types

  M.log = hs.logger.new('caps_remap', 'info')

  M.last_flags_1 = {}

  M.last_flags_0 = {}

  M.last_time_1 = 0

  M.last_time_0 = 0

  M.timeout = 0.15

  M.key = "ctrl"

  M.action = function() hs.eventtap.keyStroke({}, "f19") end

  local function _dict_has_no_other_key(dic)

  for k,v in pairs(dic) do

  if k ~= M.key then

  return false

  end

  end

  return true

  end

  function M.event_callback(e)

  local typ = e:getType()

  local code = e:getKeyCode()

  local flags = e:getFlags()

  local now = hs.timer.secondsSinceEpoch()

  if _dict_has_no_other_key(flags) and not flags[M.key]

  and _dict_has_no_other_key(M.last_flags_0) and M.last_flags_0[M.key]

  and _dict_has_no_other_key(M.last_flags_1) and not M.last_flags_1[M.key]

  and now - M.last_time_0 < M.timeout

  then

  M.log.i("Fire caps action")

  if M.action then

  M.action()

  end

  end

  M.last_flags_1 = M.last_flags_0

  M.last_flags_0 = flags

  M.last_time_1 = M.last_time_0

  M.last_time_0 = now

  return false

  end

  function M.init(options)

  if options.key then

  M.key = options.key

  end

  if options.timeout then

  M.timeout = options.timeout

  end

  if options.action then

  M.action = options.action

  end

  M.watcher = hs.eventtap.new({events.flagsChanged}, M.event_callback)

  M.watcher:start()

  end

  return M

  即快速按一下 ctrl(即 Caps Lock)會觸發 F19,而其他包含 ctrl 的按鍵組合並不會,可以滿足要求。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.