HomeWritingDifferentiating Left And Right Modifiers

More useful macOS modifier keys 🎹

Published 16 Nov '24

MacOS power users know the value of keyboard shortcuts, but here's something most people don't realize: those matching modifier keys on either side of your keyboard don't have to do the same thing. Mind-blowing, right? 🀯

While tools like Hammerspoon traditionally treat left and right modifiers as identical (how rudeee!), I wrote an extension that recognizes them as distinct keys.

Want left option+s to search files but have right option+s to launch Spotify? Now you can! Here's how it works.

Setting up your shortcuts

When you write code like this:

-- `ralt` stands for right alt
-- `alt` is Windows lingo that means `option` key
hotkeyextension.bind({'ralt'}, 's', function()
    hs.application.launchOrFocus('Spotify')
end)
 
hotkeyextension.bind({'ralt', 'rcmd'}, 'm', function()
    hs.audiodevice.defaultInputDevice():setMuted(true)
end)

The module creates a lookup table:

{
  "ralt.s" β†’ function that opens Spotify
  "ralt.rcmd.m" β†’ function that mutes the mic
}

Watching the keypresses

When you press multiple keys together, macOS doesn't send us a neat list of which keys are pressed - instead, it uses a single number to represent all pressed modifier keys. Let's break down how this works.

Each modifier key has its own bit position.

0000 0001 = left  control
0000 0010 = left  shift
0000 0100 = right shift
0000 1000 = left  command
0001 0000 = right command
0010 0000 = left  option
0100 0000 = right option

So when you press right commandright optionm, macOS gives us 80 and m (simplified example):

0001 0000  // right command (for reference)
0100 0000  // right option (AKA right alt)
---------
0101 0000  // what macOS gives us (80 in decimal)
 ^ ^
 | |
 | right command is pressed
 right option is pressed

We decode this number, figure out which modifiers are pressed, and combine it with the actual key that was pressed (in this case m) to create a lookup key ralt.rcmd.m. Then we check our lookup table from the previous step - if there's a matching function, we run it ✨

Other cool stuff

While launching apps with modifier keys is already neat, the module has more tricks up its sleeve:

Key release actions

Think of these like "peek" actions - press to show something, release to hide it. Perfect for:

Key repeat features

You know how holding down a letter key types "aaaaa"? This works the same way for your shortcuts. Hold down your shortcut to:

Flexible modifier binding

Sometimes you want a shortcut to work from either side of the keyboard (we don't discriminate here). Instead of manually binding to both left option and right option, you can just use option. The module handles the rest, like a diplomatic keyboard mediator.

Getting started

  1. Install Hammerspoon if you haven't already.
  2. Add the hotkeyextension.lua to your Hammerspoon config.
  3. Start binding functions - go nuts with dem shortcuts!

Here's how I like to organize my shortcuts: I use right Option (ralt) as my app launcher modifier, with mnemonics making them easy to remember:

Not sure where to start? Check out my app manager config - it might give you some ideas for your own setup!

If you run into any issues or just want to share your cool shortcuts, find me on Twitter or GitHub. Always excited to help out and see what others create!

Happy hammerspooning! πŸ₯„