Key to switch to specific Mac app

I’m thinking of binding prog+some easy to reach keys (jkl; maybe) to switch to my most commonly used Mac apps. Anyone tried something like this? I’m not sure how to start exactly.

One idea is to install something like Keyboard Maestro and bind “open app X” to some bizarre key combination, and bind the keys to that combo (in a new layer I guess). To avoid that app I guess I could mess around with Automator.

Another idea would be to try to use serial communication? I think Focus is just for host->keyboard communication but I could run a program that frequently uses Focus to poll the keyboard for “should I switch apps” events, and run it in the background.

Thoughts?

Focus is bi-directional, the keyboard can send stuff to the host aswell. But you can also use raw Serial, as long as there is no application actively trying to speak the Focus protocol all the time. What I do, is that I have macros that send appsel:something over the serial port, and then a small tool on the host does the hard work of selecting the appropriate application.

I can use Focus at the same time, because I only run the tool that talks with the keyboard when I need it, it has no exclusive lock on the serial port. So I can mix the two. This may not be the best solution going forward, but it is one that works for me right now. I could send appsel something\n.\n too, which would conform to Focus responses, and have an app listen on the host and act on it. It wouldn’t need periodically poll, but could use the OS-provided poll() or similar, to notice that there’s data on the port immediately, without having to wait until the next poll tick.

Using bizarre key combos (like LSHIFT(LCTRL(LALT(LGUI(RALT(Key_X)))))) together with a helper on the host, as you described.

2 Likes

I do this on my Mac.

  1. I am currently using a stock Apple keyboard, so I needed Karabiner Elements to map capslock to be F19 (a key not used by anything, only on the tenkey version of the keyboard).
  2. I then used Karabiner Elements to map F19 to be command+alt+ctrl+shift (sometimes called Hyper)
  3. I then use Alfred App to create a list of shortcuts to switch apps. Hyper+A to switch to my browser, Hyper+R to switch to my terminal, Hyper+S to switch to my IDE.

Alfred app has stats for the last month and I apparently use hotkeys in this way an average of 200x a day. The biggest outlier day I’ve seen was 1500x!

Command+tab sucks, I highly recommend this!

For Keyboard Maestro you can map all your apps to the same global shortcut (e.g. command+shift+space or something) which will prompt the KM “which app did you mean” pop up—at which point typing the first letter of the app name filters if memory serves. This actually works pretty well.

3 Likes

@algernon: I like this idea but am worried specifically about the locking issue. Is there a reasonable way to do something like this but have it always run?

@arley: hmm, this also seems nice, but Alfred seems pretty overkill to just use for this one thing… and it looks like the hotkey feature is one of the paid features? I have nothing against paying for software but am not really inspired to do so just to use one tiny feature of a huge project…

1 Like

Well, the locking issue is only present if you run two programs that want to talk to the keyboard on Serial. For example, if we baked the application switching mechanism into Chrysalis, there would be no such issue. Right now, I’m using two tools: one constantly running daemon that listens to appsel commands, and the example python script in Kaleidoscope-Focus. When I want to use the latter, I stop the former. Not ideal, but I rarely want to talk to the keyboard these days.

With that in mind, I’ll modify my appsel tool to also include a command-line REPL (a’la the Focus example), and that way I’ll only run a single thing.

So, yeah, there is a reasonable way to use Focus, have an application-selector on the host side, and do this in a reasonable way. Not in an easy, ready-made way (yet!), but a reasonable way nevertheless.

Sounds reasonable.

And if I’m not running some specific tool or plugin which I know talks over the serial port, then it’s not in use, right? Does it conflict with make flash?

Yep, sorry. I get more than my money’s worth from hotkeys and clipboard history :slight_smile:
Maybe you can whip up some macros that fire-off the Spotlight app switching?

Yes.

The tool can be made in a way that it won’t conflict: if it notices a disconnect, just don’t reconnect immediately, but wait until flashing is over. Flashing involves sending a reset to the device, which - as far as I understand - will cause clients to disconnect. I’ve yet to verify this, though.

Eh, as much fun as writing serial communication code sounds, Alfred works great. Thanks for all the suggestions!

Here’s wiring up prog plus home row keys to weird combos (layer shift worked better than just mapping prog to ctrl-option-shift-cmd because it doesn’t mess up prog-enter for flashing): https://github.com/glasser/Model01-Firmware/commit/dc93b99504f30030cf96cbb96b7cc91f4a2656d7

Then the Alfred workflows all look something like:

Regarding setting up a Hyper key, also see this comment by Jesse. (This approach is also described by algernon above, but I didn’t comprehend until reading jesse’s comment.

I was using Karabiner Elements as described above, but:

  • doing it with LSHIFT(LALT(LCTRL(Key_LeftGui))) directly in the key map is easier
  • Karabiner Elements worked for this, but was logging lots of: “IOHIDDeviceOpen error: kIOReturnBadArgument (-536870206) Model 01…” and Karabiner Elements was using a bit more CPU with the Model 01 enabled than with any of my other external keyboards, possibly due to the error logging
1 Like

I also had this. Making the board do all the work is way cooler.

@glasser you can also keep your workflow drawer cleaner if you make just one Hyper workflow (screenshot below). All my app switching is grouped together, as well as other commands (I use hyper to switch to Colemak/Qwerty, log out of my system etc.). I also use the Read Me to keep track of other apps that use Hyper (like in the Divvy app I map this key, but I want to be able to go to one place to see what every key is doing).

On my M01 I mapped Hyper on the LED key and “Meh” on the Any key (Meh is cmd+alt+ctrl)

1 Like

@arley, thanks for the excellent Alfred tip. I am using my Hyper key in this way, and it is delightfully convenient.

The only thing that would make it better is if the OneShot plugin worked on the composited LSHIFT(LALT(LCTRL(Key_LeftGui))) keymap entry.

It may be possible to do that, with a trick: using a macro! Something along these lines:

static void OneShotHyper(uint8_t keyState) {
  handleKeyswitchEvent(OSM(LeftShift), UNKNOWN_KEYSWITCH_LOCATION, keyState);
  handleKeyswitchEvent(OSM(LeftControl), UNKNOWN_KEYSWITCH_LOCATION, keyState);
  handleKeyswitchEvent(OSM(LeftAlt), UNKNOWN_KEYSWITCH_LOCATION, keyState);
  handleKeyswitchEvent(OSM(LeftGui), UNKNOWN_KEYSWITCH_LOCATION, keyState);
}

Mind you, I have not tried it, and it may or may not work. It should, though. If it doesn’t, let me know and I’ll see if I can come up with a working solution.

The trick here is that OneShot does not cancel itself when another OneShot is input, so we create a macro that simulates pressing the oneshot variant of all of the left-side modifiers.

3 Likes

Many thanks @algernon, that works as advertised.

1 Like

Also works for me, but I feel like I have to be quicker than the default of 2500ms. I don’t think that’s an issue for me, just interesting.