Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

202
Vistas
¿Cómo capturar el evento de cambio de diseño de teclado y obtener un nuevo diseño de teclado actual en Linux?

Ahora, estoy trabajando en el desarrollo de aplicaciones en Linux y quiero capturar el evento de cambio de diseño del teclado (cambiar el diseño del teclado a través de UI/widget/shell/programación, etc.) y obtener/configurar la nueva información de diseño del teclado para continuar con el proceso. Creo que esta no es una pregunta nueva, pero busco en stackoverflow una y otra vez, pero no hay respuesta. ¡Espero poder obtener la respuesta correcta aquí!

La solución principal que quiero aprender se describe aquí. En Windows, el mensaje de Windows WM_INPUTLANGCHANGE podría capturarse en WinProc, que contiene información sobre el diseño del teclado. Y podríamos usar la API GetKeyboardLayout() para obtener información actual sobre el diseño del teclado. Finalmente, si quiero usar mi diseño de teclado preferido, podría usar ActivateKeyboardLayout() para activar el diseño de teclado.

En resumen, espero encontrar los mensajes de notificación y cómo capturar el mensaje en código (es mejor que me muestre un ejemplo) en Linux, la API Obtener diseño de teclado y la API Establecer diseño de teclado en Linux. El lenguaje de desarrollo es C/C++, también.

Gracias por adelantado.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

La otra respuesta no me funciona. Se compila y ejecuta, pero el evento MappingNotify no ocurre cuando cambio los diseños. Aquí hay una modificación que funciona para mí.

 #include <stdio.h> #include <X11/Xutil.h> #include <X11/XKBlib.h> int main(int argc, char **argv) { XEvent e; Display *d; if (!(d = XOpenDisplay(NULL))) { fprintf(stderr, "cannot open display\n"); return 1; } XKeysymToKeycode(d, XK_F1); int xkbEventType; XkbQueryExtension(d, 0, &xkbEventType, 0, 0, 0); XkbSelectEvents(d, XkbUseCoreKbd, XkbAllEventsMask, XkbAllEventsMask); XSync(d, False); while (1) { XNextEvent(d, &e); if (e.type == xkbEventType) { XkbEvent* xkbEvent = (XkbEvent*) &e; if (xkbEvent->any.xkb_type == XkbStateNotify) { int lang = xkbEvent->state.group; if (lang == 1) { fprintf(stdout, "1\n"); fflush(stdout); } else { fprintf(stdout, "0\n"); fflush(stdout); } } } } return(0); }

Compilar con:

 gcc -Wall -O2 xmappingnotify.c -o xmappingnotify -lX11

Yo lo uso así:

 xmappingnotify | xargs -I {} my-custom-command {} &

entonces my-custom-command [number_of_the_layout] se ejecuta cuando cambio los diseños. Tengo 2 diseños, xmappingnotify genera "1" para un diseño y "0" para el otro.

over 4 years ago · Santiago Trujillo Denunciar

0

Respuesta para X11:

Detectar cambios a través del evento MappingNotify

Cambiar o consultar el diseño a través de setxkbmap

Aquí hay un ejemplo básico de xlib para detectar eventos de MappingNotify:

 #include <stdio.h> #include <X11/Xlib.h> #include <X11/Xutil.h> #include <X11/keysym.h> int main(int argc, char **argv) { XEvent event; Display *dpy; if (!(dpy = XOpenDisplay(NULL))) { fprintf(stderr, "cannot open display\n"); return 1; } /** * Note: We might never get a MappingNotify event if the * modifier and keymap information was never cached in Xlib. * The next line makes sure that this happens initially. */ XKeysymToKeycode(dpy, XK_F1); while (1) { XNextEvent(dpy, &event); if (event.type == MappingNotify) { XMappingEvent *e = (XMappingEvent *) &event; if (e->request == MappingKeyboard) { fprintf(stderr, "The keyboard mapping was changed!\n"); } XRefreshKeyboardMapping(e); } } return(0); }

Comando construido:

 gcc -Wall -O2 xmappingnotify.c -o xmappingnotify -lX11
over 4 years ago · Santiago Trujillo Denunciar

0

Utilicé la respuesta de @gvlasov como una notificación de diseño de teclado en la barra dwm de Suckless con un parche de diseño de teclado por ventana. Funciona correctamente con respecto al resultado, pero produce demasiados eventos (ctrl, mod, teclas de mayúsculas, presionar y soltar y el movimiento de la rueda de desplazamiento del mouse genera el diseño; el correcto, pero esto no es necesario, solo cuando se cambia el diseño debe devolver el diseño ). Probablemente sea lo mencionado por el comentario de @matanster. Así que hice un cambio que detuvo la salida del movimiento de la rueda del mouse, aunque todavía se produce la salida de las teclas ctrl, mod, shift y pulsaciones. No es ideal, es un poco mejor:

Cambió la línea:

 XkbSelectEvents(d, XkbUseCoreKbd, XkbAllEventsMask, XkbAllEventsMask);

con este:

 XkbSelectEventDetails(d, XkbUseCoreKbd, XkbMapNotifyMask, XkbAllEventsMask, XkbAllEventsMask);

Si alguien tiene alguna idea de cómo obtener resultados / resultados solo en el cambio de diseño del teclado y no en las teclas ctrl, mod, shift, presione y suelte, es bienvenido.


Actualizar, usando esto:

 XkbSelectEventDetails(d, XkbUseCoreKbd, XkbStateNotify, XkbAllStateComponentsMask, XkbGroupStateMask);

Obtuve el resultado esperado. El único evento notificado es el cambio de distribución del teclado, ni las pulsaciones ni las liberaciones de teclas. El único inconveniente en comparación con mi línea anterior es que los cambios de mayúsculas no se notifican, lo que era posible antes.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda