If you came to Linux from Mac and found the default keyboard shortcuts less than ideal, then this article is for you. It’s actually quite easy to get a keyboard setup that is like Mac, maybe even better!
PC vs. Mac Keyboards
While some large keyboards may have an extra key, most laptop keyboards and common external keyboards have the following layout on the bottom row of keys:
PC: Ctrl FN Super Alt [SPACE] Alt Ctrl Mac: Ctrl FN Opt Cmd [SPACE] Cmd Opt
My biggest complaint with the PC layout is that the Ctrl key is the most used modifier and it is not in the same position on both sides of the spacebar, nor is it the closest key to the spacebar. Remapping keys like this is far better in my opinion.
Ideal: Super FN Alt Ctrl [SPACE] Ctrl Alt
Create a System-wide Keyboard Map
It’s super easy to remap your keyboard with
udev. Use a tool called
evtest to record the codes produced when you press each key on your keyboard. Jot them down along with the event number (identifier) for the keyboard. In my case the keyboard event was 4. Use the event number to get the device identifier udev will match against (note the 4 in event4):
cat /sys/class/input/event4/device/modalias input:b0011v0001p0001eAB83-e0,1,4,11,14,k71,72,73,74,75,76,77,79,7A,7B,7C,7D,7E,7F,80,8C,8E,8F,9B,9C,9D,9E,9F,A3,A4,A5,A6,AC,AD,B7,B8,B9,D9,E2,ram4,l0,1,2,sfw
Copy that first bit to identify your keyboard. Then all you have to do is create a text file to map the keys how you like them. The text below is the mapping for the keyboard on my System76 Lemur Pro (lemp10) laptop. The codes like “3a” and “1d” are the result of using
/etc/udev/hwdb.d/10-mod-keyboard-system76-lemp10.hwdb evdev:input:b0011v0001p0001* # AT Translated Set 2 keyboard" ##KEYBOARD_KEY_3a=leftctrl # capslock to l_ctrl KEYBOARD_KEY_1d=leftmeta # l_ctrl to super KEYBOARD_KEY_db=leftalt # l_super to l_alt KEYBOARD_KEY_38=leftctrl # l_alt to l_ctrl KEYBOARD_KEY_b8=rightctrl # r_alt to r_ctrl KEYBOARD_KEY_9d=rightalt # r_ctrl to r_alt
If you have external keyboards, repeat the process and create a similar file per keyboard. With those files in place, two quick commands will make the changes effective immediately:
# For systemd Linux systems (most will use this) systemd-hwdb update # For non-systemd (like Void Linux) udevadm hwdb -u udevadm trigger
Voilà! Keys mapped! What’s great about this approach is it’s system-wide, i.e., it’s not tied to GNOME or X. Your keys will be mapped no matter where you are.
Tweak Your Desktop Environment’s Shortcuts
You’ll probably want to tweak a few core keyboard shortcuts in your desktop environment to complete the Mac-like setup. The changes below are for GNOME, but should generally be the same in any DE. In GNOME, go to
Settings > Keyboard. My suggested changes are:
close window => ctrl q switch applications => ctrl tab switch windows of an application => ctrl ` move to workspace left => alt left move to workspace right => alt right move to window to workspace left => alt shift left move to window to workspace right => alt shift right show the overview => ctrl space show all apps => ctrl shift space
Kitty: A Highly Configurable Terminal
Kitty is my favorite terminal and one of the reasons why is how easy it is to configure the keyboard shortcuts. I took the approach below to have the control key act like more like the Cmd key by default, and Ctrl+Shift acts like a traditional control key. This also has the Mac convention of Cmd+. acting like Ctrl-c. The hex codes map to the control characters you get when pressing ctrl+key at a traditional terminal.
kitty_mod ctrl # Map common terminal control+key shortcuts map kitty_mod+. send_text normal,application \x03 map ctrl+shift+a send_text normal,application \x01 map ctrl+shift+b send_text normal,application \x02 map ctrl+shift+c send_text normal,application \x03 map ctrl+shift+d send_text normal,application \x04 map ctrl+shift+e send_text normal,application \x05 map ctrl+shift+f send_text normal,application \x06 map ctrl+shift+g send_text normal,application \x07 map ctrl+shift+h send_text normal,application \x08 map ctrl+shift+i send_text normal,application \x09 map ctrl+shift+j send_text normal,application \x0A map ctrl+shift+k send_text normal,application \x0B map ctrl+shift+l send_text normal,application \x0C map ctrl+shift+m send_text normal,application \x0D map ctrl+shift+n send_text normal,application \x0E map ctrl+shift+o send_text normal,application \x0F map ctrl+shift+p send_text normal,application \x10 map ctrl+shift+q send_text normal,application \x11 map ctrl+shift+r send_text normal,application \x12 map ctrl+shift+s send_text normal,application \x13 map ctrl+shift+t send_text normal,application \x14 map ctrl+shift+u send_text normal,application \x15 map ctrl+shift+v send_text normal,application \x16 map ctrl+shift+w send_text normal,application \x17 map ctrl+shift+x send_text normal,application \x18 map ctrl+shift+y send_text normal,application \x19 map ctrl+shift+z send_text normal,application \x1A # Assign no_op to control+key sequences to pass through map kitty_mod+space no_op map kitty_mod+a no_op map kitty_mod+e no_op