Skip to content

Instantly share code, notes, and snippets.

@toroidal-code
Last active December 31, 2023 19:32
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save toroidal-code/ec075dd05a23a8fb8af0 to your computer and use it in GitHub Desktop.
Save toroidal-code/ec075dd05a23a8fb8af0 to your computer and use it in GitHub Desktop.
Have you a Hyper for Great Good

Have you Hyper for Great Good

So. You have become an Emacs wizard. And you find yourself aching for the simplicity that another modifier key would introduce into your life. Ah, the things you could do with Hyper.

Or maybe, you just want Hyper for another reason.

... Except everywhere you look, everyone's talking about .xmodmaps and xkbcomp, but you're using one of those fancy desktop managers. (Aka, not awesome, dwm, xmonad or something even more hipster) And because of that, you're lost in the sea of confusion that is trying to customize your keyboard mapping.

Gnome, Cinnamon, and KDE all use xkb.

You need gnome-tweak-tool to access all of the xkb options on Gnome.

On Cinnamon they're under Settings > Keboard > Keyboard layouts > Options.

KDE has them under Settings > Keyboard > Advanced.

That's great and all, but the only real option available is to make both of your Windows (or whatever logo is on them) keys Hyper. And you want to make it so that only the key of your choice on the right (those ones you never touch) is your new fancy Hyper.

Usually, this requires wading through a bunch of config files and reading through terrible documentation of the xkb system and strange xev outputs.

But instead of that, all you're going to need for this are root access, a handy text editor, and your mouse. Sounds simple? Because it actually is.

Alright. Let's do this.

I'm working on Arch Linux, so all of my xkb files are under /usr/share/X11/xkb. You may need to consult your distro's documentation, but it'll probably be somewhere around there.

Now, open your text editor with sudo or some other way of granting root access. So sudo + emacs or vim or subl3 or atom or nano or zile or dex or vi or... well, you get the idea.

The first file we're going to be working with is an addition, under symbols in that xkb folder. It should already have a bunch of stuff like us and dvp and stuff. We're going to be adding a file called hyper. So on my computer, this is /usr/share/X11/xkb/symbols/hyper.

The contents of hyper will be this:

partial modifier_keys
xkb_symbols "ralt" {
    key <RALT> { [ Hyper_R ] };
    modifier_map Mod3 { <HYPR>, Hyper_R };
};

partial modifier_keys
xkb_symbols "rwin" {
    key <RWIN> { [ Hyper_R ] };
    modifier_map Mod3 { <HYPR>, Hyper_R };
};

partial modifier_keys
xkb_symbols "rctl" {
    key <RCTL> { [ Hyper_R ] };
    modifier_map Mod3 { <HYPR>, Hyper_R };
};

Now, all the other files we're working with will be up a level in rules. So, again, for me, that's /usr/share/X11/xkb/rules/.

The first file to change is evdev. In evdev, all the way at the bottom, right below the line with lv5:rwin_switch_lock_cancel and above the section that starts with ! option = compat we're going to add three things to match the symbols we just introduced.

hyper:ralt = +hyper(ralt)
hyper:rwin = +hyper(rwin)
hyper:rctl = +hyper(rctl)

Good? So you should get something like this for the general area:

  lv5:lsgt_switch_lock_cancel     =       +level5(lsgt_switch_lock_cancel)
  lv5:ralt_switch_lock_cancel     =       +level5(ralt_switch_lock_cancel)
  lv5:lwin_switch_lock_cancel     =       +level5(lwin_switch_lock_cancel)
  lv5:rwin_switch_lock_cancel     =       +level5(rwin_switch_lock_cancel)
  hyper:ralt = +hyper(ralt)
  hyper:rwin = +hyper(rwin)
  hyper:rctl = +hyper(rctl)



! option        =       compat
  grp_led:num           =       +lednum(group_lock)
  grp_led:caps          =       +ledcaps(group_lock)
  grp_led:scroll        =       +ledscroll(group_lock)
  japan:kana_lock       =       +japan(kana_lock)

Great.

Now, we need to add descriptions to these things.

