Как получить коды клавиш для xmodmap?


76

Я пытаюсь использовать xmodmapпереназначить Alt/ Superключи на Dell L100 клавиатуры, и есть проблемы с получением кодов клавиш.

Например, использование xevне дает мне код ключа дляAlt

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   

За Right Superключ xevи showkeyразные коды клавиш - 134и 126соответственно.

Что происходит с этими кодами клавиш?

Я попытался получить коды клавиш showkey -kи использовать xmodmapфайл ниже, но это дало странную карту, которая переназначила bключ:

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

У меня та же проблема с Alt_L не стрельба (но Alt_R в порядке), на XUbuntu 14.04. Какую систему вы используете?
Пол Прайс

Ответы:


54

Между вашей клавиатурой и процессом, который, наконец, обрабатывает событие клавиатуры, много игроков. Среди основных составляющих ландшафта - тот факт, что система X имеет свой собственный уровень обработки клавиатуры, и X ассоциирует разные «коды клавиш» с клавишами, чем ваша базовая система Linux. Команда showkeyпоказывает вам коды клавиш в языке Linux-base-system. Для xmodmapвас нужны коды клавиш X, которые xevотображаются. Пока вы планируете работать в X и выполнять привязку ключей с помощью xmodmap, тогда игнорируйте showkeysи просто слушайте то, что xevговорит.

То, что вы хотите найти в своем xevвыводе, это блоки вроде этого:

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

xevимеет тенденцию генерировать много выходных данных, особенно когда вы двигаете мышью. Возможно, вам придется прокрутить некоторое время назад, чтобы найти результат, который вы ищете. В предыдущем выходе, мы видим , что keysym Alt_Lсвязано с Х клавиатурным 64.


3
Проблема в том, что я не получаю событие KeyPress на ключ Windows. Я попробовал 3 разных клавиатуры и тот же результат. Из xev я получаю только FocusOut, FocusIn и KeymapNotify, как видно выше. Тем не менее, я могу пойти и настроить ярлыки через менеджер Gnome, и он видит ключ Windows как «Mod4»
Ярослав Булатов

Правый ключ Windows сообщает как Mod4, левый ключ Windows сообщает как Alt ... что сбивает с толку, потому что у меня даже нет категории "Alt" в моем xmodmap.
Ярослав Булатов

Попробуйте Mod1 для Alt.
Dubiousjim

2
@YaroslavBulatov звучит так, будто ваша рабочая среда потребляет ключ (возможно, чтобы вызвать его главное меню?)
Дероберт

3
Вы можете фильтровать события, которые дает вам xev. В этом случае xev -event keyboardбудет достаточно, чтобы избавиться от большей части шума.
Фредрик Вендт

24

Xev должен работать

Странно, мой xev дает событие KeyPress и KeyRelease для alt (и для ключа Windows, здесь называемого «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

И правый:

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

Я вижу две возможности:

  1. Что-то еще полностью поглощает нажатие клавиши или расфокусирует окно при нажатии клавиши alt. Попробуйте запустить xev на другом пустом X-сервере (например, просто запустите xinit -- :1, что даст вам X-сервер только с xterm - даже не будет запущен оконный менеджер. Выход из xterm закроет сеанс).
  2. Вы просто пропустили два события в объеме, который выбрасывает xev.

Простой способ, если вы знаете имя ключа

Другая возможность: просто получить коды клавиш из 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)

Здесь снова 64 и 108. xmodmap -pmпокажет вам только карту-модификатор, которая также даст вам числа (правда, на этот раз в шестнадцатеричном виде).


15

Я "обнаружил" три вопроса в вашем вопросе:

  1. Зачем xevи showkeyсообщать разные коды клавиш для ключа?
  2. Почему xevне показывает, Altчто нажата правильно?
  3. Как поменять местами Altи Win?

Что касается первого вопроса: в наши дни, когда «драйвер» клавиатуры в X на самом деле не управляет аппаратным обеспечением, он может просто передавать коды клавиш из ядра в ядро ​​X, но это не так. Он добавляет 8 к коду ключа перед его передачей.

Второе: что-то в вашей сессии X захватывает Altсобытие. Другие ответы уже охватывают это. (Т.е. xevне получается событие, которое вы хотели бы увидеть). Виновник может быть связан с вашим оконным менеджером. Попробуйте более голую сессию X.

