Let’s get crazy with BetterTouchTool and Touch Bar Simulator
I’ve recently put some1 time into making a Touch Bar “dashboard” using BetterTouchTool. I know, the first thing you thought when you read that was “but Apple is discontinuing the Touch Bar!” Let me explain. Or try to. I almost didn’t write this post because I was worried it would indicate mental instability of some kind2. But how could I call myself a “Mac Mad Scientist” if things didn’t get a little crazy? We’re all mad here, right?
So I had a MacBook Pro with a Touch Bar for a couple of years. I immediately loved the idea of the Touch Bar, made it do a few cool things, and generally appreciated the fact that it was there, offering contextually-relevant and visually identifiable “keys.” Did I actually use it? Not a lot. I had a cool script that made buttons for tasks that howzit could run in the current directory when I was in the terminal, and I used that quite a bit, but other than that, not really.
90% of the time my MacBook was on a stand next to an external display, being controlled from an external keyboard and trackpad, and the Touch Bar was, at best, inconvenient to reach. I’d stretch to it on the occasions I needed to use Touch ID or run a howzit command, but not for any of the other features it offered. So I didn’t really miss the Touch Bar when I moved over to an M1 Mac mini.
I did, however, miss that
howzit integration I mentioned, at least enough that I got curious about Touch Bar simulators I could easily run on my Mac mini. It’s not a terribly difficult trick, but there aren’t a lot of choices out there. The most developed one seems to be Touch Bar Simulator.
This allowed me to have all of my howzit buttons appear when I
cd into a project directory (I modified it to also show the F-key equivalents for better keyboard access). And suddenly I found myself more interested in hacking around with what BetterTouchTool can do with a Touch Bar. Which is where this post is headed. First, a bit about the simulator.
- It can be docked to top or bottom of display, sans window buttons (the traffic lights)
- It can automatically hide and show the way the Dock can
- It has adjustable opacity
- It has global shortcuts for hiding/showing the Touch Bar window
A numbered list, because I’ll address them one at a time.
- This one is obvious, but it’s no longer a touch screen and there’s no translation of mouse-to-touch gestures, so some of BetterTouchTool’s cool gesture capabilities are off the table
- It floats at the absolute highest level, so it always obscures menus underneath it
- Having a Touch Bar docked at the top of your display hides title bars of windows at the top of the screen, and gets in the way of things like typing at the top of an iTerm visor window
I don’t care about con #1, I have trackpad gestures for everything anyway.
Con #2 is almost a non-issue for me. This is almost certainly a personal quirk, but I almost never have windows at the top of the screen — I keep most windows visually centered to some extent, and rarely have full-height windows. The only thing at the top of my display is my iTerm visor, and all of the action in there is usually happening at the bottom of the visor (other than the first command I type, but my prompt is two lines so the cursor is visible anyway). I actually haven’t once had to move a window because the Touch Bar is obscuring it. That said, I have a Hyper-backtick shortcut set up to easily dismiss it with my left hand when needed.
Con #3 (the window level), though, is a little more significant for me, because I want the Touch Bar at the top of my screen, basically acting as a second, much prettier menu bar. But if I don’t set it to automatically hide, any menus that drop down from my actual menu bar are hidden behind it. And if I have it automatically hide, I have to be careful not to move the pointer all the way to the top of the display if I’m trying to click something in the menu bar. However, thanks to Bartender, all of my visible menu bar icons are usually to the right of the Touch Bar window, safe from being obscured. It only bites me when I have the full menu bar open and need to access a usually-hidden dropdown.
So with those cons in mind, I’ve been using it as a kind of dashboard for a couple of weeks now and I’m very happy with it. I compiled all of the scripts I’m using into one and made it available on GitHub. It can not only display cpu/memory charts and percents and network info, it can also add widgets to BetterTouchTool for you automatically. And almost all of the widgets also work as menu bar widgets, so even if you’re not down with the Touch Bar Simulator thing, you might still find it useful.
Getting BetterTouchTool to Work With Touch Bar Simulator
When I first loaded up Touch Bar Simulator, I got no BetterTouchTool icon. I assume because my Mac mini doesn’t natively have a Touch Bar and there’s some voodoo missing as a result. I tried a few
defaults write incantations, some of which did nothing, some of which completely erased the Touch Bar screen. But none of which actually seemed to get BetterTouchTool to show up. At some point it just happened. There were probably some reboots involved.
I think that the boot order affects it. If BetterTouchTool is already running when Touch Bar Simulator loads, sometimes the BTT menu doesn’t show up. Opening BTT preferences and clicking “Restart BTT” always does the trick.
I would like to give you a step-by-step of how I eventually got it to work, but I’m unsure what eventually did it, and I’m certain that giving you the list of things I tried would do more harm than good. I don’t have any other non-Touch Bar machines to try it out again on, so I can’t be of much assistance. Sorry. But I can tell you that BetterTouchTool does work with Touch Bar Simulator, once the fates agree to it.
Try launching Touch Bar Simulator and BetterTouchTool and maybe it just works for everybody else without an hour of fiddling. Who knows?
The Moving Parts
Just in case you get an itch to follow along with the rest of this, the ingredients here are:
- BetterTouchTool (available on Setapp)
- Touch Bar Simulator, free (and also optional if you have an actual touch bar, and you can do a lot of this with just the menu bar…)
- Some scripts I wrote to make it all work
btt_stats.rb script in the GitHub repo can be run with
-h to list all of the things it can do for you, and I put some time into the README, so I won’t bore you with all of those details here. Here’s the overview:
Usage: btt_stats.rb [options] [subcommand] Subcommands (* = default): cpu* memory ip [lan|wan*] network [interface|location*] doing refresh [key:path ...] add [touch|menu] COMMAND uuids [install] To add widgets automatically, use: btt_stats.rb add [touch|menu] [command] where command is one of cpu, memory, lan, wan, interface, location, doing, or bunch To quickly get widget UUIDs for use with the refresh command, select a widget or group in BetterTouchTool configuration, press ⌘C to copy it, then run: btt_stats.rb uuids (run `btt_stats.rb uuids install` to have them added to your config automatically.) Options: -a, --averages AVERAGES Comma separated list of CPU averages to display (1, 5, 15), default all -c, --color_from AVERAGE Which CPU average to get level indicator color from (1, 5, 15), default 1 -f, --free Display free memory instead of used memory -i, --indicator Include background color indicating severity or activity -p, --percent Display percentages instead of bar graph --split_cpu Display CPU graph on multiple lines (ignores --averages) --prefix PREFIX Include text before output, [PREFIX][CHART/%] --suffix SUFFIX Include text after output, [CHART/%][SUFFIX] -w, --width WIDTH Width of bar graph (default 8) --empty CHARACTER Include character when output is empty to prevent widget from collapsing --raw Output raw text without BetterTouchTool formatting --top If CPU is maxed, include top process in output --truncate LENGTH Truncate output -h, --help Display this screen
In short, it allows me to use the same script in every widget, just changing the command line arguments for it. To get a CPU bar complete with severity level coloring, I just run
btt_stats.rb cpu -i. For memory usage it’s
btt_stats.rb mem -i. You get the idea.
I will tell you about some of the more interesting (to me) diversions, though.
You may be familiar with my little command line time tracking project, Doing. It’s a tool that helps you track what you’re doing at any given time, giving you a TaskPaper-formatted list of what you are doing and what you’ve been doing. It’s gotten pretty crazy over the years. In addition to the command line, I frequently use it with LaunchBar, but I regularly forget that I have a task running, or forget to add a task when starting one. I’ve added a bunch of features to Doing to compensate for my forgetfulness, but, and I’m just asking questions, what if there was a thingy in the Touch Bar that reminded me?
btt_stats script has a
doing command. You just set up a view in your
.doingrc like this:
views: btt: section: Currently count: 1 order: desc template: "%title" tags_bool: NONE tags: done
btt_stats.rb doing gives you a one-liner with your current task, along with a background color. You can also tell it what string to return if there’s no task running, and what color to make the widget when you’re “inactive.” (Again, see the
btt_stats README for details.) So you could potentially have a bright red button that says “WHAT ARE YOU DOING?” in your touch bar/menu bar to remind you to update when there’s no active entry.
I have my widget set to run a shell command when clicked to load up the Doing LaunchBar action (
open 'x-launchbar:select?abbreviation=DOING'), where I can just hit Space, type what I’m doing, and the widget updates with my current task. It also has a long-press action, so clicking and holding the Touch Bar button will run
doing finish in a shell script, completing any current task. It’s a one-button interface to my Doing setup.
Side note: I updated Doing recently with the ability to run an external script whenever it runs a command which alters the doing file. I wanted this because I set up most of these widgets to accept “push” updates rather than constantly polling for changes. This requires copying the UUID from each widget into the
btt_stats config, but once they’re there, you can just run something like
btt_stats refresh doing and the Doing widget will update with new contents. I haven’t documented this new “hook” in the Doing docs yet, but it’s as easy as adding a line to your
run_after: ~/scripts/btt_stats.rb refresh doing
You may also be familiar with my little text-based automation project, Bunch. I had some fun making a “Bunch Status Board” for my Touch Bar. It’s not a necessary thing, all of my Bunches have easy shortcuts and seeing their status is as simple as hitting the Bunch shortcut to open the menu. But I was having fun and this came out pretty cool.
btt_stats script can generate the status board for you automatically (
btt_stats.rb add touch bunch). It will get a list of all your Bunches (everything that shows up in the Bunch menu), create a buttons for them, and generate the URLs they’ll send to toggle their assigned Bunches. It adds them in a Touch Bar group with a little Bunch button to open it. Like the Doing widgets, I have Bunch update the buttons when it opens or closes a Bunch, rather than having all of the buttons constantly poll to get the state of their Bunch. I detailed this setup in the “Advanced Scripting” section of the Bunch docs for anyone wanting to try it.
btt_stats script can even generate the necessary configuration for the push updates. Just select the Bunch group in BetterTouchTool settings, hit ⌘C, and then run
btt_stats.rb uuids install. All of the Bunch widget UUIDs get added to your configuration, and then you can just run
btt_stats.rb refresh Bunch:Comms to update the widget at any time (like from a script that runs after any Bunch opens and closes… see the Bunch docs).
The Other Stuff
As I’ve mentioned, the
btt_stats script can generate any widgets you see that aren’t already available as BetterTouchTool widgets.
I’m making use of “groups” in the BetterTouchTool Touch Bar settings to create separate panels for “system status,” “Bunch,” and “Weather.” The buttons on the main screen are assigned to open different groups, and then each group contains a simple “X” button with the action “Close current group.” With all of the other macOS stuff hidden via BTT preferences, this provides clean navigation between “screens.”
Clicking the CPU meter in the main Touch Bar screen opens the “system status” group, with network details, ip addresses, memory meter, and 2-bar/3-average CPU load readout. These widgets serve as shortcuts to things like System Preferences or Activity Monitor.
The weather icon on the main screen just has a current conditions icon and current temp. Clicking it opens a full screen of weather details, including moon phase, sunrise/sunset, and a 7 day forecast.
And of course, there’s a Now Playing widget that shows me the current track playing in Spotify or Apple Music. I have it set up so that clicking it toggles play/pause, and a long press skips to the next track.
A Few Tips
I’ve learned a few things along the way. Here are some tips I can offer after toying with BetterTouchTool and the Touch Bar for
a while too long.
Regarding the Touch Bar simulator, I’ve personally settled on not having it auto-hide and assigning a hotkey to toggle it on and off. Mine is Hyper-` (backtick), which is an easy left-hand combo to get it out of the way when needed.
Also, set up a keyboard shortcut in BetterTouchTool with the action “Toggle BetterTouchTool Touch Bar.” It will come in handy to be able to quickly toggle it on and off while fiddling, as well as making it easy to get to default Touch Bar functionality when you want to. Mine is assigned to an extra button on a thumb module of my keyboard, which puts it conveniently next to my spacebar, but I’m guessing you don’t have that key available. You’d pick something awesome, too, I’m sure of it.
BetterTouchTool Touch Bar widgets can have long press actions, and menu bar widgets can have right click actions. Both of these use Named Triggers, which you can define in BetterTouchTool under Named & Other Triggers. So a Touch Bar button or menu bar widget can be a status indicator, plus an action, plus a secondary action. That’s three more things than you could do without a button.
Per-App Settings and Groups
If you want to disable the BetterTouchTool Touch Bar for a specific app, just add it to the sidebar in the BetterTouchTool Touch Bar settings, and then under “Touch Bar Configuration For: [APP],” choose “Default (No Special Handling).”
You can also have apps trigger specific Touch Bar groups by adding a “Specific App Did Activate” trigger under Named & Other Triggers, and adding an “Open Touch Bar Group With Name” action to it. Add another one for “Did Deactivate” to “Close current Touch Bar group”” when another app is focused.
Link to Today View in Calendar
If you want a custom date widget to link to the current day in Calendar, use an AppleScript action with:
tell application "Calendar" switch view to day view view calendar at current date end tell
Link Directly to a System Preferences Pane
If you want to link a button to a specific pane of System Preferences, add a “Launch Application” action and point it directly to the
.prefPane file for that pane. For example, the Network preference pane is at
That’s it. It got a little crazy, but you survived to the end. Treat yourself to something nice.
An understatement, but I refuse to say exactly how much. ↩
Yes, I’m bipolar and ADHD, and you might chalk this up to a manic episode or a bout of ADHD hyperfocus, except I spent over 3 weeks playing with this and coming back to it. My manic episodes are never more than 5 days. If this project indicates a mental disorder, it’s something I haven’t been diagnosed with yet. ↩