Add documentation and cleanup previous PR

This commit is contained in:
Kovid Goyal 2021-04-03 06:25:47 +05:30
parent 777b9eb68e
commit d5448e6902
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 33 additions and 27 deletions

View File

@ -140,14 +140,17 @@ sub-field for the shifted key, like this::
Modifiers Modifiers
~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
This protocol supports four modifier keys, :kbd:`shift, alt, ctrl and super`. This protocol supports six modifier keys, :kbd:`shift, alt, ctrl, super, hyper
Here super is either the *Windows/Linux* key or the *Cmd* key on mac keyboards. and meta`. Here :kbd:`super` is either the *Windows/Linux* key or the *Cmd* key on
Modifiers are encoded as a bit field with:: mac keyboards. :kbd:`hyper` and :kbd:`meta` are typically present only on X11
based systems with special XKB rules. Modifiers are encoded as a bit field with::
shift 0b1 (1) shift 0b1 (1)
alt 0b10 (2) alt 0b10 (2)
ctrl 0b100 (4) ctrl 0b100 (4)
super 0b1000 (8) super 0b1000 (8)
hyper 0b10000 (16)
meta 0b100000 (32)
In the escape code, the modifier value is encoded as a decimal number which is In the escape code, the modifier value is encoded as a decimal number which is
``1 + actual modifiers``. So to represent :kbd:`shift` only, the value would be ``1 + ``1 + actual modifiers``. So to represent :kbd:`shift` only, the value would be ``1 +

43
glfw/xkb_glfw.c vendored
View File

