Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

478
Visualizações
How to get the character for an XLib key wrt the keyboard layout?

Using XKeycodeToKeysym (in C++) I can get the KeySym for a key-press event. From what I understand this already should respect the keyboard layout. However, when I switch a keyboard layout (between english and hebrew) I get the same KeySym. I suspect that the Xlib Keysym only honors keyboard layout defined in the X11 level? In my system the keyboard layouts are defined only in the desktop environment level (Mate). And if so, is there any way to get the correct character without using a toolkit like Qt / GTK? Must I handle each desktop environment separately?

[Edit]

I've tried the following (according to Andrey's suggestion), which doesn't work:

#include <X11/XKBlib.h>

#include <cstring>
#include <cassert>
#include <iostream>

int main() {
    Display *display = XOpenDisplay(nullptr);
    Window root, window;
    XSetWindowAttributes swa;
    root = DefaultRootWindow( display );
    XSelectInput( display, root, MappingNotify );
    std::memset(&swa, 0, sizeof swa );
    swa.event_mask = MappingNotify | KeyPressMask;
    window = XCreateWindow( display, root, 50, 200, 1024, 768, 0, CopyFromParent, InputOutput, CopyFromParent,
                             CWEventMask, &swa );
    XMapRaised( display, window );
    int xkbEventCode=0, n0=0, n1=0, n2=0, n3=0;
    bool isOk = XkbQueryExtension(  display, &n0, &xkbEventCode, &n1, &n2, &n3 ) ==True;
    assert( isOk );
    isOk = XkbSelectEvents( display, XkbUseCoreKbd, XkbAllEventsMask, XkbAllEventsMask ) ==True;
    assert( isOk );
    while (true) {
        XEvent event;
        std::memset( &event, 0, sizeof event );
        XNextEvent( display, &event );
        if (event.type == xkbEventCode)
            switch (reinterpret_cast<XkbEvent*>(&event)->any.xkb_type) {
              case XkbNewKeyboardNotify:
              case XkbMapNotify: {
                std::cout << "Keyboard mapping has changed." << std::endl;
                break;
                }
            default:  break;
            }
        else
            switch (event.type) {
              case KeyPress: {
                KeyCode keyCode = event.xkey.keycode;
                int keySymsPerkeyCode=0;
                KeySym *keySyms( XGetKeyboardMapping(display, keyCode, 1, &keySymsPerkeyCode)),
                       *keySym = keySyms;
                while (keySymsPerkeyCode--  &&  *keySym != NoSymbol) {
                    std::cout << *keySym << std::endl;
                    ++keySym;
                    }
                XFree( keySyms );
                break;
                }
              case MappingNotify: {
                std::cout << "Keyboard mapping has changed." << std::endl;
                break;
                }
              default:  break;
              }
        }
    return 0;
    }
over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

I can answer only at a lower level, don't know what XKeycodeToKeysym does.

You need to listen for MappingNotify event and each time you receive it re-read new mapping (usually this means keyboard layout / language changed ) with XGetKeyboardMapping

This is part of core X protocol, desktop environment / WM independent

update:

Looks like xlib enables XKeyboard extension by default. After it's enabled you need to explicitly express interest in mapping change events ( unlike with core protocol where MappingNotify is always sent to all clients ) - see http://www.x.org/archive/X11R7.5/doc/man/man3/XkbSelectEvents.3.html

 XkbSelectEvents (display, XkbUseCoreKbd, XkbAllEventsMask, XkbAllEventsMask);

After that you respond to XkbMapNotify event and do XkbGetMap() to get new layout

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda