I have fixed a problem with changing xkb keymaps. The problem occured when i switched from a keymap which had 'types' w/ 2 shift levels to one w/ types w/ 4 shift levels, and affects (probably) only XKB-unaware applications.
The type information (on the excess shift levels) was NOT UPDATED. It is due to 'insufficient' translation from the XKB event to X core event.
The XKB code is very complex, and i stopped looking at all details, when i found a working solution. In particular i didn't understand when XkbNewKeyboardNotify event arrives instead of XkbMapNotify. I will return to it later.
The patch is 1 line in xc/lib/X11/XKBUse.c .
I include 2 other 1-line changes to xc/lib/X11/XKBGetMap.c
--- XKBUse.c.old 2004-02-22 01:21:35.000000000 +0100
+++ XKBUse.c 2004-02-21 03:15:27.000000000 +0100
@@ -305,7 +305,7 @@
ev->count = mn->nKeySyms;
_XkbNoteCoreMapChanges(&xkbi->changes,ev,XKB_XLIB_MAP_MASK);
if (xkbi->changes.changed)
- xkbi->flags|= XkbMapPending;
+ xkbi->flags|= XkbMapPending | XkbXlibNewKeyboard;
return True;
}
}
--- XKBGetMap.c.old 2004-02-22 01:22:27.000000000 +0100
+++ XKBGetMap.c 2004-02-21 03:18:45.000000000 +0100
@@ -150,6 +150,7 @@
register int i;
XkbClientMapPtr map;
+ if ( rep->totalSyms>0 ) {
map= xkb->map;
if (map->key_sym_map==NULL) {
register int offset;
@@ -236,6 +237,7 @@
oldMap->width = newMap->width;
}
}
+ }
return Success;
}
@@ -478,7 +480,7 @@
}
extraData= (int)(rep->length*4);
extraData-= (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply));
- if (rep->length) {
+ if (extraData) {
XkbReadBufferRec buf;
int left;
if (_XkbInitReadBuffer(dpy,&buf,extraData)) {