A macOS menu-bar app that lets you launch and switch between applications using global keyboard shortcuts. Written in Rust. Define your shortcuts in a TOML config file and they work system-wide, regardless of which app is in front.
Each shortcut toggles its app:
- not running: launch it
- running but not in front: bring it forward
- already focused: hide it
If the app has multiple windows, repeated presses cycle through them before hiding.
brew tap nhz-io/tap
brew install --cask kbswAfter installing, grant Accessibility permission in System Settings > Privacy & Security > Accessibility (needed for window cycling). Then register the login agent:
kbsw installDownload the zip from the latest release, then:
unzip kbsw-*.zip
xattr -cr kbsw.app
kbsw.app/Contents/MacOS/kbsw installThe xattr step clears the macOS Gatekeeper quarantine flag. Homebrew does
this automatically.
The config file lives at ~/.config/kbsw/config.toml and is created with
sensible defaults on first run. Save the file and changes apply immediately
(no restart needed). You can also pick Reload config or Edit config...
from the menu-bar icon.
# Identify an app by bundle id (most reliable) ...
[[binding]]
keys = "cmd+ctrl+t"
bundle_id = "com.apple.Terminal"
# ... or by name / path.
[[binding]]
keys = "shift+alt+s"
app = "Safari"modifier+modifier+...+key
- modifiers:
cmd(orcommand/super),ctrl(orcontrol),alt(oroption),shift - keys:
a-z,0-9,f1-f24,space,enter,tab,escape,arrowup/arrowdown/arrowleft/arrowright, etc.
Examples: cmd+ctrl+t, shift+alt+f5, ctrl+space
Avoid ctrl+alt combos since macOS VoiceOver reserves them. If a shortcut is
already taken by the system or another app, registration fails with a log
message and the rest keep working.
osascript -e 'id of app "Safari"' # -> com.apple.Safarikbsw # run the menu-bar service (default)
kbsw install # deploy to ~/Applications + start at login
kbsw install --force # redeploy over an existing install
kbsw uninstall # stop and remove the agent (config is kept)
kbsw --help # usageinstall copies the app bundle to ~/Applications/kbsw.app, writes a
LaunchAgent so it starts at login and restarts if it exits, and starts the
agent immediately.
Installed paths:
~/Applications/kbsw.app~/Library/LaunchAgents/io.nhz.kbsw.agent.plist~/Library/Logs/kbsw.log
Requires a Rust toolchain (rustup).
# Run in the foreground (logs to the terminal):
cargo run
# Build an optimized binary:
cargo build --release
# Build a distributable zip:
cargo xtask releasecargo xtask release assembles dist/kbsw.app and zips it into
dist/kbsw-<version>-macos-<arch>.zip.
- Launching, switching, and hiding apps works without Accessibility permission.
- Window cycling (rotating through an app's windows on repeated presses) needs Accessibility. Without it, repeated presses just hide and restore. kbsw prompts for the grant on startup.
- Some apps (notably Finder) don't populate the standard
AXWindowsattribute but still expose windows as children. kbsw handles this automatically. - macOS may prompt the first time the app controls another application (Automation/AppleEvents). Allow it.
src/
main.rs command dispatch (run / install / uninstall / help)
service.rs event loop, hotkey registration, tray menu, hot-reload
config.rs TOML config loading + default config
app_control.rs launch / activate / hide / cycle via AppKit + AX
ax.rs Accessibility helpers (enumerate + raise windows)
installer.rs deploy .app bundle + LaunchAgent
assets/ templates embedded via include_str! at build time
Info.plist app bundle metadata
agent.plist LaunchAgent template
default-config.toml default config written on first run
xtask/ build tooling (cargo xtask release)