Cómo reasignar teclas en Linux solo para un teclado específico


18

Recientemente compré un teclado Unicomp que viene con teclas de Windows y Alt derecha intercambiadas. El teclado se identifica así en lsusb:

Bus 003 Device 002: ID 17f6:0822 Unicomp, Inc 

¿Hay alguna manera de hacer que el kernel (es decir, no basado en xmodmap) intercambie las teclas right-alt y windows para que todas las aplicaciones las vean en los lugares intercambiados incluso si obtienen una entrada de teclado sin procesar (intercambiar cosas con xmodmap no hará eso) ? ¿Hay alguna manera de tener eso solo para este teclado?


Sospecho que podría hacer esto con udev haciendo coincidir el número de serie del teclado y luego llamando a un script que realiza la reasignación. Probablemente necesitará una secuencia de comandos similar para ser llamada al separar para que el dispositivo la vuelva a colocar.
mermelada

1
@jam ¿Esto reasignaría todos los teclados conectados? No puedo imaginar que Linux sea tan inflexible que solo pueda administrar una tabla de mapeo para todos los teclados (USB) conectados.
FUZxxl

@ jam Además, realmente me ayudarías si pudieras describir cómo hacer el intercambio real. No logré encontrar nada útil en esto, solo cosas de xmodmap (que no quiero usar).
FUZxxl

Si no desea usar xmodmap, lo que está preguntando parece ser demasiado específico para mi conocimiento como para ayudarlo a que lo sienta. El método que propuse usaría xmodmap para intercambiar los códigos de teclas de esas teclas para todos los dispositivos, durante el tiempo que esté conectado su teclado específico, y luego volver a colocarlo. ¿Espera usar varios teclados simultáneamente?
Jam

@jam Si usara Xmodmap, los programas X seguirían viendo códigos de clave incorrectos ya que el servidor X también envía códigos de clave no traducidos al cliente. Esto es importante, por ejemplo, para los videojuegos. Se supone que hay una solución en el kernel que no me complica la vida con aplicaciones que leen códigos de escaneo.
FUZxxl

Respuestas:


27

Sí, es posible usar XKB. A diferencia de xmodmap, XKB puede reasignar sus claves para dispositivos individuales.

Nota: Asegúrese de tener xkbcomp> 1.2.0

Primero enumere sus dispositivos con:

xinput list

Obtendrás algo como esto:

⎡ Virtual core pointer                      id=2    [master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer                id=4    [slave  pointer  (2)]
⎜   ↳ Wacom Bamboo Pen Pen stylus               id=11   [slave  pointer  (2)]
⎜   ↳ Wacom Bamboo Pen Finger touch             id=12   [slave  pointer  (2)]
⎜   ↳ Logitech USB-PS/2 Optical Mouse           id=13   [slave  pointer  (2)]
⎜   ↳ Wacom Bamboo Pen Pen eraser               id=14   [slave  pointer  (2)]
⎜   ↳ Wacom Bamboo Pen Finger pad               id=15   [slave  pointer  (2)]
⎜   ↳ GASIA USB KB V11                          id=17   [slave  pointer  (2)]
⎣ Virtual core keyboard                     id=3    [master keyboard (2)]
    ↳ Virtual core XTEST keyboard               id=5    [slave  keyboard (3)]
    ↳ Power Button                              id=6    [slave  keyboard (3)]
    ↳ Power Button                              id=7    [slave  keyboard (3)]
    ↳ G19 Gaming Keyboard                       id=8    [slave  keyboard (3)]
    ↳ G19 Gaming Keyboard                       id=9    [slave  keyboard (3)]
    ↳ Logitech G19 Gaming Keyboard              id=10   [slave  keyboard (3)]
    ↳ GASIA USB KB V11                          id=16   [slave  keyboard (3)]

Identifique la cadena de su dispositivo y edite el siguiente script de shell, cambiando la línea de sed con una que se ajuste al nombre de su dispositivo. Luego cambie las teclas que necesita reasignar.

Ejemplo: cargue xevy presione la tecla que desea reasignar. Suponga que descubre que es el código clave 84. Busque 84 en https://gist.github.com/zoqaeski/3880640 . El nombre clave que hay <KP5>. Luego busque la clave por la que desea reemplazarla (en el mismo enlace, más abajo ) y copie lo que está dentro de los corchetes. Repita el proceso para todas las teclas que desee.

remote_id=$(
    xinput list |
    sed -n 's/.*GASIA.*id=\([0-9]*\).*keyboard.*/\1/p'
)
[ "$remote_id" ] || exit

# remap the following keys, only for my custom vintage atari joystick connected
# through an old USB keyboard:
#
# keypad 5 -> keypad 6
# . -> keypad 2
# [ -> keypad 8
# left shift -> left control

mkdir -p /tmp/xkb/symbols
# This is a name for the file, it could be anything you
# want. For us, we'll name it "custom". This is important
# later.
#
# The KP_* come from /usr/include/X11/keysymdef.h
# Also note the name, "remote" is there in the stanza
# definition.
cat >/tmp/xkb/symbols/custom <<\EOF

xkb_symbols "remote" {
    key <KP5>  { [ KP_Right, KP_6, U2192, U21D2 ]       };
    key <I129> { [ KP_Down, KP_2, U2193, U21D3 ]       };
    key <AD12> { [ KP_Up, KP_8, U2191, U21D1 ]  };
    key <LFSH> { [ Control_L ]        };
};
EOF

# (1) We list our current definition
# (2) Modify it to have a keyboard mapping using the name
#     we used above, in this case it's the "remote" definition
#     described in the file named "custom" which we specify in
#     this world as "custom(remote)".
# (3) Now we take that as input back into our definition of the
#     keyboard. This includes the file we just made, read in last,
#     so as to override any prior definitions.  Importantly we 
#     need to include the directory of the place we placed the file
#     to be considered when reading things in.
#
# Also notice that we aren't including exactly the 
# directory we specified above. In this case, it will be looking
# for a directory structure similar to /usr/share/X11/xkb
# 
# What we provided was a "symbols" file. That's why above we put
# the file into a "symbols" directory, which is not being included
# below.
setxkbmap -device $remote_id -print \
 | sed 's/\(xkb_symbols.*\)"/\1+custom(remote)"/' \
 | xkbcomp -I/tmp/xkb -i $remote_id -synch - $DISPLAY 2>/dev/null

Luego fuente (puede agregarlo a su .xinitrc). ¡Todo listo! Ahora presionar las teclas debería generar la salida deseada, solo para el dispositivo que especificó.

Editar : Recientemente, he notado que, por alguna razón, la nueva configuración no se aplica de inmediato. Primero debe presionar una tecla en su otro teclado, luego probar las teclas configuradas en su teclado modificado. No sé por qué sucede esto, tal vez algún tipo de caché.


Permítanme probar esto el lunes cuando regrese a la computadora donde uso este teclado.
FUZxxl

1
a) sed -n 's/.*G19 Gaming Keyboard.*id=\([0-9]*\).*keyboard.*/\1/p' c) Sí, definitivamente debe probarlo primero reemplazando $remote_idcon el número de identificación. Tenga en cuenta que hay dos referencias $remote_idallí, ¿cambió las dos?
Watcom

