Como obter códigos de teclas para o xmodmap?

66

Estou tentando usar xmodmap para remapear as teclas Alt / Super no teclado Dell L100 e ter problemas para obter os códigos de teclas.

Por exemplo, usar xev não me dá código para 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   

Para a chave Right Super , xev e showkey fornecem códigos de tecla diferentes - 134 e 126 , respectivamente.

O que está acontecendo com esses códigos de teclas?

Eu tentei obter códigos de tecla de showkey -k , e usando o arquivo xmodmap abaixo, mas isso deu um mapa estranho que remapeava a chave 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
    
por Yaroslav Bulatov 02.10.2012 / 05:35

6 respostas

46

Existem muitos jogadores entre o seu teclado e o processo que finalmente lida com o evento do teclado. Entre as principais partes da paisagem está o fato de que o sistema X tem sua própria camada de manipulação de teclado, e o X associa diferentes "códigos de teclas" com chaves que seu sistema básico Linux. O comando showkey está mostrando os códigos-chave no jargão do sistema básico do Linux. Para xmodmap , você precisa dos códigos-chave X, que são o que xev está exibindo. Contanto que você esteja planejando trabalhar no X e fazer a reconexão de chave com xmodmap , ignore o showkeys e apenas escute o que o xev diz.

O que você deseja procurar na sua saída xev são blocos como este:

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 tende a gerar muita saída, especialmente quando você move o mouse. Você pode ter que voltar um pouco para encontrar a saída que está procurando. Na saída anterior, vemos que o keysym Alt_L está associado ao X keycode 64 .

    
por 02.10.2012 / 06:36
20

xev deve funcionar

Estranho, meu xev dá um evento KeyPress e KeyRelease para o alt (e para a tecla do Windows, aqui chamado de "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

E o da mão direita:

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

Eu posso ver duas possibilidades:

  1. Algo mais está comendo completamente a tecla ou desfocando a janela ao pressionar alt. Tente executar o xev em um servidor X vazio (por exemplo, apenas execute xinit -- :1 , que deve obter um servidor X com apenas um xterm - não haverá nem mesmo um gerenciador de janelas em execução. Sair do xterm fechará a sessão).
  2. Você só perdeu os dois eventos no volume que xev vomitou.

Uma maneira fácil, se você souber o nome da chave

Outra possibilidade: é só pegar os códigos de teclas do 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)

Há o 64 e o 108 novamente. xmodmap -pm mostrará apenas o mapa modificador, que também fornece os números (embora, desta vez, em hexadecimal).

    
por 26.10.2012 / 18:14
15

Eu "detecto" três problemas na sua pergunta:

  1. Por que xev e showkey relatam códigos de teclas diferentes para uma chave?
  2. Por que xev não mostra Alt sendo pressionado corretamente?
  3. Como trocar Alt e Win ?

Com relação à primeira pergunta: atualmente, onde o "driver" do teclado no X não direciona o hardware, ele pode passar pelos códigos-chave do kernel para o núcleo X, mas isso não acontece. Adiciona 8 ao código antes de passá-lo.

Segundo: Algo em sua sessão X está pegando o evento Alt . As outras respostas cobrem isso já. (Por exemplo, xev não recebe o evento que você gostaria de ver). O culpado pode estar relacionado ao seu gerenciador de janelas. Tente uma sessão X mais nua.

Terceiro: não use xmodmap . Está desatualizado há uma década. Os novos caras são o XKB e sua ferramenta setxkbmap .

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

Para trocar Alt e Win já existe uma opção preparada em XKB. Apenas adicione:

$ setxkbmap -option altwin:swap_alt_win
$ setxkbmap -query
rules:      evdev
model:      pc105
layout:     us
variant:    altgr-intl
options:    altwin:swap_alt_win,caps:backspace
    
por 14.11.2014 / 12:54
10

Eu estava tentando resolver isso sozinho e acabei de descobrir.

O principal problema é que você não está recebendo o evento para o pressionamento de tecla. Olhando para o log que você postou a razão é aparente.

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   

Você pode ver que os eventos Focus{In,Out} têm mode de Notify{Grab,Ungrab} . Isso indica que uma chave foi manipulada por outro processo (provavelmente um aplicativo de atalho / atalho).

No meu caso, eram xbindkeys, mas se você estiver usando um ambiente de desktop, eles provavelmente têm um sistema de keybinding. Para ver esses eventos é xev, você precisará parar / desativar o outro programa.

Se você não puder determinar qual programa está roubando os principais eventos, a melhor solução é iniciar outra sessão X sem executá-la. Execute o seguinte comando para iniciar outra sessão X na exibição :1 , se isso já foi feito, basta aumentar o número no final. É claro que você pode alterar o terminal para o que preferir ou instalar no seu sistema.

xinit /usr/bin/xterm -- :1

Em seguida, execute xev novamente. Isso deve lhe dar o resultado sem que seja capturado por outros programas. Note que o gerenciador de janelas que é iniciado é focalizado, portanto você terá que colocar o cursor acima da janela xev para que as chaves sejam capturadas.

Como foi dito em esta excelente resposta por dubiousjim , o código de acesso é diferente porque há muitas camadas entre xev e o kernel.

    
por 23.08.2013 / 00:47
8

Como root, execute:

showkey -s

... para ver o que é o scancode para a sua chave de mistério. Eu tenho algo assim:

# 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 

Não sei por que parece que uma chave gera dois scancodes. Não é uma coisa keydown / keyup, tão perto quanto eu poderia dizer do padrão. Observe o aviso, então você pode querer executar isso no modo de usuário único.

Eu acho que 0x46 foi meu scancode.

Em seguida, encontre um código de acesso não usado com:

xmodmap -pke | less

Aqui você pode ver que o código-chave 97 não é usado no meu sistema:

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

O keycode X usa e o keycode que o kernel usa são OFF BY 8 por "razões históricas". Então pegue 97 - 8 = 89 e use 89 com o comando setkeycodes (novamente como root):

# setkeycodes 46 89

E você deve estar definido. Confirme com xev que você está recebendo um Keypress Event com o código de 97. (embora uma vez eu disse ao arquivo de chaves do Fluxbox para usar esse código eu não recebi mais eventos KeyPress - talvez porque o Fluxbox os engole quando os usa?)

Note que o 'setkeycodes' não sobreviverá a uma reinicialização, então você terá que adicioná-lo aos seus scripts de inicialização (por exemplo, em /etc/rc.local)

    
por 26.10.2012 / 11:56
4

Eu tive o mesmo problema com Alt_L desaparecendo no XUbuntu 14.04 ( Alt_R estava bom). Depois de muito jogar, observei que showkey registrou o pressionamento de tecla, mas xev não - ele tinha que ser algo no sistema de janelas. Eu vasculhei todas as configurações do "Window Manager" e do "Window Manager Tweaks", e não encontrei nada. Finalmente, encontrei um Alt_L na lista de atalhos de teclado ( xfce4-keyboard-shortcuts ) no "Editor de configurações". Eu "redefinir" isso, e eu tenho meu Alt_L de volta! O atalho Alt_L perdido não apareceu em nenhum outro lugar, exceto no "Editor de configurações".

    
por 10.06.2014 / 20:44