Làm cách nào để lấy mã khóa cho xmodmap?


76

Tôi đang cố gắng sử dụng xmodmapđể ánh xạ lại Alt/ Superphím trên bàn phím Dell L100 và gặp sự cố khi lấy mã phím.

Chẳng hạn, việc sử dụng xevkhông cung cấp cho tôi mã khóa choAlt

FocusOut event, serial 36, synthetic NO, window 0x4a00001,
    mode NotifyGrab, detail NotifyAncestor

FocusIn event, serial 36, synthetic NO, window 0x4a00001,
    mode NotifyUngrab, detail NotifyAncestor

KeymapNotify event, serial 36, synthetic NO, window 0x0,
    keys:  122 0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   
           0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   

Đối với Right Superkhóa xevshowkeycung cấp các mã khóa khác nhau - 134126tương ứng.

Điều gì đang xảy ra với các mã khóa này?

Tôi đã thử nhận mã khóa từ showkey -kvà sử dụng xmodmaptệp bên dưới, nhưng điều đó đã đưa ra một bản đồ kỳ lạ đã ánh xạ lại bkhóa:

clear Mod1
clear Control
keycode 125 = Meta_L
keycode 126 = Meta_R
keycode 58 = Control_L
keycode 56 = Control_L
keycode 100 = Control_R
add Control = Control_L Control_R
add Mod1 = Meta_L Meta_R

Tôi gặp vấn đề tương tự với Alt_L không bắn (nhưng Alt_R vẫn ổn), trên XUbfox 14.04. Bạn đang sử dụng hệ thống nào?
Paul Giá

Câu trả lời:


54

Có rất nhiều người chơi giữa bàn phím của bạn và quá trình cuối cùng xử lý sự kiện bàn phím. Trong số các phần chính của cảnh quan là thực tế là hệ thống X có lớp xử lý bàn phím riêng và X liên kết các "mã khóa" khác nhau với các khóa so với hệ thống cơ sở Linux của bạn. Các showkeylệnh được hiển thị cho bạn mã phím trong Linux-base-system biệt ngữ. Đối với xmodmapbạn cần mã phím X, đó là những gì xevđang hiển thị. Vì vậy, miễn là bạn có kế hoạch làm việc trong X và thực hiện thao tác sửa khóa xmodmap, sau đó, bỏ qua showkeysvà chỉ lắng nghe những gì xevnói.

Những gì bạn muốn tìm kiếm trong xevđầu ra của bạn là các khối như thế này:

KeyPress event, serial 27, synthetic NO, window 0x1200001,
    root 0x101, subw 0x0, time 6417361, (340,373), root:(342,393),
    state 0x0, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 27, synthetic NO, window 0x1200001,
    root 0x101, subw 0x0, time 6417474, (340,373), root:(342,393),
    state 0x8, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

xevcó xu hướng tạo ra rất nhiều đầu ra, đặc biệt là khi bạn di chuyển chuột. Bạn có thể phải cuộn lại một lúc để tìm đầu ra mà bạn đang tìm kiếm. Trong đầu ra trước, chúng ta thấy rằng keysym Alt_Lcó liên quan đến mã phím X 64.


3
Vấn đề là tôi không nhận được sự kiện KeyPress trên khóa Windows. Tôi đã thử 3 bàn phím khác nhau và kết quả tương tự. Từ xev tôi chỉ nhận được FocusOut, FocusIn và KeymapNotify như đã thấy ở trên. Tuy nhiên, tôi có thể đi và thiết lập các phím tắt thông qua trình quản lý Gnome và nó thấy khóa Windows là "Mod4"
Yaroslav Bulatov

Phím Windows bên phải báo cáo là Mod4, phím Windows trái báo cáo là Alt ... thật khó hiểu vì tôi thậm chí không có danh mục "Alt" trong xmodmap của mình.
Yaroslav Bulatov

Hãy thử Mod1 cho Alt.
dubiousjim

2
@YaroslavBulatov có vẻ như môi trường máy tính để bàn của bạn đang ăn chìa khóa (có thể để hiển thị menu chính của nó?)
derobert

3
Bạn có thể lọc các sự kiện mà xev cung cấp cho bạn. Trong trường hợp này xev -event keyboardsẽ là đủ để loại bỏ hầu hết các tiếng ồn.
Fredrik Wendt

24

xev nên làm việc

Kì lạ, xev của tôi đưa ra một sự kiện KeyPress và KeyRelease cho alt (và cho khóa Windows, ở đây được gọi là "super"):

KeyPress event, serial 40, synthetic NO, window 0xae00001,
    root 0x2ca, subw 0x0, time 595467354, (98,77), root:(102,443),
    state 0x10, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 40, synthetic NO, window 0xae00001,
    root 0x2ca, subw 0x0, time 595467453, (98,77), root:(102,443),
    state 0x18, keycode 64 (keysym 0xffe9, Alt_L), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

Và bên tay phải:

KeyPress event, serial 40, synthetic NO, window 0xae00001,
    root 0x2ca, subw 0x0, time 595572876, (75,33), root:(79,399),
    state 0x10, keycode 108 (keysym 0xffea, Alt_R), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