1
Ah, y cuando pruebes el codificado $remote_id, asegúrate de comentar la línea [ "$remote_id" ] || exitsi aún no lo has hecho, de lo contrario simplemente se rescatará.
Watcom

1
@ stats-hb $9no funcionará, ¿querías decir 9?
Watcom

1
esto funciona para mí lampjs.wordpress.com/2015/06/26/…
usil

6

Para cualquier otra persona que venga de Google y quiera una respuesta más en línea con lo que el interlocutor esperaba originalmente, conozco dos formas de reasignar eventos a evdevnivel para que el cambio se aplique a todas las aplicaciones:

  1. udev proporciona una API para modificar las entradas de la base de datos de hardware que controlan las asignaciones entre códigos de escaneo y códigos clave. Esta página de ArchiWiki , que contiene instrucciones, dice explícitamente que funcionará tanto para X11 como para la entrada de la consola.

    La esencia es que crea una entrada personalizada /etc/udev/hwdb.d/que consiste en un patrón de coincidencia del dispositivo y algunas definiciones de reasignación de código de escaneo a código clave, luego se ejecuta systemd-hwdb updatepara reconstruir la base de datos y udevadm triggeraplicarla sin reiniciar.

  2. Dado que Wayland no usa el subsistema de teclado X11 y los principales compositores de Wayland como GNOME Shell y Weston no implementan interfaces de usuario para configurar los aspectos relevantes de libinput, alguien escribió un demonio llamado evdevremapkeys que resuelve el problema de manera similar al controlador de espacio de usuario G15Daemon para Logitech Teclados para juegos G15.

    (Se traga los eventos que pretende reasignar, por lo que nada más que escuche en el dispositivo puede verlos, luego emite los eventos corregidos a través de la uinputAPI para crear dispositivos de entrada a nivel de kernel desde el espacio de usuario).


Vengo de DuckDuckGo, pero gracias por la respuesta de todos modos (:
sm4rk0

0

Para aquellos que no tuvieron éxito con la opción @Watcom, simplemente coloque su nuevo archivo de mapeo, algo así como:

xkb_symbols "remote" {
    key <KP5>  { [ KP_Right, KP_6, U2192, U21D2 ]       };
    key <I129> { [ KP_Down, KP_2, U2193, U21D3 ]       };
    key <AD12> { [ KP_Up, KP_8, U2191, U21D1 ]  };
    key <LFSH> { [ Control_L ]        };
};

Para / usr / share / X11 / xkb / symbols / como quizás root (ubuntu, puede ser diferente para su distribución), llame al archivo 'custom'. Solicite su cadena de diseño actual con setxkbmap -device <device id> -print | grep xkb_symbolsy agréguela +custom. Establezca un nuevo diseño con teclas reasignadas con una cadena de diseño modificada:

setxkbmap -device <device id> -layout "us+ru:2+us:3+inet(evdev)+capslock(grouplock)+custom"

El efecto no es permanente y desafortunadamente se restablece cuando se conecta otro teclado, todavía no se sabe cómo solucionarlo. Sin .bashrcembargo, puede agregar el comando anterior a su , para que las teclas se intercambien al reiniciar si es necesario.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.