Третье: не используйте xmodmap. Это было устаревшим в течение десятилетия. Новые парни - XKB и его инструмент setxkbmap.

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

Для обмена Altи Winесть уже подготовленный вариант в XKB. Просто добавьте это:

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

Как вы делаете setxkbmapизменение постоянным?
Стив Кехлет

Добавьте изменение в ~/.xinitrc.
Матиас Браун

11

От имени пользователя root запустите:

showkey -s

... чтобы узнать, что такое скан-код вашего тайного ключа. Я получил что-то вроде этого:

# 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 

Не уверен, почему кажется, что один ключ генерирует два сканкода. Насколько я могу судить по шаблону, это не относится к keydown / keyup. Обратите внимание на предупреждение, поэтому вы можете запустить его в однопользовательском режиме.

Я догадался, что 0x46 был мой скан-код.

Затем найдите неиспользуемый код ключа с помощью:

xmodmap -pke | less

Здесь вы можете видеть, что код 97 ключа не используется в моей системе:

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

Код клавиши X и код ядра, который используется ядром, имеют значение OFF BY 8 по «историческим причинам». Итак, возьмите 97 - 8 = 89 и используйте 89 с командой setkeycodes (снова как root):

# setkeycodes 46 89

И вы должны быть установлены. С помощью xev подтвердите, что вы получаете событие нажатия клавиш с кодом клавиши 97. (хотя, как только я сказал файлу ключей Fluxbox использовать этот код ключа, я больше не получал события KeyPress - может быть, потому что Fluxbox глотает их, когда использует их?)

Обратите внимание, что «setkeycodes» не выдержит перезагрузки, поэтому вам придется добавить его в свои сценарии инициализации (например, в /etc/rc.local)


1
У вас есть указатель относительно "выключено на 8 по историческим причинам"?
Роберт Симер

Я использовал ваш ответ, чтобы отобразить caps-lock на функциональную клавишу (особенно F9). Это позволяет мне использовать F9 в качестве префиксного ключа в tmux. Благодарю.
Раймонд Крукер

@RobertSiemer tldp.org/HOWTO/Keyboard-and-Console-HOWTO-15.html «Часто число Х будет на 8 больше, чем число Linux». Моя формулировка с «историческим» должна быть с другой страницы.
Грег Белл

11

Я пытался решить это для себя, и я просто понял это.

Основная проблема в том, что вы не получаете событие для нажатия клавиши. Глядя на журнал, который вы разместили, причина очевидна.

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   

Вы можете увидеть Focus{In,Out}события имеют modeоф Notify{Grab,Ungrab}. Это указывает на то, что ключ был обработан другим процессом (вероятно, приложением ярлыка / связывания клавиш).

В моем случае это были xbindkeys, но если вы используете настольную среду, они, вероятно, имеют систему привязки клавиш. Чтобы увидеть эти события xev, вам нужно остановить / отключить другую программу.

Если вы не можете определить, какая программа ворует ключевые события, лучшим решением будет запустить еще один сеанс X без его запуска. Выполните следующую команду, чтобы начать другой сеанс X на дисплее :1, если это уже сделано, просто увеличьте число в конце. Вы, конечно, можете изменить терминал на тот, который вы предпочитаете или установили в своей системе.

xinit /usr/bin/xterm -- :1

Тогда беги xevснова. Это должно дать вам результат без его захвата другими программами. Обратите внимание, что диспетчер окон, который запускается, находится при наведении курсора, поэтому вам нужно будет поместить курсор над окном xev, чтобы ключи были захвачены.


Как сказал в этом превосходном ответе dubiousjim , код ключа отличается, потому что между xev и ядром много слоев.


4

У меня была такая же проблема с Alt_Lисчезновением в XUbuntu 14.04 ( Alt_Rбыло хорошо). После долгих игр, я заметил, что showkeyзаписал нажатие клавиши, но xevне ... это должно было быть что-то в оконной системе. Я просмотрел все настройки «Window Manager» и «Window Manager Tweaks» и ничего не нашел. Наконец, я обнаружил отклонение Alt_Lв списке сочетаний клавиш ( xfce4-keyboard-shortcuts) в «Редакторе настроек». Я «сбрасываю» это, и у меня есть Alt_Lспина! Случайный Alt_Lярлык не появлялся нигде, кроме как в «Редакторе настроек».

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.