How to make Hyper and Super keys not do the same thing?

Solution 1:

For some reason Ubuntu currently assigns both Super and Hyper to Mod4. You can see this in /usr/share/X11/xkb/symbols/pc:

 key <SUPR> {   [ NoSymbol, Super_L ]   };
 modifier_map Mod4   { <SUPR> };

 key <HYPR> {   [ NoSymbol, Hyper_L ]   };
 modifier_map Mod4   { <HYPR> };

I was able to change this to put super and hyper on separate modifiers without needing to be root or modify any system files. I'm not sure if this is the best way as I am definitely not an xkb expert, but it's a way that has been reliable for me.

First, create a local symbols file. I have mine in ${HOME}/.config/xkb/symbols/local. This assigns Super to Mod3 and Hyper to Mod4.

default  partial modifier_keys
xkb_symbols "superhyper" {

    modifier_map Mod3 { Super_L, Super_R };

    key <SUPR> {    [ NoSymbol, Super_L ]   };
    modifier_map Mod3   { <SUPR> };

    key <HYPR> {    [ NoSymbol, Hyper_L ]   };
    modifier_map Mod4   { <HYPR> };
};

Then recompile the existing map to add a "local":

setxkbmap -print | sed -e '/xkb_symbols/s/"[[:space:]]/+local&/' | xkbcomp -I${HOME}/.config/xkb - ${DISPLAY}

Put this in a script to be run when you log in. You can run it as an ordinary user.

Solution 2:

With xmodmap you can change this behavior with 2 commands:

## Hyper_L is mod4 by default, we will "move" it to Mod3
xmodmap -e "remove mod4 = Hyper_L"
xmodmap -e "add mod3 = Hyper_L"