I have used xmodmap in ~/.xinitrc to add the Super_R key to the mod3 modifier list. This worked well until the X.Org server was updated to a newer version. With this new version the Super_R key is still correctly added to the mod3 modifier list. But now the problem is that this operation affects some other modifier mappings. But only if there was no keystroke before xmodmap gets invoked for the first time. If there was a keystroke then everything works fine. Please see the test cases below. I am using the X.org server 7.3+10 from Debian testing. The ~/.xinitrc for the test cases: ( xmessage -geometry +10+10 "Run xmodmap?" && xmodmap -e "add mod3 = Super_R" && xmessage -geometry +10+10 "OK" ) & exec xterm -geometry x33+200+10 & exec twm Keyboard settings from /etc/X11/xorg.conf: Section "InputDevice" Identifier "Keyboard" Driver "kbd" Option "CoreKeyboard" Option "XkbRules" "xorg" Option "XkbModel" "pc105" Option "XkbLayout" "de" Option "XkbVariant" "nodeadkeys" EndSection Test case 1: Running xmodmap after a key was pressed: Works fine. Please see xmodmap-correct.png and xkeycaps-correct.png 1. Start X with startx 2. The xmessage pops up 3. Press some keys 4. Click okay with the mouse 5. Press Alt Gr + ß 6. Result: \ $ xmodmap -pm xmodmap: up to 3 keys per modifier, (keycodes in parentheses): shift Shift_L (0x32), Shift_R (0x3e) lock Caps_Lock (0x42) control Control_L (0x25), Control_R (0x6d) mod1 Alt_L (0x40), Meta_L (0x9c) mod2 Num_Lock (0x4d) mod3 Super_R (0x74) mod4 Super_L (0x7f), Hyper_L (0x80) mod5 Mode_switch (0x5d), ISO_Level3_Shift (0x71), ISO_Level3_Shift (0x7c) Test case 2: Running xmodmap before any key was pressed: Broken. Please see xmodmap-broken.png and xkeycaps-broken.png. 1. Start X with startx 2. The xmessage pops up 3. Click okay with the mouse 4. Press Alt Gr + ß 5. Result: Ü $ xmodmap -pm xmodmap: up to 3 keys per modifier, (keycodes in parentheses): shift Shift_L (0x32), Shift_R (0x3e) lock Caps_Lock (0x42) control Control_L (0x25), Control_R (0x6d) mod1 Alt_L (0x40), ISO_Level3_Shift (0x71), Meta_L (0x9c) mod2 Num_Lock (0x4d) mod3 Super_R (0x74) mod4 Super_L (0x7f), Hyper_L (0x80) mod5 Mode_switch (0x5d), ISO_Level3_Shift (0x7c) In the second test case the ISO_Level3_Shift (0x71) key is listed on the mod1 modifier list and in the first one this key was assigned to the mod5 modifier list. Moving the ISO_Level3_Shift (0x71) key manually from mod1 to mod5 in the second test case does fix it. See xmodmap-fixed.png and xkeycaps-fixed.png. This manual fix can't be done in the ~/.xinitrc file. What's going wrong here?
Created attachment 17125 [details] xkeycaps-correct.png
Created attachment 17126 [details] xmodmap-correct.png
Created attachment 17127 [details] xkeycaps-broken.png
Created attachment 17128 [details] xmodmap-broken.png
Created attachment 17129 [details] xkeycaps-fixed.png
Created attachment 17130 [details] xmodmap-fixed.png
On Sun, Jun 15, 2008 at 11:32:22AM -0700, bugzilla-daemon@freedesktop.org wrote: > I have used xmodmap in ~/.xinitrc to add the Super_R key to the mod3 modifier > list. This worked well until the X.Org server was updated to a newer version. > With this new version the Super_R key is still correctly added to the mod3 > modifier list. But now the problem is that this operation affects some other > modifier mappings. But only if there was no keystroke before xmodmap gets > invoked for the first time. If there was a keystroke then everything works > fine. Please see the test cases below. my guess would be the following: changing anything on the keyboard before a key has been pressed causes a change on the virtual core keyboard (VCK). when a key is pressed, this keyboard's settings are copied into the VCK, thus overwriting previous settings on the VCK. Since this only ever happens on a device switch, this won't happen again if you only have one keyboard, hence why your approach of setting it after the key press works. To verify this, plug in two keyboards, configure them as two separate devices (using evdev as driver) and then hit a key on one keyboard, run xmodmap, then see if everything works when you use the other keyboard.
On Thu, Jul 10, 2008 at 03:23:12AM -0700, bugzilla-daemon@freedesktop.org wrote: > --- Comment #7 from Peter Hutterer <peter.hutterer@who-t.net> 2008-07-10 03:23:12 PST --- > On Sun, Jun 15, 2008 at 11:32:22AM -0700, bugzilla-daemon@freedesktop.org > wrote: > > I have used xmodmap in ~/.xinitrc to add the Super_R key to the mod3 modifier > > list. This worked well until the X.Org server was updated to a newer version. > > With this new version the Super_R key is still correctly added to the mod3 > > modifier list. But now the problem is that this operation affects some other > > modifier mappings. But only if there was no keystroke before xmodmap gets > > invoked for the first time. If there was a keystroke then everything works > > fine. Please see the test cases below. > > my guess would be the following: changing anything on the keyboard before a > key has been pressed causes a change on the virtual core keyboard (VCK). > when a key is pressed, this keyboard's settings are copied into the VCK, thus > overwriting previous settings on the VCK. Rather. Peter, would this make sense to you: store the RMLVO names of the two devices, and if identical, copy the map from core to extended, instead of creating a new one? Of course, if they differ, create a new map on extended.
> Peter, would this make sense to you: store the RMLVO names of the two > devices, and if identical, copy the map from core to extended, instead > of creating a new one? Of course, if they differ, create a new map on > extended. This doesn't really fix the root of the problem. The problem is that the map is changed on the wrong device and later overwritten. Rather than storing stuff and a conditional copy, it'd be better to ensure that the map is stored on the right device in the first place. Then we don't have to worry about the copy. This means modifying the clients, i.e. modifying xkbcomp, xmodmap, and xwhateverelsethereis. The hard bit here is choosing which device to pick if none is specified. I guess a default policy of "all devices" would be a reasonable, if that doesn't work, then we can see what does later.
On Thu, Jul 10, 2008 at 05:58:26AM -0700, bugzilla-daemon@freedesktop.org wrote: > --- Comment #9 from Peter Hutterer <peter.hutterer@who-t.net> 2008-07-10 05:58:25 PST --- > > Peter, would this make sense to you: store the RMLVO names of the two > > devices, and if identical, copy the map from core to extended, instead > > of creating a new one? Of course, if they differ, create a new map on > > extended. > > This doesn't really fix the root of the problem. The problem is that the map > is changed on the wrong device and later overwritten. Rather than storing > stuff and a conditional copy, it'd be better to ensure that the map is stored > on the right device in the first place. Then we don't have to worry about the > copy. This means modifying the clients, i.e. modifying xkbcomp, xmodmap, and > xwhateverelsethereis. > > The hard bit here is choosing which device to pick if none is specified. I > guess a default policy of "all devices" would be a reasonable, if that doesn't > work, then we can see what does later. Heh, I think we perceive different problems, then. IMHO, devices should come up with a 'reasonable' default, which is more often than not the core keyboard's current map. Of course, MPX screws this sideways with a flagpole, but.
> Heh, I think we perceive different problems, then. IMHO, devices should > come up with a 'reasonable' default, which is more often than not the > core keyboard's current map. Of course, MPX screws this sideways with a > flagpole, but. not necessarily, the same rule works for MPX too, except that you have to pick which core device to use. The attached master is good, and it's picked for you anyway where needed. So this wouldn't change. Of couse, with two MDs working in the same app, you're screwed anyway, but - oh well. Anyway - to make sure we don't talk about two different things: if xmodmap is called for the core keyboard, we have to chose either whether you change the VCK, or the extension devices. If we just change the VCK, it may get overwritten later. If we change the extension devices, then theirs gets pulled into the VCK anyway, so we're good. So the policy change I see here is "xmodmap for core devices == change all devices" and "xmodmap for specific device == only this device changes". That right?
Just as an interim solution, we use the following patch in fedora for server 1.5. From 638cab7e1dc3711f7fb04155bcdabf4b8895cc5e Mon Sep 17 00:00:00 2001 From: Peter Hutterer <peter.hutterer@who-t.net> Date: Mon, 4 Aug 2008 17:08:36 +0930 Subject: [PATCH] xfree86: force SwitchCoreKeyboard for evdev devices (updated). If an evdev keyboard device is added through the HAL mechanism, force a SwitchCoreKeyboard to load the evdev map into the VCK. This way, by the time a client starts the evdev keymap is already there, leading to less pain lateron. Works if: - all keyboards are hotplugged through HAL, and/or - the xorg.conf keyboard uses the kbd driver. Has no effect (i.e. busted keymaps) if: - an evdev keyboard device has been specified in the xorg.conf. - we don't have a device at startup and plug a device in after starting the desktop environment. - if the device we use isn't the first one reported by HAL. If HAL isn't set up, this patch is a noop. --- hw/xfree86/common/xf86Xinput.c | 31 +++++++++++++++++++++++++++++++ 1 files changed, 31 insertions(+), 0 deletions(-) diff --git a/hw/xfree86/common/xf86Xinput.c b/hw/xfree86/common/xf86Xinput.c index 710e787..dacc3dc 100644 --- a/hw/xfree86/common/xf86Xinput.c +++ b/hw/xfree86/common/xf86Xinput.c @@ -423,6 +423,37 @@ NewInputDeviceRequest (InputOption *options, DeviceIntPtr *pdev) (!is_auto || xf86Info.autoEnableDevices)) EnableDevice(dev); + /* XXX: The VCK always starts with built-in defaults for keymap. These + * defaults are different to the evdev ones. When the first key is hit on + * an extension device, the keymap is copied into the VCK's and any + * changes made at runtime to the VCK map are lost. + * + * Assumption: if we have at least one evdev keyboard device, we can + * ignore kbd devices. Force a SwitchCoreKeyboard so the VCK has the same + * keymap as we do. + * + * Next time we hit a key, we don't change the map over anymore (see + * SwitchCoreKeyboard), and live happily ever after. + * Until we have 2 physical keyboards. Or the first real keyboard isn't + * actually the one we use. Oh well. + * + */ + if (dev->key) + { + InputInfoPtr info; + + /* Search if there is one other keyboard that uses evdev. */ + for (info = xf86InputDevs; info; info = info->next) + { + if (info != pInfo && info->dev && info->dev->key && + (strcmp(info->drv->driverName, "evdev") == 0)) + break; + } + + if (!info) + SwitchCoreKeyboard(dev); + } + *pdev = dev; return Success;
Fixed with 9c5dd7337fa93fb1650cc017e523b939dcbf482a: Let the DDX decide on the XkbRulesDefaults.
Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.