Como obter códigos de chave para xmodmap?

76

Estou tentando usar o xmodmapremapeamento Alt/ Superteclas no teclado Dell L100 e tenho problemas para obter os códigos de teclas.

Por exemplo, usar xevnão me fornece o código-chave paraAlt

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 Right Superchave xeve showkeyforneça códigos de chave diferentes - 134e 126respectivamente.

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

Tentei obter códigos de chave showkey -ke usar o xmodmaparquivo abaixo, mas isso deu um mapa estranho que remapeava a bchave:

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
Yaroslav Bulatov
fonte
Eu tenho o mesmo problema com o Alt_L não disparando (mas Alt_R está bom), no XUbuntu 14.04. Que sistema voce está usando?
Paul Preço

Respostas:

54

Há muitos jogadores entre o teclado e o processo que finalmente lida com o evento do teclado. Entre as principais partes do cenário, está o fato de o sistema X possuir sua própria camada de manipulação de teclado, e o X associa diferentes "códigos de chave" a chaves que o sistema base Linux. O showkeycomando está mostrando os códigos de chave no jargão do sistema básico do Linux. Para xmodmapvocê precisar dos códigos de teclas X, que são o que xevestá sendo exibido. Desde que você esteja planejando trabalhar no X e fazer a sua religação de chave xmodmap, ignore showkeyse ouça apenas o que xevdiz.

O que você deseja procurar em sua xevsaída 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

xevtende a gerar muita saída, especialmente quando você move o mouse. Pode ser necessário voltar um pouco para encontrar a saída que você está procurando. Na saída anterior, vemos que o keysym Alt_Lestá associado com o código de acesso X 64.

dubiousjim
fonte
3
O problema é que não recebo o evento KeyPress na tecla Windows. Eu tentei 3 teclados diferentes e o mesmo resultado. No xev, só recebo FocusOut, FocusIn e KeymapNotify, como visto acima. No entanto, posso ir e atalhos de configuração através gerente Gnome, e vê a tecla Windows como "Mod4"
Yaroslav Bulatov
Os relatórios de teclas direita do Windows como Mod4, os relatórios de teclas esquerda como Alt ... o que é confuso porque eu nem tenho uma categoria "Alt" no meu xmodmap.
Yaroslav Bulatov 02/10/12
Tente Mod1 para Alt.
precisa saber é o seguinte
2
@YaroslavBulatov soa como seu ambiente de trabalho está comendo a chave (possivelmente para abrir seu menu principal?)
derobert
3
Você pode filtrar os eventos que o xev fornece a você. Nesse caso, xev -event keyboardseria suficiente para livrar a maior parte do barulho.
Fredrik Wendt
24

xev deve funcionar

Estranho, meu xev fornece um evento KeyPress e KeyRelease para alt (e para a chave do Windows, aqui chamada "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 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. Outra coisa é comer completamente o pressionamento de tecla ou desfocar a janela quando você pressiona alt. Tente executar o xev em um servidor X vazio (por exemplo, basta executar xinit -- :1, o que deve lhe dar um servidor X com apenas um xterm - nem haverá um gerenciador de janelas em execução. Sair do xterm fechará a sessão).
  2. Você acabou de perder os dois eventos em massa que o xev vomita.

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

Outra possibilidade: basta obter os códigos de chave no 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)

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

derobert
fonte
15

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

  1. Por que xeve showkeyrelatar códigos de chave diferentes para uma chave?
  2. Por que xevnão aparece Altsendo pressionado corretamente?
  3. Como trocar Alte Win?

Com relação à primeira pergunta: hoje em dia, onde o "driver" do teclado no X realmente não conduz o hardware, ele pode simplesmente passar os códigos de chave do kernel para o núcleo do X, mas não o faz. Ele adiciona 8 ao código-chave antes de transmiti-lo.

Segundo: Algo na sua sessão X está agarrando o Altevento. As outras respostas já cobrem isso. (Ou seja 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 troca Alte Winjá existe uma opção preparada no XKB. Basta adicioná-lo:

$ setxkbmap -option altwin:swap_alt_win
$ setxkbmap -query
rules:      evdev
model:      pc105
layout:     us
variant:    altgr-intl
options:    altwin:swap_alt_win,caps:backspace
Robert Siemer
fonte
Como você torna a setxkbmapmudança permanente?
Steve Kehlet
Adicione a alteração em ~/.xinitrc.
Matthias Braun
11

Como root, execute:

showkey -s

... para ver qual é o scancode da sua chave de mistério. Eu tenho algo parecido com isto:

# 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 de keydown / keyup, o mais próximo que pude perceber pelo padrão. Observe o aviso, portanto, você pode querer executá-lo no modo de usuário único.

Imaginei que 0x46 fosse o meu scancode.

Em seguida, encontre um código-chave não utilizado com:

xmodmap -pke | less

Aqui você pode ver que o keycode 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 código de chave X usa e o código de chave que o kernel usa é DESLIGADO POR 8 por "razões históricas". Portanto, pegue 97 - 8 = 89 e use 89 com o comando setkeycodes (novamente como root):

# setkeycodes 46 89

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

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

Greg
fonte
1
Você tem um ponteiro sobre "desligado por 8 por razões históricas"?
Robert Siemer 14/11
Usei sua resposta para mapear caps-lock em uma tecla de função (especificamente F9). Isso me permite usar F9 como a chave de prefixo no tmux. Obrigado.
Raymond Kroeker
@RobertSiemer tldp.org/HOWTO/Keyboard-and-Console-HOWTO-15.html "Freqüentemente o número X será 8 a mais que o número do Linux". Minha redação com "histórico" deve ter sido de outra página de manual.
Greg Bell
11

Eu estava tentando resolver isso sozinho e só descobri.

O principal problema é que você não está recebendo o evento para pressionar a tecla. Observando o log que você postou, o motivo é 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 os os Focus{In,Out}eventos têm um modedos Notify{Grab,Ungrab}. Isso indica que uma chave foi manipulada por outro processo (provavelmente um aplicativo de atalho / combinação de teclas).

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

Se você não conseguir determinar qual programa está roubando os principais eventos, a melhor solução é iniciar outra sessão X sem ela ser executada. Execute o comando a seguir para iniciar outra sessão X em exibição :1, se já tiver sido tomada, apenas aumente o número no final. É claro que você pode alterar o terminal para o que preferir ou instalar em seu sistema.

xinit /usr/bin/xterm -- :1

Então corra xevnovamente. Isso deve fornecer o resultado sem que ele seja capturado por outros programas. Observe que o gerenciador de janelas que é iniciado é foco focalizado, portanto, você terá que colocar o cursor acima da janela xev para que as chaves sejam capturadas.


Como foi dito nesta excelente resposta por dubiousjim , o código-chave é diferente porque há muitas camadas entre o xev e o kernel.

Kevin Cox
fonte
4

Eu tive o mesmo problema ao Alt_Ldesaparecer no XUbuntu 14.04 ( Alt_Restava bom). Depois de muito jogo, observei que showkeygravou o pressionamento de tecla, mas xevnão - tinha que ser algo no sistema de janelas. Examinei todas as configurações do "Gerenciador de Janelas" e "Ajustes do Gerenciador de Janelas" e não encontrei nada. Por fim, encontrei um desvio Alt_Lna lista de atalhos de teclado ( xfce4-keyboard-shortcuts) no "Editor de configurações". Eu "redefino" isso e estou de Alt_Lcostas! O Alt_Latalho perdido não apareceu em nenhum outro lugar, exceto no "Editor de configurações".

Paul Price
fonte