Due to an influx of spam, we have had to impose restrictions on new accounts. Please see this wiki page for instructions on how to get full permissions. Sorry for the inconvenience.
Admin message
Our infrastructure migration is complete. Please remember to update your SSH remote to point to ssh.gitlab.freedesktop.org; SSH to the old hostname will time out. You should not see any problems apart from that. Please let us know if you do have any other issues.
I am acting as an intermediate for Christophe. He has filed a bug in the Debian BTS, that follows:
When doing something like
xkbcomp $DISPLAY /tmp/xkb
<edit /tmp/xkb to change key autorepeat state>
xkbcomp /tmp/xkb $DISPLAY
to change some keys' autorepeat state as viewed by the X server, the
autorepeat states are silently unchanged.
I believe that this is because the code which would be responsible for
changing the state is commented out:
#ifdef NOTYET
...
#endif
in XkbWriteToServer in srvmisc.c.
My IBM X40 Thinkpad has two keys which I would like to turn into Hyper
and Super modifiers; however, their default state is to autorepeat, and
I can't turn this off using xkbcomp. (Using xset -r <keycode> works,
however, as does generating an XkbSetControls request manually).
I'd be happy to provide more information or provide sample files if that
would help.
Version: 7.1 (2006.05)
Designs
Child items ...
Show closed items
Linked items 0
Link issues together to show that they're related.
Learn more.
Indeed, xkbcomp used XkbWriteToServer from libxkbfile, but XkbWriteToServer has the call "XkbSetControls" ifdef-ed out. To the per-key-repeat array (which is part of the XkbControls) is not updated in the server.
I can't guess why it's commented out like this, I will have to try it.
I wanted to try it, but actually when I'm trying your example from bug #78661, I cannot reproduce the problem. Please see the attached file for the steps I took. It seems like the server does receive the repeat=Yes and the Ctrl+Alt+Up does repeat.
Can you please read the steps and try them, and see if there's any diff showing at the end?
Attachment 99162, "Steps to try to reproduce": steps
ok, now I can reproduce the problem for you. And found something interesting. Please see the attached script.
Somewhere on the path from the xkb file to the X server, the repeat bits get messed up and overwritten with their old values.
As a result, it appears that this happens:
when there is a "repeat=" setting in the key definition
the X server will change the repeat setting for that key
but NOT to the repeat value defined in the xkb file
but to the repeat value that the X server had stored for this key BEFORE the new definition
So as shown by the attached script...
xset r 111
xkb input to X: "repeat= yes" or "repeat= no"
xkb output from X: "repeat= yes"
xset -r 111
xkb input to X: "repeat= yes" or "repeat= no"
xkb output from X: "repeat= no"
xset r 111 or xset -r 111
xkb input to X: repeat not mentioned
xkb output from X: repeat not mentioned
This would also explain why you could not reproduce the problem while it occurs to me after a clean reboot. You tried your script on a system that was up and running and thus had the repeat bit for key 111 set already. But I tried after a reboot when (apparently) the repeat bit for key 111 wasn't set, yet.
This diagnosis is still guesswork, so forgive me if this is incorrect.
Hi Hanno, thanks for investigating. Until I feel like looking at it, I can at least give you some details that might help pinpoint the issue.
There are two things at play here: core X input (let's call it "Core") and the XKB extension. The core input provides the original X11 requests, and is very simple. XKB provides many more capabilities.
(In fact it's also possible to change keyboard controls using the XInput1 extension, but that's equivalent to Core here).
Assuming that XKB is enabled, the key-repeat settings between Core and XKB are supposed to be synchronized; that is, if you use one of the above requests it should be recognized by the other. (One place where this shows is the fact in XKB the key-repeat setting is for the entire key rather then per key-group or even key-group-level, which is more sensible. But due to backward compatibility with Core [I'm guessing] they left it per-key).
Now I'll describe what happens in the various cases.
Server start up. The server itself reads your config values from xorg.conf ("RMLVO" - rules/model/layout/variant/options). It looks at the "rules" files to translate the RMLVO (well, it already used the "R" part) to a "KCCGST" (keycodes/types/compat/symbols/geometry) which is the format of the XKB keymaps. It then forks xkbcomp to compile the KCCGST for it. xkbcomp processes all of the needed xkeyboard-config files and then serializes the compiled keymap back to the server over a pipe in a (pretty bad and in some rare cases lossy) format called "XKM". Server deserializes this format and then it has its initial keymap, more or less.
xkbcomp $DISPLAY out.xkb to download the active keymap. xkbcomp in this case uses various functions from libX11, like XkbGetMap and XkbGetControls, which use an XKB request of the same name to get all the parts of the keymap. Then it uses the libxkbfile library to convert the keymap struct to text and print it.
xkbcomp out.xkb $DISPLAY to upload a keymap to the server. In this case xkbcomp reads the given file and compiles it to a keymap struct itself. Then it uses the XkbWriteToServer() function from libxkbfile to write the new keymap to the server. XkbWriteToServer calls various functions from libX11 like XkbSetMap which use the XKB requests of the same name. (Here though XkbSetControls is commented out with NOTYET as pointed out in this bug). Note that these request modify the active keymap in the server in-place, as opposed to (1) which creates a keymap.
xset +/-r <keycode>. This just uses the Core ChangeKeyboardControl request (through a wrapper in libX11).
Internally in the server all changes to key-repeat settings are supposed to percolate to the dev->kbdfeed->ctrl.autoRepeats array of each keyboard device, which is a simple bitmap with repeat/no-repeat for each key.
So as you can see there are a lot of places where things can go wrong. One seemingly obvious culprit seemed to be the mysterious NOTYET on XkbSetControls but you say removing it doesn't help. So other problems can be in the Core/XKB interaction (which can be buggy), or maybe one of the functions along the way ignores/overrides the perKeyRepeat array, or just some coding error.
One final note: you may wonder if the perKeyRepeat array is a bitmap, how come xkbcomp only shows Repeat=True/False for keys where you've set it explicitly? Well fittingly enough the keymap contains an "explicit" array which says among other things if each key has an explicit key-repeat setting. If there isn't libxkbfile doesn't print it to the keymap file.
Well that was a lot to write just to avoid looking at old XKB code :)
Thanks! Will go hunt for clues in the source code of the various packages.
Please try patching the NOTYET section yourself. I'm not sure if things were done right that right when I tried that.
Thanks for the write-up. Looking at the source of the various packages, there appear to be several duplicated implementations of XKB file parsing. One wonders why these haven't been merged to one library so that when things go wrong, it's just one place to look at.
I'm not much into X source and thus still guess what the code does. But the problem might be in XkbUpdateActions in xkb/xkbUtils.c where there is some back and forth memcpy copying of repeat bits going on.
I was able to reproduce the problem using your scripts. Indeed with a patched libxkbfile (which I think is required in any case), the problem still occurs. I can see that libxkbfile calls XkbSetControls with key 111's repeat bit is 1 and explicit-repeat bit also 1:
-#ifdef NOTYET
printf("111 r is: %d\n", xkb->ctrls->per_key_repeat[111/8] & (1 << (111 % 8)));
printf("111 exp is: %d\n", xkb->server->explicit[111] & XkbExplicitAutoRepeatMask);
if (!XkbSetControls(dpy, XkbAllControlsMask, xkb))
return False;
-#endif
Since libX11's XkbSetControls function seems fine to me, I think the XkbSetControls request is also sent properly to the server.
So if we look at the "in -> server -> out" path, besides the NOTYET problem in the "in" part there is a problem somewhere in the "server -> out" parts.
In the "server" part the XkbSetControls is handled in src/xkb.c. It calls XkbDDDChangeControls which shuffles around 3 perKeyRepeat arrays, it might be worth checking if there's a problem there maybe. However testing modified X servers is a bit difficult for me now, so I'll leave it to you or another time.
Works perfectly when I'm loading it manually via xkbcomp -I$HOME/.xkb ~/.xkb/keymap/mykbd $DISPLAY
However, when included from /usr/share/X11/xkb, the keys do not autorepeat.