If you want to bind just a few sequences of the form Super+x, Super+c, Super+v to other sequences like Ctrl+x, Ctrl+c, Ctrl+v, for example so that (as the OP desired) these particular Super-key sequences will generally map to cut & paste without affecting any other uses of the Super key on your system, it is possible using just the XKB extension. The procedure below outlines the steps and gives two different examples of the details for two different starting keyboard setups; hopefully that will provide enough information to adapt to your system. It assumes you are comfortable with creating and editing files on your system, including ones in system locations like /usr/share/X11/xkb
.
Decide where you want your XKB configuration tree to reside. First find the system one. It is typically in /usr/share/X11/xkb, and I am not quite certain how to find it if it is not there; you could just search your system for directories named "xkb". Anyhow, once you have found it, you can either modify the system one in place, or you can use any directory of your choice. The advantage to using the system directory is that you can much more easily invoke your changes, but the drawback is that future system updates might overwrite your changes (you have been warned). In any case, all filenames mentioned hereafter are relative to this directory, which I will refer to when needed as $XKBLOCAL$, and all commands assume that's your current directory.
Determine what XKB "type" of key the current x,c,v keys are. The easiest way to do this is via the command xkbcomp -a $DISPLAY - | grep -C 6 c,
(note the comma is intentionally included in the pattern). In my first example setup, this produces:
key <AB02> {
type= "ALPHABETIC",
symbols[Group1]= [ x, X ]
};
key <AB03> {
type= "ALPHABETIC",
symbols[Group1]= [ c, C ]
};
key <AB04> {
type= "ALPHABETIC",
symbols[Group1]= [ v, V ]
};
key <AB05> {
whereas in my other example setup this produces
key <AB02> {
type= "FOUR_LEVEL",
symbols[Group1]= [ x, X, approxeq, dead_ogonek ]
};
key <AB03> {
type= "FOUR_LEVEL",
symbols[Group1]= [ c, C, ccedilla, Ccedilla ]
};
key <AB04> {
type= "FOUR_LEVEL",
symbols[Group1]= [ v, V, squareroot, U25CA ]
};
key <AB05> {
The upshot is that in the first example, the relevant keys are of type "ALPHABETIC" while in the second example they are of type "FOUR_LEVEL". Depending on your keyboard setup, you may find that they are of some other type altogether. In what follows, the type will be referred to as $TYPE$, which you must replace with the actual string ALPHABETIC or whatever in the commands below.
Find the definition of $TYPE$ and copy it to a new file in the $XKBLOCAL$/types directory. Here's a command that does just that: xkbcomp -a $DISPLAY - | grep -z -o 'type "$TYPE$" {[^}]*};' > types/cutpaste
. The name of the file "cutpaste" that I chose is arbitrary, use whatever name you like, but note you will have to refer to this file consistently in later steps. In the first setup, this file gets the contents
type "ALPHABETIC" {
modifiers= Shift+Lock;
map[Shift]= Level2;
map[Lock]= Level2;
level_name[Level1]= "Base";
level_name[Level2]= "Caps";
};
and in the other example it gets the contents
type "FOUR_LEVEL" {
modifiers= Shift+LevelThree;
map[Shift]= Level2;
map[LevelThree]= Level3;
map[Shift+LevelThree]= Level4;
level_name[Level1]= "Base";
level_name[Level2]= "Shift";
level_name[Level3]= "Alt Base";
level_name[Level4]= "Shift Alt";
};
Edit the file types/cutpaste to do two things: add a preamble and postamble that makes it a proper XKB clause, and alter the type name and the type definition to add one more level produced by the modifier corresponding to Super. You should check what that modifier is on your system, it is likely Mod4 as used below. The necessary modifications should be evident from the two example final versions of types/cutpaste, namely:
default partial xkb_types "addsuper" {
type "ALPHABETIC_SUPER" {
modifiers= Shift+Lock+Mod4;
map[Shift]= Level2;
map[Lock]= Level2;
map[Mod4]= Level3;
map[Shift+Mod4]= Level3;
map[Lock+Mod4]= Level3;
level_name[Level1]= "Base";
level_name[Level2]= "Caps";
level_name[Level3]= "With Super";
};
};
and
default partial xkb_types "addsuper" {
type "FOUR_LEVEL_SUPER" {
modifiers= Shift+LevelThree+Mod4;
map[Shift]= Level2;
map[LevelThree]= Level3;
map[Shift+LevelThree]= Level4;
map[Mod4]= Level5;
map[Shift+Mod4] = Level5;
map[LevelThree+Mod4] = Level5;
map[Shift+LevelThree+Mod4] = Level5;
level_name[Level1]= "Base";
level_name[Level2]= "Shift";
level_name[Level3]= "Alt Base";
level_name[Level4]= "Shift Alt";
level_name[Level5]= "With Super"';
};
};
Copy the key symbol definitions which were output by grep in the second step into a second new file symbols/cutpaste, and add similar preamble and postamble, and modify the definitions to use the new types and add actions to the definition to handle the desired key produced by the Super versions. The results of this in our two examples are:
default partial xkb_symbols "superversions" {
replace key <AB02> {
type[Group1]= "ALPHABETIC_SUPER",
symbols[Group1]= [ x, X, NoSymbol ],
actions[Group1]= [ NoAction(), NoAction(), RedirectKey(key=<LatX>,mods=Control,clearmods=Super)]
};
replace key <AB03> {
type[Group1]= "ALPHABETIC_SUPER",
symbols[Group1]= [ c, C, NoSymbol ],
actions[Group1]= [ NoAction(), NoAction(), RedirectKey(key=<LatC>,mods=Control,clearmods=Super)]
};
replace key <AB04> {
type[Group1]= "ALPHABETIC_SUPER",
symbols[Group1]= [ v, V, NoSymbol ],
actions[Group1]= [ NoAction(), NoAction(), RedirectKey(key=<LatV>,mods=Control,clearmods=Super)]
};
};
and
default partial xkb_symbols "superversions" {
replace key <AB02> {
type[Group1]= "FOUR_LEVEL_SUPER",
symbols[Group1]= [x,X,approxeq,dead_ogonek,NoSymbol],
actions[Group1]= [NoAction(),NoAction(),NoAction(),NoAction(),RedirectKey(key=<LatX>,mods=Control,clearmods=Super)]
};
replace key <AB03> {
type[Group1]= "FOUR_LEVEL_SUPER",
symbols[Group1]= [c,C,ccedilla,Ccedilla,NoSymbol],
actions[Group1]= [NoAction(),NoAction(),NoAction(),NoAction(),RedirectKey(key=<LatC>,mods=Control,clearmods=Super)]
};
replace key <AB04> {
type[Group1]= "FOUR_LEVEL_SUPER",
symbols[Group1]= [v,V,squareroot,U25CA,NoSymbol],
actions[Group1]= [NoAction(),NoAction(),NoAction(),NoAction(),RedirectKey(key=<LatV>,mods=Control,clearmods=Super)]
};
};
Note that in the second example I squeezed out some of the (non-significant) whitespace as well to keep the line length under a little bit of control.
Find the name of the rules set that XKB is currently using. That's easy, it's shown in the result of setxkbmap -query
. In my case, it was "evdev".
Copy the system version of rules/evdev (or whatever the name of your rules set is) to $XKBLOCAL$/rules/evdev and add rules pointing to the options we have created. You have two choices here: you can copy all of
evdev or just the portions mentioning the keyboard model, layout, variant, and option(s) that you are actually using. Of course, if you are modifying the system files in place, you don't need to do any copying, just editing.
In this case, what gets added is identical regardless of the initial keyboard setup, so there's just one example. You find the section of the rules file that starts with ! option = symbols
and add a line cutpaste:super = +cutpaste
to that section, and you also find the section of the rules file that starts with ! option = types
and a line cutpaste:super = +cutpaste
to that section as well.
Copy the system version of evdev.lst and add a line for your new option. Note that the name of this file simply corresponds to the name of the rules file with .lst appended. As in the previous step, you can either copy the whole file or just the portion referenced by the model, layout, variant, and option(s) you are using. You just need to find the section of this file that starts with ! option
and add a line like this: cutpaste:super Add super equivalents of cut and paste operations
to that section.
OK, now all the configuration files are in place. If you modified the system files, you can now invoke your new option with setxkbmap -option cutpaste:super
. On the other hand, if you did not, you have to let setxkbmap know where your $XKBLOCAL$ directory is. What's worse, the server doesn't know where that directory is, either, and setxkbmap doesn't (or perhaps can't, since ultimately the server might be running on another machine) tell it. So you have to pipe the output of setxkbmap to xkbcomp, and also tell that command where your $XKBLOCAL directory is. The full command line is therefore setxkbmap -I$XKBLOCAL$ -option cutpaste:super -print | xkbcomp -I$XKBLOCAL - $DISPLAY
.
Hopefully this is of help/interest to someone, as good definitive XKB documentation/reference is scarce. One very helpful reference was http://madduck.net/docs/extending-xkb/.