https://notes.alinpanaitiu.com/Keyboard%20tricks%20from%20a%20macOS%20app%20dev logo * Home * Blog * Notes * Stuff * Contact * Resume * RSS < Back to NotesPublished on April 21, 2023 Keyboard tricks from a macOS app dev This is a collection of keyboard and trackpad workflows that I accumulated over the last 7 years of using a MacBook. Here are some important abbreviations I am using in this article: Term Meaning Explanation lcmd [?] Left Command The Command key on the left side of the spacebar rcmd [?] Right The Command key on the right side of the Command spacebar lalt [?] Left Option The Option key on the left side of the spacebar ralt [?] Right Option The Option key on the right side of the spacebar hyper ^ [?] [?] A rarely used combination of modifiers # Key Sequences In 6 years of using BetterTouchTool I had no idea this feature existed. It can map any sequence of keys (even modifiers) to any action. Sequence: individual keys pressed one after the other, not key combos that you press at the same time In the below video, I map rcmd then lcmd to the macOS zoom hotkey: [?] [?] 8 Activating macOS zoom by pressing rcmd then lcmd I only have 2 key sequences at the moment: * rcmd then lcmd - Picture-in-Picture Zoom * lcmd then rcmd - Superkey Seek --------------------------------------------------------------------- Superkey is the Pro version of Hyperkey, the app that maps CapsLock to the hyper key, made by Ryan Hanson (developer of the popular window management app Rectangle). The below video is a demonstration of how I use it to quickly find and click on things that I know they're somewhere on the screen, but I would be too slow to notice-point-and-click with my eyes and trackpad. I'm pressing lcmd then rcmd, typing fip then pressing Enter which clicks on the browser tab with fipple in its title. Clicking on things by searching them with Seek You can even hold modifiers while pressing Enter to do the same action that clicking with that modifier would do. In my browser's case I can: * ^ Enter to right click the tab and show the context menu (for muting or pinning the tab, etc) * [?] Enter to close the tab without trying to click on the tiny X # Double Tap Raycast added the possibility of mapping a double tap modifier combo to summon it. I personally mapped [?] [?] and I like it because it doesn't clash with any other keys while being unique enough to remember. One thing I noticed though is that it is faster and easier to press lalt then ralt to register a double tap, instead of actually pressing one Option key twice. The reverse direction (right then left) works as well. [Raycast-00] One could also use BTT's Key Sequences to map arbitrary double or even triple taps to any action. For example here I mapped ^ ^ to BTT's GPT action and I use it to convert some ObjC code to Swift: the [?] C and [?] V in the video are synthesised by BTT, I'm not copy-pasting anything Double tapping ^ Control to summon GPT # One-key app switching When using more than 3 apps, it becomes annoying to Command Tab Tab Tab... all of the time. I'd like to switch to exactly the app I need, with a single keypress. Previously I did this by manually assigning rcmd + letter to my most used apps, using Karabiner or BTT. I finally wrote the rcmd iconrcmd app to do the assigning automatically for me, while also adding nice features like show/hide app by pressing the same letter twice, or launch app if not already running etc. Holding [?] Right Command while pressing letters to focus apps --------------------------------------------------------------------- As a bonus, I was able to implement focusing and opening specific projects, documents or windows of an app using the same method. screenshot of the window focusing section from the rcmd page I have many projects in my code editor and frequently need to switch between them. And when opening up such a project, I also need to open a terminal tab and cd to the directory of that project. For some of those I also need to open a specific Sketch or Pixelmator file which contains the graphics of the app or website. And of course, if it's a website, I also need to open the damn webpage in my browser to see how it looks while I develop it. l(|*|l) That's too much work. And way too many things to remember. And I don't always need all of them at once, I want to be able to open things selectively, so a script that does it all isn't a good choice for me So I dedicated the ralt key for opening and switching between these projects. Using [?] ralt + letters to focus windows and open projects Configuring rcmd icon rcmd to do the window focusing thingie is a bit convoluted because of the App Store sandbox limitations, but if you have many projects to switch between, it's worth it. To give you the basics on how to do this: * Install Hammerspoon and the window switching script from rcmd's Switcher menu * Manually open the project you want to assign (e.g. open a folder in VSCode) * Press ralt = (or the key before backspace) to show the assignment menu * Press K and then press the letter you want to bind to that project * Tell rcmd how it can open that window (usually you'd choose Open a file) [CleanShot-] if the ralt hotkeys don't do anything after first installing the script, you might need to restart rcmd and Hammerspoon # Fn key It always seemed weird to me how we have this Fn key which only interacts with the function row of keys, backspace and arrows and just takes up keyboard space for the rest of the time. So of course, after running out of keys to bind, I looked for ways to use that key. I know BTT and Karabiner can use it, but I prefer skhd for its simplicity. I decided to use it mostly for running scripts, and doing window management with yabai. Starting with skhd is really simple: * brew install skhd * brew services start skhd * Give it the required permissions * Start adding your hotkeys inside ~/.skhdrc Simply editing and saving the skhdrc file will hot reload the changes. Much faster than clicking around in the BTT UI. Here are some interesting hotkeys I use with skhd: # Edit skhd config fn + k : code $HOME/.skhdrc # Easy to use Sleep hotkey fn - q : pmset sleepnow # Turn on lights to warm colors fn - w : shortcuts run "Warm Blend" # Connect or disconnect Sidecar fn - s : $HOME/.local/bin/lunar toggle-connection sidecar # Search selected text on Google fn - g : skhd -k 'cmd - c'; open "https://www.google.ro/search?q=$(pbpaste)" # Upload selected file and copy URL to clipboard fn - f : skhd -k 'cmd + alt - c'; \ terminal-notifier -title "Uploading file" -message "$(pbpaste)" -ignoreDnD; \ curl --upload-file "$(pbpaste)" "https://transfer.sh/$(basename $(pbpaste))" | pbcopy; \ terminal-notifier -title "File uploaded" -message "$(pbpaste)" -ignoreDnD # --- Things that need SIP disabled --- () # Decrease window opacity (more transparent) -- "0x1B" => "minus (-)" fn - 0x1B : yabai -m window --opacity $(bc -e "$(yabai -m query --windows --window | jq -r '."opacity"') - 0.05") # Increase window opacity (less transparent) -- "0x18" => "plus (=)", fn - 0x18 : yabai -m window --opacity $(bc -e "$(yabai -m query --windows --window | jq -r '."opacity"') + 0.05") # Toggle Picture-in-Picture for the current window fn - p : yabai -m window --toggle pip # Text expansions Everyone has these snippets of text that they type often: email address, phone number, specific emojis, URLs etc. I use Raycast's Snippets feature to quickly type these things by assigning mnemonics to them. Typing mnemonics to expand Raycast Snippets I also map typos I frequently do to their correct words. Examples: * oyu -> you * improt -> import * stirng -> string Adding a snippet in Raycast is as simple as copying some text, then opening its clipboard manager and pressing [?] S. Here's how I have it configured in case you want to replicate my setup exactly: [Raycast-00] # Trackpad gestures I've been working on MacBooks exclusively for the last 6 years, and the Trackpad has always been right there at the center. It's such a good input device, with multitouch, Force Touch and great OS support. It would be a shame to neglect it. I'm using BTT to configure all kinds of gestures for it, the below video shows some of my most used ones: (contains sound) Controlling music and tabs with the Trackpad # Remembering key bindings How do you keep all this in mind?? I get that question often. And the truth is it's becoming harder and harder. I cope by dedicating modifiers to sets of actions and by always looking at the places where these key bindings are configured when I need them. Very often I forget where a hotkey was defined. # FuzzyKey About a year ago, I started writing FuzzyKey, a fuzzy search Spotlight-like UI for all types of hotkeys. There are multiple apps doing similar things, but I wanted to take things further. The defining features would have been: * Parsers and ingesters for user defined hotkeys in most common apps + (e.g. keeping an always up-to-date database of hotkeys from skhdrc, keybindings.json etc.) + this could be extensible by users who want to write their own parsers * Really good fuzzy search that surfaces the keys most likely to be forgotten * Easily edit a key binding without having to remember where it's defined After a few months, me and 2 friends wrote the parser architecture, the key bindings change watchers, a bit of UI, a bit of CLI, and the following parsers: * Shells: Bash, ZSH, Fish * Browsers: Chrome (for extension hotkeys) * Terminals: iTerm, Kitty * Code Editors: Sublime Text, VSCode, XCode, JetBrains * Menubar (basically what CheatSheet does) * skhd But there was so much more work to do, and some parsers were already getting compatibility issues from app updates, that we paused working on it. I gained a lot more experience in macOS app dev, so I'm hoping to revisit this idea soon. I'm also secretly hoping to start crafting wood flutes and composing music so that I don't have a need for remembering any hotkeys anymore. Here's my first Romanian Kaval ^_^ [making-cav] * Twitter @alinp32 * The low-tech guys my macOS app studio * Github alin23