Linux

如何正確更改鍵盤映射?

  • June 11, 2015

我將嘗試詳細描述問題。我經常在上網本上使用外接鍵盤。鍵盤是“TK Stealth”:


點擊放大

您可以看到,小鍵盤與經典小鍵盤非常相似,但箭頭鍵實際上映射不同 - 作為寬鍵盤上的附加箭頭鍵。

我想讓它們像小鍵盤一樣映射,即“8”==“上”、“2”==“下”、“4”==“左”、“6”==“右”和很快。

僅當連接了此類鍵盤時,這些設置才有效。

我嘗試使用xmodmap /home/johnfound/TKStelth以下地圖文件“TKStelth”來做到這一點:

keycode  79 = KP_Home KP_Home KP_Home KP_Home
keycode  80 = KP_Up KP_Up KP_Up KP_Up
keycode  81 = KP_Prior KP_Prior KP_Prior KP_Prior
keycode  83 = KP_Left KP_Left KP_Left KP_Left
keycode  84 = KP_Begin KP_Begin KP_Begin KP_Begin
keycode  85 = KP_Right KP_Right KP_Right KP_Right
keycode  87 = KP_End KP_End KP_End KP_End
keycode  88 = KP_Down KP_Down KP_Down KP_Down
keycode  89 = KP_Next KP_Next KP_Next KP_Next
keycode  90 = KP_Insert KP_Insert KP_Insert KP_Insert
keycode  91 = KP_Delete KP_Delete KP_Delete KP_Delete

它確實有效,但有醜陋的副作用。例如,有時佈局恢復為預設值,我必須手動執行上述腳本。將腳本包含在初始化腳本中會導致一些衝突/鎖定,導致作業系統在從掛起和更改螢幕解析度恢復後掛起幾分鐘。這樣,我被迫從初始化腳本中刪除腳本。

我在某處讀到 xmodmap 實際上是處理鍵盤佈局的舊方法。

所以,問題是:如何配置 Linux 來正確處理這個並且只有這個鍵盤?

附加資訊:帶有 XFCE 的 Manjaro Linux。鍵盤配置有兩種佈局 - 美國和保加利亞語,在上述配置更改後它們必須保留。

只要找到合適的解決方案,我就會回答我自己的問題。

有一個名為keyfuzz的程序可以根據輸入設備更改核心使用的鍵盤映射 - 即分別為連接到電腦的每個鍵盤。

該程序有兩個問題在文件中沒有正確描述:

  1. USB 鍵盤生成掃描碼,而不是連接到 ps/2 埠的鍵盤的掃描碼。這樣,如果您需要重新映射 USB 鍵盤,您將需要一種了解按鍵掃描碼的方法。通常推薦用於測試掃描碼和鍵碼的工具“showkey”不會完成這項工作,因為它讀取的表單/dev/console會發出“標準”掃描碼,而與鍵槃無關。

為了根據/dev/input/KEYBOARD地址測試鍵盤的掃描碼,您需要使用名為getscancodes的程序。請注意,從上述連結下載的文件未正確壓縮。它被命名為getscancodes.tar.gz,但使用 ZIP 算法壓縮。該包包含原始碼以及預編譯的二進製文件。

在我的例子中,keyfuzz 配置文件看起來是這樣的:

### evdev 1.0.0., driver 'TK Stealth keyboard'
### Proper old-style numpad handling

0x70059    107
0x7005A    108
0x7005B    109
0x7005C    105
0x7005D    108
0x7005E    106
0x7005F    102
0x70060    103
0x70061    104

0x70062    110
0x70063    111
  1. 程序“keyfuzz”在引導期間作為服務啟動,以便儘早修補表。不幸的是,USB 鍵盤是稍後添加到設備中的,因此當 keyfuzz 啟動時,即使在引導期間連接了 USB 鍵盤,也沒有需要修補的鍵盤。

解決方案是使用udev規則文件並在添加所需鍵盤時啟動 keyfuzz。

為此,您需要添加一個文件/etc/udev/rules.d/mykeyboard.rules,其中包含(在我的情況下):

ACTION=="add", ATTRS{idVendor}=="2516", RUN+="/usr/lib/systemd/scripts/keyfuzz start"

現在,插入鍵盤後,keyfuzz 啟動腳本將啟動並修補鍵盤解碼表。

引用自:https://unix.stackexchange.com/questions/207299