跳至內容
出自 Arch Linux 中文维基

修改鍵位映射的前提是了解按鍵如何生成符號:

  1. 鍵盤向計算機發送一個掃描碼(scancode)
  2. Linux 內核將掃描碼映射為鍵碼(keycode);參見掃描碼映射至鍵位碼
  3. 鍵盤布局根據按下的修飾鍵將鍵碼映射為符號,稱作鍵符(keysym)

大部分按鍵應該有鍵碼或至少有掃描碼。內核無法識別沒有掃描碼的按鍵,如一些「遊戲鍵盤」上附加的按鍵。

在 Xorg 中,某些鍵符(如 XF86AudioPlayXF86AudioRaiseVolume 等)可以映射到操作(例如啟動外部應用程式),詳見快捷鍵#Xorg

在 Linux 控制台中,某些鍵符(如 F1F246)可被映射到特定操作(例如切換到其他控制台或列印字符序列)。詳見 Linux 控制台/鍵盤配置#創建自定義鍵盤映射

識別掃描碼

使用 evtest

識別掃描碼的最可靠方法是參考按鍵按下時生成的 MSC_SCAN evdev 事件[1]。有多種 evdev API 測試工具,但最直接的是來自 evtest 包的 evtest(1)

# evtest /dev/input/event12
...
Event: time 1434666536.001123, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70053
Event: time 1434666536.001123, type 1 (EV_KEY), code 69 (KEY_NUMLOCK), value 0
Event: time 1434666536.001123, -------------- EV_SYN ------------
提示:若不確定目標設備對應的事件編號,可不帶參數運行 evtest,該命令會顯示設備列表及其對應的事件編號並要求輸入所需設備的事件編號。

MSC_SCAN 的「value」欄位即為按鍵對應的掃描碼。此示例顯示 NumLock 的掃描碼為70053,鍵碼為 69。

使用 showkey

注意:手冊頁中指出,在現代內核上,原始掃描碼模式「並不是真正的原始(is not very raw at all)」。看起來這種方法對於 USB 設備尤其容易產生錯誤的結果。

識別掃描碼的傳統方法是使用 showkey(1) 工具。showkey 等待按鍵按下,如果 10 秒內沒有按下按鍵則退出。只有處於虛擬控制台而不是圖形環境中,且不是通過網絡連接登錄時,showkey 才能正常工作。運行以下命令:

# showkey --scancodes

然後嘗試按下鍵盤按鍵,應當輸出對應掃描碼。

使用 dmesg

注意:此方法僅可用於識別未知按鍵。

可以通過按下所需的按鍵後查看 dmesg 的輸出來獲取該按鍵的掃描碼。例如,如果輸出如下:

Unknown key pressed (translated set 2, code 0xa0 on isa0060/serio0

那麼按下按鍵的掃描碼就是 0xa0


識別鍵碼

Linux 將鍵碼定義在 /usr/include/linux/input-event-codes.h 中(參見其中以 KEY_ 開頭的變量)。

在控制台中識別鍵碼

showkey(1) 工具可用於報告虛擬控制台中按下按鍵的鍵碼。showkey 等待按鍵按下,如果 10 秒內沒有按下按鍵則退出。只有處於虛擬控制台而不是圖形環境中,且不是通過網絡連接登錄時,showkey 才能正常工作。運行以下命令:

# showkey --keycodes

然後嘗試按下鍵盤按鍵,應當輸出對應鍵碼。

在 Xorg 中識別「鍵碼」

這篇文章的某些內容需要擴充。

原因:xev 同時也會報告鍵符。請注意,需要讓「Event Tester」窗口獲取到焦點。 (在 en:Talk:Keyboard Input 中討論)
注意:Xorg 使用的「鍵碼」比 Linux 定義的鍵碼大 8(詳見 [2]),此處中使用帶雙引號的「鍵碼」指代 Xorg 使用的「鍵碼」。


xev(1) 工具可用於報告 Xorg 中按下按鍵的「鍵碼」,該工具由 xorg-xev 軟體包提供。當然,要運行 xev,需要處於圖形環境而不是控制台中。

使用以下命令可以啟動 xev 並僅顯示相關部分:

$ xev | awk -F'[ )]+' '/^KeyPress/ { a[NR+2] } NR in a { printf "%-3s %s\n", $5, $8 }'
38  a
55  v
54  c
50  Shift_L
133 Super_L
135 Menu

xev 的封裝工具 xbindkeys英語xbindkeys#Identifying keycodes 同樣能報告「鍵碼」。

如果你按下某個鍵後終端中沒有任何輸出,可能意味著該鍵沒有掃描碼,或者該掃描碼未映射到「鍵碼」,又或者有其他進程在捕捉該按鍵事件。如果懷疑某個監聽 X 伺服器的進程正在捕捉按鍵,可以嘗試在一個乾淨的 X 會話中運行 xev:

$ xinit /usr/bin/xterm -- :1

在 Wayland 中識別鍵碼

雖然 xev 也能通過 XWayland 在 Wayland 上工作,但也可以使用 wev 在純 Wayland 環境下獲取「鍵碼」。(wev 獲取的「鍵碼」也比 Linux 定義、Wayland 使用的鍵碼大 8。)

使用以下命令可僅檢索鍵符及其 UTF-8 等效值:

$ wev | grep 'sym'

提示與技巧

VIA 兼容鍵盤的配置

VIA 是一款直接將鍵位重映射到兼容鍵盤的程序。若擁有此類鍵盤,為了讓瀏覽器能夠識別並在線配置,需添加自定義的 udev 規則以修改通過 hidraw 驅動訪問設備的權限。

注意:此方法可能存在安全風險。

創建以下 udev 規則

/etc/udev/rules.d/99-via.rules
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", MODE="0666", TAG+="uaccess", TAG+="udev-acl"

隨後重新加載規則使其生效。

另見

  • kbd-project⸺showkeys 工具的官方網站
  • interception-tools英語interception-tools⸺用於控制和自定義鍵盤輸入映射行為的工具集
  • kmonad⸺高級鍵位重綁定與重映射守護進程
  • Hawck⸺又一個鍵位重綁定守護進程
  • keyd⸺簡約型鍵位重綁定守護進程
  • Vial⸺VIA 離線配置程序
  • Keyshift⸺注重性能的 Linux 鍵盤分層與重映射軟體