So open up the file evdev.lst, and aaaaalll the way at the bottom (just below the terminate:ctrl_alt_bksp, add some wording like this:

  hyper                Position of the Hyper key
  hyper:ralt           Right Alt as Hyper
  hyper:rwin           Right Windows key as Hyper
  hyper:rctl           Right Ctrl as Hyper

Be careful about those leading spaces!

So now, we have our actions, our keyword-to-internal mapping, and a description. But we still need some more things so that our fancy guis will work. So the next file to edit is evdev.xml.

Again, all the way at the bottom, between the last </optionList> and </xkbConfigRegistry> we're going to insert a new optionList node.

  <optionList>
    <group allowMultipleSelection="true">
      <configItem>
        <name>Hyper</name>
        <description>Position of the Hyper key</description>
      </configItem>
      <option>
        <configItem>
          <name>hyper:ralt</name>
          <description>Right Alt as Hyper</description>
        </configItem>
      </option>
      <option>
        <configItem>
          <name>hyper:rwin</name>
          <description>Right Windows key as Hyper</description>
        </configItem>
      </option>
      <option>
        <configItem>
          <name>hyper:rctl</name>
          <description>Right Ctrl as Hyper</description>
        </configItem>
      </option>
    </group>
  </optionList>

And that's it!

You should now be able to open up your keyboard settings of choice and enable your hyper key to be any (or all) of those options under "Position of the Hyper Key".

Happy hacking!

@tareefdev
Copy link

Hey Katherine, thanks for this great post.
I followed it literally, on Arch Linux with Gnome. Now right-Ctrl works perfectly as Heypr but right-Alt Doesn't.
What do you suggest in this case?

@tareefdev
Copy link

tareefdev commented Apr 28, 2019

I figured out the problem, now Right Alt key is mapped to both Meta_R and Hyper_R, and when pressing it with a key (says a) emacs receive H-M-a as a keybinde.
One possible solution is to re-bind my shortcut, so instead of using (H-s) I have to use (H-M-s), but still prefer to unmap Meta_R from the key

@jduhamel
Copy link

jduhamel commented May 2, 2019

tarefdev if you figure this out let us all know.

@colonelpanic8
Copy link

@tareefdev I'm having the same issue that you described. Did you figure out why this occurs for ralt, but not for rwin?

@colonelpanic8
Copy link

@tareefdev, @jduhamel

I figured it out from this answer:

https://unix.stackexchange.com/a/65607/92324

I'm not totally sure why, but this works for me:

partial modifier_keys
xkb_symbols "ralt_as_hyper" {
    replace key <RALT> { [ Hyper_L, Hyper_L ] };
	modifier_map Mod3 { <RALT>, Hyper_L };
};

@colonelpanic8
Copy link

@tareefdev, @jduhamel

I figured it out from this answer:

https://unix.stackexchange.com/a/65607/92324

I'm not totally sure why, but this works for me:

partial modifier_keys
xkb_symbols "ralt_as_hyper" {
    replace key <RALT> { [ Hyper_L, Hyper_L ] };
	modifier_map Mod3 { <RALT>, Hyper_L };
};

@LorenRiccie
Copy link

Works great on Debian with kde. Thanks

@bjohas
Copy link

bjohas commented Feb 19, 2020

Hello all, I've got a bit of an intractable problem regarding to mapping the Hyper key, as well as keymap switching. It's partially off-topic for this, but I thought one of you might be able to give some input? The issue is described here https://gitlab.freedesktop.org/xkeyboard-config/xkeyboard-config/issues/187, various notes here https://github.com/bjohas/Ubuntu-keyboard-map-like-OS-X and a more in-depth walk-through here: https://docs.google.com/document/d/1KiZN0hBhohqUWo3UXJDx-VAKvlBvJ6y_YyUp5l2nxy0/edit.
I'd really really appreciate some input, as I've been stuck on this for almost a year! There's a bounty available via upwork (or otherwise) https://www.upwork.com/ab/applicants/1230080312551604224/suggested.

@christian-schulze
Copy link

I'm running Ubuntu 21.04 with Gnome 38.8.5. I had to make an adjustment to the XML in evdev.xml to make this work.
Instead of adding a new <optionList>, I had to add the <group allowMultipleSelection="true"> to the existing <optionList>.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment