Search code examples
c++xlibcapslock

XKB - Get Caps Lock mask


I've been trying to write a program that enables/disables different locks (num lock, caps lock, scroll lock), but I've been having issues with caps lock. For some reason, XKB doesn't know about "CapsLock" vmod, while it does know about ScrollLock and NumLock.

How do I get the caps lock mask?


My function is this (nearly directly copied from numlockx):

unsigned int KL_Modifier::get_mask(const char* name) {
    XkbDescPtr xkb;
    if ((xkb = XkbGetKeyboard(this->disp, XkbAllComponentsMask, XkbUseCoreKbd)) != NULL) {
            int i;
            unsigned int mask = 0;
            if (!xkb || !xkb->names) {
                    mask = 0;
                    goto end;
            }
            for (i = 0; i < XkbNumVirtualMods; i++) {
                    char* mod_str = XGetAtomName(this->disp, xkb->names->vmods[i]);
                    std::cout << mod_str << " " << name << std::endl;
                    if (mod_str != NULL && strcmp(name, mod_str) == 0) {
                            XkbVirtualModsToReal(xkb, 1 << i, &mask);
                            //break;
                    }
            }
end:
            XkbFreeKeyboard(xkb, 0, True);
            return mask;
    }
    return 0;
}

I call it like this:

unsigned int mask = this->get_mask("CapsLock");
assert(mask != 0);

Solution

  • I don't know what my problem was, but I found a solution: Use XkbKeysymToModifiers instead, like this:

    unsigned int mask = XkbKeysymToModifiers(display, XK_Caps_Lock);
    

    Where display is a Display*. With this solution, I was able to switch XK_Caps_Lock to XK_Num_Lock and XK_Scroll_Lock for the other locks.