- Change the behaviour of Ctrl+Left to do Home (instead of previous word), systemwide or at least for all X programs: not possible.
- Change Alt+Left to do Ctrl+Left systemwide: not possible.
Possible and not too difficult with XKB, the standard X11 keyboard layout mechanism. You just need an apropriate key "type", and a "Redirect action"
As it's not too difficult, you can probably show us how to do that?
- Change the behaviour of Fn+Left to do Home: not possible either (the Fn key could be the left Windows key or CapsLock for example).
Something like this already part of the Neo 2 and AdNW layout that ship with the standard layouts (just that Home is on Fn+A, and Fn is called ISO_Level5_Shift). It would work more robustly with a Redirect action in additon.
Can show us how to do that?
For Redirect actions and types, see an example in the following post:
https://geekhack.org/index.php?topic=53137.msg1184091#msg1184091
For a "Fn" key, see the neo layout in symbols/de of your local xkeyboard-config installation. For combining this with Redirect actions for better robustness, see the modified xkeyboard-config here:
http://adnw.de/uploads/Main/Downloads/AdNW-xkc.tar.gz
Here, have a look at the file compat/misc for definitions of keysyms that do a redirection, and at symbols/de and symbols/adnw for their use.
The main problem is that XRecord/XTest won't let you remove key events from the queue.
I agree, and I handle this in the same way as you do. There might be an alternative to XRecord, described here:
http://lists.freedesktop.org/archives/xorg/2010-September/051098.html
But it is complicated and unproven.
- Change Shift so a single press on Shift does "persistent Shift", like on a mobile phone, to capitalize only the next letter: GTFO.
It's called "Latch" in XKB. Simple.
Can you tell me how to activate it?
There is a keysym called 'ISO_Level2_Latch'. You map it like you would map a shift key. In xmodmap syntax:
keycode 62 = ISO_Level2_Latch
add shift = ISO_Level2_Latch
(Note I cannot test this, as my xkeyboard-config is too much customized to make this meaningful). You can also latch modifiers other than shift, even multiple modifiers at the same time. There are predefined ISO_Level3_Latch and ISO_Level5_Latch keysyms, for other stuff you have go a bit deeper. To see a predefined layout using latches, see the T3 layout in symbols/de of xkeyboard-config.
- Change the behaviour of Ctrl+Left to do Home (instead of previous word), systemwide or at least for all X programs: not possible.
- Change Alt+Left to do Ctrl+Left systemwide: not possible.
Possible and not too difficult with XKB, the standard X11 keyboard layout mechanism. You just need an apropriate key "type", and a "Redirect action"
As it's not too difficult, you can probably show us how to do that?
- Change the behaviour of Fn+Left to do Home: not possible either (the Fn key could be the left Windows key or CapsLock for example).
Something like this already part of the Neo 2 and AdNW layout that ship with the standard layouts (just that Home is on Fn+A, and Fn is called ISO_Level5_Shift). It would work more robustly with a Redirect action in additon.
Can show us how to do that?
For Redirect actions and types, see an example in the following post:
https://geekhack.org/index.php?topic=53137.msg1184091#msg1184091
For a "Fn" key, see the neo layout in symbols/de of your local xkeyboard-config installation. For combining this with Redirect actions for better robustness, see the modified xkeyboard-config here:
http://adnw.de/uploads/Main/Downloads/AdNW-xkc.tar.gz
Here, have a look at the file compat/misc for definitions of keysyms that do a redirection, and at symbols/de and symbols/adnw for their use.
I have tried what you have suggested in the GeekHack post you have linked to above, and I'm running into problems.
My first step has been to remap Control+arrow to Home, End, PgUp and PgDn.
For example, Ctrl+Up is supposed to do PgUp.
In my ".xkb" file, created from my default configuration with "xkbcomp :0 my.xkb", I have found that I already have a "type" for Control, which is called "PC_CONTROL_LEVEL2".
Here it is:
type "PC_CONTROL_LEVEL2" {
modifiers= Control;
map[Control]= Level2;
level_name[Level1]= "Base";
level_name[Level2]= "Control";
};
So I just use this "type" to remap the UP key, exactly as you suggested:
key <UP> {
type="PC_CONTROL_LEVEL2",
symbols[Group1] = [ Up, NoSymbol ],
actions[Group1] = [ NoAction(), RedirectKey(key=<PGUP>,clearMods=Control) ]
};
I then feed xkbcomp with "my.xkb":
xkbcomp my.xkb :0
This worked fine in Firefox and OpenOffice. I thought it was great.
Then I discovered that the remapping did not work in some other programs. For example, it does not work in gedit.
What happens in these programs is that when I press Ctrl-Up they believe that Ctrl-PgUp has been pressed. The "clearMods" stuff is not working.
I'm using Ubuntu 12.04, but it appears to be a known problem in others versions of Ubuntu, and probably other versions of Linux:
https://bugs.freedesktop.org/show_bug.cgi?format=multiple&id=78661
Apparently, client programs are free to ignore the "clearMods" thing, which means that remapping is actually not transparent. It is somehow exposed to the client programs, which defeats the purpose of remapping and leaves open the possibility of programs not behaving according to the remapping.
The other way to remap, with:
key <UP> {
type="PC_CONTROL_LEVEL2",
symbols[Group1] = [ Up, Prior ]
};
...exhibits exactly the same problem, but in reverse. It works in gedit but does not in Firefox or OpenOffice.
This version does not work either:
key <UP> {
type="PC_CONTROL_LEVEL2",
symbols[Group1] = [ Up, Prior ],
actions[Group1] = [ NoAction(), RedirectKey(key=<PGUP>,clearMods=Control) ]
};
I have tried a few others without success: clearMods=Control+LControl+RControl, clearMods=all...
Do you have a solution for this? Did I do something wrong?
I'm actually wondering if you are yourself using (or tried) remapping the way you have described it, and if so why you are not affected by this problem.
The main problem is that XRecord/XTest won't let you remove key events from the queue.
I agree, and I handle this in the same way as you do. There might be an alternative to XRecord, described here:
http://lists.freedesktop.org/archives/xorg/2010-September/051098.html
But it is complicated and unproven.
It looks like they are doing it in a similar way as we do it: to "own" Control you are going to associate it with an unused keycode.
This will suffer from the problem I have described: this will prevent Ctrl-Alt-Backspace and Ctrl-Alt-Fx to work as they should.
- Change Shift so a single press on Shift does "persistent Shift", like on a mobile phone, to capitalize only the next letter: GTFO.
It's called "Latch" in XKB. Simple.
Can you tell me how to activate it?
There is a keysym called 'ISO_Level2_Latch'. You map it like you would map a shift key. In xmodmap syntax:
keycode 62 = ISO_Level2_Latch
add shift = ISO_Level2_Latch
(Note I cannot test this, as my xkeyboard-config is too much customized to make this meaningful). You can also latch modifiers other than shift, even multiple modifiers at the same time. There are predefined ISO_Level3_Latch and ISO_Level5_Latch keysyms, for other stuff you have go a bit deeper. To see a predefined layout using latches, see the T3 layout in symbols/de of xkeyboard-config.
Thank you, this works.
One pure XKB thing one might try out is:
key <UP> {
type="PC_CONTROL_LEVEL2",
symbols[Group1] = [ Up, NoSymbol ],
actions[Group1] = [ NoAction(), RedirectKey(key=<FK13>,clearMods=Control) ]
};
key <FK13> {
type="PC_CONTROL_LEVEL2",
symbols[Group1] = [ Prior, Prior ]
};
using key FK13, assuming you do not need it otherwise. You could also use PGUP instead, if you never want to enter Control+Prior and have it treated different from Prior alone.
The idea is that applications that do not use the XInput extensions get the Control cleared by the RedirectKey, and applications that do use XInput handle consumed modifiers properly. GTK applications tend to be quite good in this respect, in my experience.
Of course, even if this works, setting a modifier rather than clearing one cannot be done in a similar manner.
One pure XKB thing one might try out is:
key <UP> {
type="PC_CONTROL_LEVEL2",
symbols[Group1] = [ Up, NoSymbol ],
actions[Group1] = [ NoAction(), RedirectKey(key=<FK13>,clearMods=Control) ]
};
key <FK13> {
type="PC_CONTROL_LEVEL2",
symbols[Group1] = [ Prior, Prior ]
};
using key FK13, assuming you do not need it otherwise. You could also use PGUP instead, if you never want to enter Control+Prior and have it treated different from Prior alone.
The idea is that applications that do not use the XInput extensions get the Control cleared by the RedirectKey, and applications that do use XInput handle consumed modifiers properly. GTK applications tend to be quite good in this respect, in my experience.
Of course, even if this works, setting a modifier rather than clearing one cannot be done in a similar manner.
Well... I works!!!
At first it didn't, because I have tried using FK20 instead of FK13.
It turns out that, on my system at least, you can remap FK13 to FK24 except FK20 to FK23. :mad:
It took me a while to figure this out, but now it works.
Thank you for the trick, it's a nice workaround for the Xserver bug. :)
So what I understand from this is that bouncing to another key using RedirectKey allows the clearMods to work.
Now I'm trying to remap keys in combination with Alt, and I'm hitting a wall again.
I'm doing this:
key <UP> {
type="PC_ALT_LEVEL2",
symbols = [ Up, NoSymbol ],
actions = [ NoAction(), NoAction() ]
};
PC_ALT_LEVEL2 is predefined as:
type "PC_ALT_LEVEL2" {
modifiers= Alt;
map[Alt]= Level2;
level_name[Level1]= "Base";
level_name[Level2]= "Alt";
};
Now when I hit the UP key, it generates Alt+UP, always. I don't understant why.
What is happening is that I just press the UP key, without any modifier, and I receive Alt-UP. It does not make any sense to me.
That is strange, indeed. Maybe it can be understood like this: The key type consumes the Alt modifier, that is, the Alt modifier must not be considered in determining the key's function, other than determining the level. So the application determines the level, and finds an Up keysym there. It has one function bound to Up alone, and another one bound to Alt+Up. But it must not consider the the Alt modifier anymore; so it cannot decide whether the to match to Up or to Alt+Up, and decides the conflict in a quasi-random fashion. If it works like this, with the Control stuff, we just were lucky.
Now that we apparently cannot get rid of the Alt modifier, me can try to prevent it getting set in the first place. We can do so by making Alt a key with two levels switched by Control, with the first level a plain Alt and the second level a level three shift:
key <LALT> {
type= "PC_CONTROL_LEVEL2",
repeat= No,
symbols[Group1]= [ Alt_L, Meta_L ],
actions[Group1]= [ SetMods(modifiers=Mod1), SetMods(modifiers=Mod5) ]
};
(you probably can use LevelThree instead of Mod5 and Alt instead of Mod1. I prefer real modifiers for simplicity). We introduce a new key type to select levels based on Control and the modifier for level three:
type "CONTROL_LEVEL3" {
modifiers= Control+Mod5;
map[Control]= Level2;
preserve[Control]= Control;
map[Mod5]= Level3;
map[Control+Mod5]= Level4;
preserve[Control+Mod5]= Control;
level_name[Level1]= "Base";
level_name[Level2]= "Control";
level_name[Level3]= "Level three";
level_name[Level2]= "Control+Level three";
};
and then we use it:
key <UP> {
type="CONTROL_LEVEL3",
symbols = [ Up, Up, Up, Prior ]
};
You might have to add redirect actions to UP for robustness, but you can just redirect to one level keys, and you should not need any clearMods.
And, of course, you must press Control before Alt. The other way round still gives you Control+Alt modifiers.
What is happening is that I just press the UP key, without any modifier, and I receive Alt-UP. It does not make any sense to me.
That is strange, indeed. Maybe it can be understood like this: The key type consumes the Alt modifier, that is, the Alt modifier must not be considered in determining the key's function, other than determining the level. So the application determines the level, and finds an Up keysym there. It has one function bound to Up alone, and another one bound to Alt+Up. But it must not consider the the Alt modifier anymore; so it cannot decide whether the to match to Up or to Alt+Up, and decides the conflict in a quasi-random fashion. If it works like this, with the Control stuff, we just were lucky.
Now that we apparently cannot get rid of the Alt modifier, me can try to prevent it getting set in the first place. We can do so by making Alt a key with two levels switched by Control, with the first level a plain Alt and the second level a level three shift:
key <LALT> {
type= "PC_CONTROL_LEVEL2",
repeat= No,
symbols[Group1]= [ Alt_L, Meta_L ],
actions[Group1]= [ SetMods(modifiers=Mod1), SetMods(modifiers=Mod5) ]
};
(you probably can use LevelThree instead of Mod5 and Alt instead of Mod1. I prefer real modifiers for simplicity). We introduce a new key type to select levels based on Control and the modifier for level three:
type "CONTROL_LEVEL3" {
modifiers= Control+Mod5;
map[Control]= Level2;
preserve[Control]= Control;
map[Mod5]= Level3;
map[Control+Mod5]= Level4;
preserve[Control+Mod5]= Control;
level_name[Level1]= "Base";
level_name[Level2]= "Control";
level_name[Level3]= "Level three";
level_name[Level2]= "Control+Level three";
};
and then we use it:
key <UP> {
type="CONTROL_LEVEL3",
symbols = [ Up, Up, Up, Prior ]
};
You might have to add redirect actions to UP for robustness, but you can just redirect to one level keys, and you should not need any clearMods.
And, of course, you must press Control before Alt. The other way round still gives you Control+Alt modifiers.
Thank you for sharing this.
I cannot test it at this time, as my Ubuntu 12.04 linux box is currently working on video conversion (and it's going to take ages).
I'm going to save this for later.
Honestly, I may actually end up giving up on remapping Ctrl-arrow for Home/End/PgUp/PgDn and Alt-arrow to previous/next word.
It's probably simpler to remap Super-arrow to Home/End/PgUp/PgDn and leave Ctrl and Alt alone. This would turn Super into a kind of Fn key similar to what we find today on some keyboards (my FC660C and FC660M can have the Fn key in place of the left Super for example). It's not important to lose the primary function of Super-arrow in Ubuntu, as I have already disabled it anyway (I think it allowed to select another virtual desktop).
I should be able to do that either with xkbcomp (preferred method if it works) or with the daemon I have already written: as long as I don't try to remap Ctrl and Alt with my daemon, I don't lose some of the functionality of the X server, like access to the virtual consoles and terminate server. So using Super should certainly be made to work.
I can easily configure my Macs to work similarly. Actually I have already written the script in Karabiner, I just have to enable this feature so my linux boxes and my Macs will react (almost) the same way to keyboard input.
Then I'll have to adapt to this, which may be less difficult than trying to work around all the problems with remapping Ctrl and Alt.
Thank you anyway for your continued support. This forum needs someone like you, someone with a deep knowledge of the linux keyboard system.