KeyRelease event, serial 40, synthetic NO, window 0xae00001,
    root 0x2ca, subw 0x0, time 595572972, (75,33), root:(79,399),
    state 0x18, keycode 108 (keysym 0xffea, Alt_R), same_screen YES,
    XLookupString gives 0 bytes: 
    XFilterEvent returns: False

Tôi có thể thấy hai khả năng:

  1. Một cái gì đó khác là hoàn toàn ăn phím, hoặc làm mờ cửa sổ khi bạn nhấn alt. Hãy thử chạy xev trong một máy chủ X trống khác (ví dụ: chỉ cần chạy xinit -- :1, nó sẽ giúp bạn có một máy chủ X chỉ với một xterm, thậm chí sẽ không có trình quản lý cửa sổ nào chạy. Thoát khỏi xterm sẽ đóng phiên).
  2. Bạn vừa bỏ lỡ hai sự kiện trong số lượng lớn mà xev phun ra.

Một cách dễ dàng, nếu bạn biết tên khóa

Một khả năng khác: chỉ cần lấy mã khóa từ xmodmap:

anthony@Zia:~$ xmodmap -pk | grep -i alt
     64         0xffe9 (Alt_L)  0xffe7 (Meta_L) 0xffe9 (Alt_L)  0xffe7 (Meta_L)
    108         0xffea (Alt_R)  0xffe8 (Meta_R) 0xffea (Alt_R)  0xffe8 (Meta_R)
    204         0x0000 (NoSymbol)       0xffe9 (Alt_L)  0x0000 (NoSymbol)       0xffe9 (Alt_L)
anthony@Zia:~$ xmodmap -pk | grep -i super
    133         0xffeb (Super_L)        0x0000 (NoSymbol)       0xffeb (Super_L)
    134         0xffec (Super_R)        0x0000 (NoSymbol)       0xffec (Super_R)
    206         0x0000 (NoSymbol)       0xffeb (Super_L)        0x0000 (NoSymbol)       0xffeb (Super_L)

Có 64 và 108 một lần nữa. xmodmap -pmsẽ chỉ cho bạn bản đồ sửa đổi, cũng cung cấp cho bạn các số (mặc dù, lần này, ở dạng hex).


15

Tôi "phát hiện" ba vấn đề trong câu hỏi của bạn:

  1. Tại sao làm xevshowkeybáo cáo các mã khóa khác nhau cho một khóa?
  2. Tại sao xevkhông hiển thị Altđược nhấn đúng cách?
  3. Làm thế nào để trao đổi AltWin?

Về câu hỏi đầu tiên: những ngày này, nơi "trình điều khiển" bàn phím trong X không thực sự điều khiển phần cứng, nó chỉ có thể chuyển mã khóa từ nhân sang lõi X, nhưng không. Nó thêm 8 vào mã khóa trước khi chuyển nó vào.

Thứ hai: Một cái gì đó trong phiên X của bạn đang lấy Altsự kiện. Các câu trả lời khác bao gồm điều này rồi. (Tức là xevkhông nhận được sự kiện bạn muốn xem). Thủ phạm có thể liên quan đến người quản lý cửa sổ của bạn. Hãy thử một phiên X trần trụi hơn.

Thứ ba: Không sử dụng xmodmap. Nó đã lỗi thời trong một thập kỷ. Những kẻ mới là XKB và công cụ của nó setxkbmap.

$ setxkbmap -query
rules:      evdev
model:      pc105
layout:     us
variant:    altgr-intl
options:    caps:backspace

Để hoán đổi AltWinđã có một tùy chọn được chuẩn bị trong XKB. Chỉ cần thêm nó:

$ setxkbmap -option altwin:swap_alt_win
$ setxkbmap -query
rules:      evdev
model:      pc105
layout:     us
variant:    altgr-intl
options:    altwin:swap_alt_win,caps:backspace

Làm thế nào để bạn thực hiện setxkbmapthay đổi vĩnh viễn?
Steve Kehlet

Thêm thay đổi vào ~/.xinitrc.
Matthias Braun

11

Là root, chạy:

showkey -s

... Để xem scancode là gì cho khóa bí ẩn của bạn. Tôi có một cái gì đó như thế này:

# showkey -s
kb mode was RAW
[ if you are trying this under X, it might not work
since the X server is also reading /dev/console ]

press any key (program terminates 10s after last keypress)...

0xc6 
0x46 0xc6 
0xc6 
0x46 0xc6 
0x46 

Không chắc chắn tại sao có một khóa tạo ra hai scancodes. Nó không phải là một phím tắt / keyup, gần như tôi có thể nói từ mẫu. Lưu ý cảnh báo, vì vậy bạn có thể muốn chạy nó trong chế độ người dùng.

Tôi đoán rằng 0x46 là scancode của tôi.

Tiếp theo, tìm một mã khóa không sử dụng với:

xmodmap -pke | less

Ở đây bạn có thể thấy mã khóa 97 không được sử dụng trên hệ thống của tôi:

