Binding Super+C Super+V to Copy and Paste

Binding Super to Ctrl

What about binding your left Windows/Logo/Super key to act as another Ctrl key?

You can achieve that with the following xmodmap commands:

remove mod4 = Super_L
keysym Super_L = Control_L
add Control = Control_L

Assuming you saved the above lines as super_as_ctrl.xmodmap you can test out the effect by executing

xmodmap super_as_ctrl.xmodmap

To make the change permanent (surviving re-login/reboot) rename the file to .Xmodmap in your home folder.

(The above was tested on Ubuntu 11.10 live system, but it should be the same for other Linux distributions)


Adjusting Copy/Paste shortcuts for your terminal program

Having bound Super to Ctrl you can now use Super-C to copy almost everywhere. The only common exception is your terminal program. However you can redefine the shortcuts there.

I found out that even gnome-terminal has this option by now (I did not have until I got used to Ctrl-Shift-C anyway). In case you use that one, go to Edit / Keyboard Shortcuts... in the menu and assign Ctrl-C to copy and Ctrl-V to paste. Should be similar for konsole etc.

And don't worry, you won't loose the ability to terminate a program using a shortcut. After rebinding the copy shortcut for the terminal, you can just use Ctrl-Shift-C like you used Ctrl-C before. The terminal does not distinguish here if Shift is pressed or not. And the shortcut is not caught anymore for the copy. Alternatively rebind the terminate to another shortcut, as MountainX suggests in his answer.


XF86Copy etc. do not work

Concerning the key symbols for copy and paste: Apparently they have no effect. I tested it quickly by assigning the copy action to Shift-ScrollLock (it was unused and I wanted to test with a non modifier key):

xmodmap -e 'keycode 78 = Scroll_Lock XF86Copy Scroll_Lock'

Pressing it had no effect, neither with XF86AudioMute. However it did work when assigning the letter 'a'. So I guess there is a specific problem with these XF86 special key symbols.


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.

  1. 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.

  2. 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.

  3. 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";
    };
    
  4. 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"';
       };
    };
    
  5. 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.

  6. 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".

  7. 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.

  8. 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.

  9. 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/.


Here's what I do. It is not the ultimate solution, but I tried to achieve the ultimate solution and couldn't get there after much effort. So I settled for something that is simple and that works for more than 90% of what I need. I can implement it on any computer I go to (or any new Linux install) in a matter of minutes. It's dead simple.

In the X terminal application, set the shortcut preferences. I have done this in both Gnome and KDE. In Konsole, for example, go to Menu > Settings > Configure Shortcuts. There is a similar menu in Gnome X terminal. Just select the shortcut (e.g., "copy") and enter the desired key sequence.

In case the terminal copy & paste shortcuts conflict with terminal commands, there's an easy fix for that too. For example, what if someone wants to use CTRL-C for copy (so the X terminal conforms to the CUA standard)?

In that case, you can change the stty key bindings easily (in .bashrc). Continuing the CTRL-C for copy example, say you want the interrupt key to now be CTRL-b (for "break"). This accomplishes that:

echo "stty intr \^b" >> ~/.bashrc 

Then source .bashrc.

The whole solution is as simple as using the X terminals settings to change shortcuts and then, optionally, resolving conflicts with stty with a one-line echo command. Dead simple and covers almost everything I need.


Update 02/03/2020

Kinto - Type in Linux like it's a Mac.

I think this latest update better addresses the issue the original author was trying to tackle, even though it is binding Super to Ctrl+Shift for terminals.

Kinto has now been rewritten in C for Ubuntu/Debian systems using x11. It also uses json config files, making it easier to manage and extend to other applications than just terminals. The app no longer maps to Super in the Terminal apps, it will now properly map to Ctrl+Shift to create the exact same feel as having a Cmd key.

Please checkout the latest release. https://github.com/rbreaves/kinto

The main change to allow for the Super = Ctrl+Shift change is in this symbols file.

default partial xkb_symbols "mac_levelssym" {
    key <LWIN> {
      repeat= no,
      type= "ONE_LEVEL",
      symbols[Group1]= [ Hyper_L ],
      actions[group1]=[ SetMods(modifiers=Shift+Control) ]
    };
    key <RWIN> {
      repeat= no,
      type= "ONE_LEVEL",
      symbols[Group1]= [ Hyper_R ],
      actions[group1]=[ SetMods(modifiers=Shift+Control) ]
    };
};

I've taken some of what Glen Whitney had said and managed to use that knowledge to map word-worse or text manipulation behavior from macOS into a custom keymap.

I already solved the the Ctrl vs Super copy and paste issue without involving that specific solution, but like I said it was very helpful for other things. I've also avoided things like xmodmap as I am aiming to fully support Wayland at some point. Kinto uses the native xkb and it respects the expected macOS like terminal behavior.

https://github.com/rbreaves/kinto

https://medium.com/@benreaves/kinto-a-mac-inspired-keyboard-mapping-for-linux-58f731817c0

Here's a Gist as well, if you just want to see what is at the heart of it all, it will not alternate your keymap when needed though. The Gist also does not include custom xkb keymap files that setup macOS style cursors/word-wise manipulations that use Cmd and the arrow keys.

https://gist.github.com/rbreaves/f4cf8a991eaeea893999964f5e83eebb

gist content

# permanent apple keyboard keyswap
echo "options hid_apple swap_opt_cmd=1" | sudo tee -a /etc/modprobe.d/hid_apple.conf
update-initramfs -u -k all

# Temporary & instant apple keyboard keyswap
echo '1' | sudo tee -a /sys/module/hid_apple/parameters/swap_opt_cmd

# Windows and Mac keyboards - GUI (Physical Alt is Ctrl, Physical Super is Alt, Physical Ctrl is Super)
setxkbmap -option;setxkbmap -option altwin:ctrl_alt_win

# Windows and Mac keyboards - Terminal Apps (Physical Alt is Super, Physical Super is Alt, Physical Ctrl is Ctrl)
setxkbmap -option;setxkbmap -option altwin:swap_alt_win

# If the hid_apple driver is not loaded for Apple keyboards, which can be found out
# by the lsmod command then the above setxkbmap commands will not work
# Use the following commands for Apple style keyboards without an hid_apple driver
#
# Note: this could also apply to hid_apple driver as well 
# if this option is set to 0 inside swap_opt_cmd
#
lsmod | grep hid_apple

# Apple keyboard without hid_apple - GUI
setxkbmap -option;setxkbmap -option ctrl:swap_lwin_lctl,ctrl:swap_rwin_rctl

# Apple keyboard without hid_apple - Terminal
setxkbmap -option;setxkbmap -option altwin:alt_super_win

#
# If you want a systemd service and bash script to help toggle between
# GUI and Terminal applications then look at project Kinto.
# https://github.com/rbreaves/kinto
#
# Note: The above may not work for Chromebooks running Linux, please look
# at project Kinto for that.
#
# If anyone would like to contribute to the project then please do!
#