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);
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.