La interrupción del soporte a xneur me causó ciertas dificultades en los últimos seis meses (con la llegada de OpenSUSE 15.1 en mis escritorios: con xneur activado, las ventanas pierden el enfoque y parpadean divertidamente al ritmo de la escritura en el teclado).
"Ah, maldita sea, otra vez empecé a escribir en la distribución equivocada" — esto ocurre con una frecuencia indecorosa en mi trabajo. Y no aporta ninguna positividad.

Al mismo tiempo, yo (como ingeniero diseñador) puedo formular con bastante claridad lo que quiero. Y quería exactamente una cosa (primero de Punto Switcher, y luego, gracias a Windows Vista, al pasarme finalmente a Linux, de xneur). Al darme cuenta de que en la pantalla hay un desorden en la distribución equivocada (esto suele ocurrir al final de escribir una nueva palabra), solo quería golpear "Pause/Break". Y obtener lo que había escrito.
En este momento, el producto tiene una relación funcionalidad/complejidad óptima (desde mi punto de vista). Es hora de compartir.
TL.DR
A continuación, vendrán varios detalles técnicos, así que primero — para los impacientes.
Actualmente, el comportamiento siguiente está fijado:
- "Pause/Break": elimina (Backspace) la última palabra, cambia la distribución en la ventana activa (entre 0 y 1) y vuelve a escribir.
- "Control izquierdo sin nada": cambia la distribución en la ventana activa (entre 0 y 1).
- "Shift izquierdo sin nada": activa la distribución №0 en la ventana activa.
- "Shift derecho sin nada": activa la distribución №1 en la ventana activa.
A partir de este momento, planeo personalizar el comportamiento. Sin retroalimentación, no es interesante (ya estoy satisfecho). Supongo que habrá suficiente porcentaje de audiencia en Habr con problemas similares.
N.B. Dado que en la versión actual el keylogger se conecta a "/dev/input/", xswitcher debe ejecutarse con privilegios de root:
chown root:root xswitcher
chmod +xs xswitcherPor favor, ten en cuenta: el propietario del archivo con suid debe ser root, ya que quien es el propietario — se convierte en suid al ejecutarse.
Los paranoicos (yo no soy la excepción) pueden clonar desde y compilar en el lugar. Más o menos así:
go get "github.com/micmonay/keybd_event"
go get "github.com/gvalkov/golang-evdev"
### Encabezados de X11 para OpenSUSE/deb-based
zypper install libX11-devel libXmu-devel
apt-get install libx11-dev libxmu-dev
cd "x switcher/src/"
go build -o xswitcher -ldflags "-s -w" --tags static_all src/*.go
Añadir el autostart a gusto (dependiendo del DE).
Funciona, "no pide nada" (≈30 segundos de CPU al día, ≈12 MB en RSS).
Detalles
Ahora — los detalles.
Todo el repositorio se dedicó inicialmente a mi proyecto personal, y no tengo ganas de crear otro por ahora. Así que, todo está amontonado (simplemente en carpetas) y cubierto por AGPL (“patente inversa”).
El código de xswitcher está escrito en golang, con mínimas inserciones de C. Se supone que este enfoque dará el menor esfuerzo posible (hasta ahora ha sido así). Manteniendo la posibilidad de conectar lo que falta a través de cgo.
A lo largo del texto se han colocado comentarios sobre de dónde tomé qué y por qué. Dado que el código de xneur no me “inspiró”, tomé como punto de partida .
El uso de "/dev/input/" tiene sus ventajas (todo se puede ver, incluyendo la tecla presionada con repetición automática) y desventajas. Las desventajas son las siguientes:
- La repetición automática (eventos con el código “2”) no correlaciona con la repetición desde X.
- No se ve la entrada a través de interfaces X11 (así es como funciona, por ejemplo, VNC).
- Se necesita root.
Por otro lado, se pueden suscribir a eventos X a través de “XSelectExtensionEvent()”. Se puede consultar en . Para go no encontré nada parecido, y la implementación preliminar dio de inmediato un centenar de líneas de código en C. Por ahora lo he dejado a un lado.
La salida “inversa” se ha hecho hasta ahora a través de la adición de un teclado virtual. Gracias al autor de keybd_event, pero allí la abstracción es demasiado alta y tendré que rehacerlo más adelante. Por ejemplo, en mi caso, la tecla Win derecha selecciona la fila 3. Y la izquierda se traduce de vuelta.
Errores conocidos
- No sabemos nada sobre la entrada “compositiva” (ejemplo: ½). En este momento no es necesario.
- Reproducimos incorrectamente la tecla Win derecha. En mi caso, rompe la colocación de acentos.
- No hay un análisis claro de la entrada. En su lugar, hay varias funciones: Compare(), CtrlSequence(), RepeatSequence(), SpaceSequence(). Gracias por la atención: lo corregí en el código y aquí. Con cierta probabilidad, se pueden obtener errores al hacer el cambio.
En este lugar no sé “cómo hacer” y agradeceré cualquier sugerencia. - (Oh no) uso concurrente de canales (keyboardEvents, miceEvents).
Conclusión
El código es el procedimiento más simple. Y tonto como yo. Así que me engaño a mí mismo con la esperanza de que cualquier técnico pueda completar lo que deseo. Y este producto no desaparecerá sin apoyo como la mayoría de just-for-fun.
¡Buena suerte!
Fuente: habr.com