keycode  94 = less greater less greater bar brokenbar
keycode  95 = F11 XF86Switch_VT_11 F11 XF86Switch_VT_11
keycode  96 = F12 XF86Switch_VT_12 F12 XF86Switch_VT_12
keycode  97 =
keycode  98 = Katakana NoSymbol Katakana
keycode  99 = Hiragana NoSymbol Hiragana

Mã khóa X sử dụng và mã khóa mà hạt nhân sử dụng là OFF BY 8 vì "lý do lịch sử". Vì vậy, lấy 97 - 8 = 89 và sử dụng 89 với lệnh setkeycodes (một lần nữa là root):

# setkeycodes 46 89

Và bạn nên được thiết lập. Xác nhận với xev rằng bạn đang nhận Sự kiện nhấn phím với mã khóa 97. (mặc dù một lần tôi đã nói với tệp khóa Fluxbox để sử dụng mã khóa đó, tôi không nhận được các sự kiện KeyPress nữa - có thể vì Fluxbox nuốt chúng khi sử dụng chúng?)

Lưu ý rằng 'setkeycodes' sẽ không tồn tại khi khởi động lại, vì vậy bạn sẽ phải thêm nó vào tập lệnh init của mình (ví dụ: trong /etc/rc.local)


1
Bạn có một con trỏ liên quan đến "tắt 8 vì lý do lịch sử" không?
Robert Siemer

Tôi đã sử dụng câu trả lời của bạn để ánh xạ khóa mũ vào một phím chức năng (cụ thể là F9). Điều này cho phép tôi sử dụng F9 làm khóa tiền tố trong tmux. Cảm ơn.
Raymond Kroeker

@RobertSiemer tldp.org/HOWTO/Pal-and-Console-HOWTO-15.html "Thường thì số X sẽ nhiều hơn 8 số so với số Linux." Từ ngữ của tôi với "lịch sử" phải có từ một trang khác.
Greg Bell

11

Tôi đã cố gắng giải quyết điều này cho chính mình và tôi chỉ cần tìm ra nó.

Vấn đề chính là bạn không nhận được sự kiện cho phím bấm. Nhìn vào nhật ký bạn đăng lý do là rõ ràng.

FocusOut event, serial 36, synthetic NO, window 0x4a00001,
    mode NotifyGrab, detail NotifyAncestor

FocusIn event, serial 36, synthetic NO, window 0x4a00001,
    mode NotifyUngrab, detail NotifyAncestor

KeymapNotify event, serial 36, synthetic NO, window 0x0,
    keys:  122 0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   
           0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   

Bạn có thể xem các Focus{In,Out}sự kiện có một modesố Notify{Grab,Ungrab}. Điều này chỉ ra rằng một khóa đã được xử lý bởi một quy trình khác (có thể là một ứng dụng phím tắt / liên kết phím).

Trong trường hợp của tôi, đó là xbindkey, nhưng nếu bạn đang sử dụng môi trường máy tính để bàn thì có lẽ họ có hệ thống khóa phím. Để xem các sự kiện này là xev, bạn sẽ cần dừng / tắt chương trình khác.

Nếu bạn không thể xác định chương trình nào đang đánh cắp các sự kiện chính, giải pháp tốt nhất là bắt đầu một phiên X khác mà không chạy. Chạy lệnh sau để bắt đầu một phiên X khác trên màn hình :1, nếu điều đó đã được thực hiện, chỉ cần tăng số ở cuối. Tất nhiên bạn có thể thay đổi thiết bị đầu cuối thành bất cứ thứ gì bạn thích hoặc đã cài đặt trên hệ thống của bạn.

xinit /usr/bin/xterm -- :1

Sau đó chạy xevlại. Điều đó sẽ cung cấp cho bạn kết quả mà không bị bắt bởi các chương trình khác. Lưu ý rằng trình quản lý cửa sổ được bắt đầu là tập trung di chuột, do đó bạn sẽ phải đặt con trỏ lên trên cửa sổ xev để các phím được chụp.


Như đã nói trong câu trả lời xuất sắc này của dubiousjim , mã khóa khác nhau vì có rất nhiều lớp giữa xev và kernel.


4

Tôi gặp vấn đề tương tự với việc Alt_Lbiến mất trong XUbfox 14.04 ( Alt_Rvẫn ổn). Sau khi chơi rất nhiều, tôi quan sát thấy rằng đã showkeyghi lại tiếng gõ phím, nhưng xevkhông --- nó phải là thứ gì đó trong hệ thống cửa sổ. Tôi đã quét tất cả các cài đặt "Window Manager" và "Window Manager Tweaks" và không tìm thấy gì. Cuối cùng, tôi đã tìm thấy một sự đi lạc Alt_Ltrong danh sách các phím tắt ( xfce4-keyboard-shortcuts) trong "Trình chỉnh sửa cài đặt". Tôi "thiết lập lại" điều đó, và tôi đã Alt_Ltrở lại! Alt_LPhím tắt đi lạc không hiển thị ở bất kỳ nơi nào khác ngoại trừ trong "Trình chỉnh sửa cài đặt".

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.