@ -317,6 +317,7 @@ glfw_xkb_update_x11_keyboard_id(_GLFWXKBData *xkb) {
static void static void
glfw_xkb_update_masks(_GLFWXKBData *xkb) { glfw_xkb_update_masks(_GLFWXKBData *xkb) {
// See https://github.com/kovidgoyal/kitty/pull/3430 for discussion
bool succeeded = false; bool succeeded = false;
unsigned used_bits = 0; /* To avoid using the same bit twice */ unsigned used_bits = 0; /* To avoid using the same bit twice */
XkbDescPtr xkb_ptr = XkbGetMap( _glfw.x11.display, XkbVirtualModsMask | XkbVirtualModMapMask, XkbUseCoreKbd ); XkbDescPtr xkb_ptr = XkbGetMap( _glfw.x11.display, XkbVirtualModsMask | XkbVirtualModMapMask, XkbUseCoreKbd );
@ -324,34 +325,34 @@ glfw_xkb_update_masks(_GLFWXKBData *xkb) {
#define S( a ) xkb->a##Idx = XKB_MOD_INVALID; xkb->a##Mask = 0 #define S( a ) xkb->a##Idx = XKB_MOD_INVALID; xkb->a##Mask = 0
S(control); S(alt); S(shift); S(super); S(hyper); S(meta); S(capsLock); S(numLock); S(control); S(alt); S(shift); S(super); S(hyper); S(meta); S(capsLock); S(numLock);
#undef S #undef S
if ( xkb_ptr ) { if (xkb_ptr) {
Status status = XkbGetNames( _glfw.x11.display, XkbVirtualModNamesMask, xkb_ptr ); Status status = XkbGetNames(_glfw.x11.display, XkbVirtualModNamesMask, xkb_ptr);
if ( status == Success ) { if (status == Success) {
for ( int indx = 0; indx < XkbNumVirtualMods; ++indx ) { for (int indx = 0; indx < XkbNumVirtualMods; ++indx) {
Atom atom = xkb_ptr->names->vmods[indx]; Atom atom = xkb_ptr->names->vmods[indx];
if ( atom ) { if (atom) {
unsigned mask_rtn = 0; unsigned mask_rtn = 0;
if ( XkbVirtualModsToReal( xkb_ptr, 1<<indx, &mask_rtn ) ) { if (XkbVirtualModsToReal( xkb_ptr, 1<<indx, &mask_rtn) ) {
const char *name = XGetAtomName( _glfw.x11.display, atom ); const char *name = XGetAtomName(_glfw.x11.display, atom);
#define S( a, s ) if ( !(used_bits & mask_rtn) && strcmp( name, #s ) == 0 ) xkb->a##Mask = mask_rtn, used_bits |= mask_rtn #define S( a, s ) if (!(used_bits & mask_rtn) && strcmp(name, #s) == 0) xkb->a##Mask = mask_rtn, used_bits |= mask_rtn
/* Note that the order matters here; earlier is higher priority. */ /* Note that the order matters here; earlier is higher priority. */
S( alt, Alt ); S(alt, Alt);
S( super, Super ); S(super, Super);
S( numLock, NumLock ); S(numLock, NumLock);
S( meta, Meta ); S(meta, Meta);
S( hyper, Hyper ); S(hyper, Hyper);
#undef S #undef S
} }
} }
} }
succeeded = true; succeeded = true;
} }
XkbFreeNames( xkb_ptr, XkbVirtualModNamesMask, True ); XkbFreeNames(xkb_ptr, XkbVirtualModNamesMask, True);
XkbFreeKeyboard( xkb_ptr, 0, True ); XkbFreeKeyboard(xkb_ptr, 0, True);
} }
if ( succeeded ) { if (succeeded) {
unsigned indx, shifted; unsigned indx, shifted;
for ( indx = 0, shifted = 1; used_bits; ++indx, shifted <<= 1, used_bits >>= 1 ) { for (indx = 0, shifted = 1; used_bits; ++indx, shifted <<= 1, used_bits >>= 1) {
#define S( a ) if ( xkb->a##Mask == shifted ) xkb->a##Idx = indx #define S( a ) if ( xkb->a##Mask == shifted ) xkb->a##Idx = indx
S(alt); S(super); S(hyper); S(meta); S(numLock); S(alt); S(super); S(hyper); S(meta); S(numLock);
#undef S #undef S
@ -361,13 +362,14 @@ glfw_xkb_update_masks(_GLFWXKBData *xkb) {
S(control, XKB_MOD_NAME_CTRL); S(control, XKB_MOD_NAME_CTRL);
S(shift, XKB_MOD_NAME_SHIFT); S(shift, XKB_MOD_NAME_SHIFT);
S(capsLock, XKB_MOD_NAME_CAPS); S(capsLock, XKB_MOD_NAME_CAPS);
if ( !succeeded ) { if (!succeeded) {
S(numLock, XKB_MOD_NAME_NUM); S(numLock, XKB_MOD_NAME_NUM);
S(alt, XKB_MOD_NAME_ALT); S(alt, XKB_MOD_NAME_ALT);
S(super, XKB_MOD_NAME_LOGO); S(super, XKB_MOD_NAME_LOGO);
} }
#undef S #undef S
debug( "Modifier indices alt:%d super:%d hyper:%d meta:%d num>ock:%d\n", xkb->altIdx, xkb->superIdx, xkb->hyperIdx, xkb->metaIdx, xkb->numLockIdx ); debug("Modifier indices alt:%d super:%d hyper:%d meta:%d numlock:%d\n",
xkb->altIdx, xkb->superIdx, xkb->hyperIdx, xkb->metaIdx, xkb->numLockIdx);
} }
@ -378,7 +380,8 @@ glfw_xkb_update_masks(_GLFWXKBData *xkb) {
static void static void
glfw_xkb_update_masks(_GLFWXKBData *xkb) { glfw_xkb_update_masks(_GLFWXKBData *xkb) {
/* Should find better solution under evdev or wayland */ // Should find better solution under Wayland
// See https://github.com/kovidgoyal/kitty/pull/3430 for discussion
#define S( a ) xkb->a##Idx = XKB_MOD_INVALID; xkb->a##Mask = 0 #define S( a ) xkb->a##Idx = XKB_MOD_INVALID; xkb->a##Mask = 0
S(hyper); S(meta); S(hyper); S(meta);