I use a German keyboard but switched to the QWERTY layout to input programming symbols more easily. I still want to be able to type German umlauts, though. My keyboard also has a alt gr key that I want to put to use. So I created the file ~/.xkb/symbols/us-custom with the following contents:

default partial alphanumeric_keys
xkb_symbols "basic" {
	// Umlauts (ä, ö, ü) and €
	include "us(de_se_fi)"

	name[Group1] = "US layout plus some Unicode symbols using altgr combinations";
	// <AC06> means: middle row, 6th key on the board from the left

	// Unicode arrows (←, ↓, ↑, →)
	key <AC06> { [ h, H, U2190 ] };
	key <AC07> { [ j, J, U2193 ] };
	key <AC08> { [ k, K, U2191 ] };
	key <AC09> { [ l, L, U2192 ] };

	// Typographic punctuation
	key <AE11> { [      minus, underscore,   endash,       emdash ] };
	key <AB09> { [     period,    greater, ellipsis               ] };
	key <AB10> { [      slash,   question, division, questiondown ] };
	key <AE08> { [          8,   asterisk,        8,     multiply ] };
	key <AC11> { [ apostrophe,   quotedbl, rightsinglequotemark   ] };

	// Quotes
	key <AB02> { [ x, X,       guillemotright,            0x100203a ] };
	key <AB03> { [ c, C,        guillemotleft,            0x1002039 ] };
	key <AB04> { [ v, V,   doublelowquotemark,   singlelowquotemark ] };
	key <AB05> { [ b, B,  leftdoublequotemark,  leftsinglequotemark ] };
	key <AB06> { [ n, N, rightdoublequotemark, rightsinglequotemark ] };
};

In line 4 I included the de_se_fi section of /usr/share/X11/xkb/symbols/us. This has the same effect as putting the following into my custom layout:

include "us(basic)"
include "eurosign(e)"

key <AC01> {[ a,          A,          adiaeresis, Adiaeresis ]};
key <AD09> {[ o,          O,          odiaeresis, Odiaeresis ]};
key <AC02> {[ s,          S,          ssharp,     U1E9E      ]};
key <AD07> {[ u,          U,          udiaeresis, Udiaeresis ]};
key <AD10> {[ p,          P,          aring,      Aring      ]};

include "level3(ralt_switch)"

Including level3(ralt_switch) allows me to access the third layer by holding down the right alt key. This is how you access the other layers:

  • 1: hold down nothing
  • 2: hold Shift
  • 4: hold Shift+alt

With the key keyword you can remap a key. In the angle brackets you specify the position of the key on the keyboard. The second letter specifies the row:

  • B: bottom row
  • C: middle row
  • D: top row
  • E: number row

The next two digits specify the position on the row starting with 01 from the left.

The next bit of syntax is self-explanatory:

{[ layer1, layer2, layer3, layer4 ]};

You can leave out layer4 to map it to nothing.

You then should be able to select your custom layout. If you use Sway, add the following to the config file.

input * xkb_layout "us-custom"

Alternatively, export the environment variable XKB_DEFAULT_LAYOUT=us-custom.

See also: XKB on ArchWiki