Repository navigation
v1.2.0 — Custom Key Actions, Profiles & UX Polish
Pre-releaseWhat's New in v1.2.0
This release is a significant feature expansion. All changes are build-verified via swift build and ready for testing via ./build.sh.
🎛️ Custom Key Remapping
Each F-key can now be remapped to any of four action types:
| Type | What it does |
|---|---|
| System | Original macOS HID/CGEvent function (default, unchanged) |
| App | Launch or activate any app by bundle ID (e.g. com.apple.Safari) |
| URL | Open any URL — https://, file://, or custom schemes |
| Shell | Run an arbitrary command via /bin/sh -c in the background |
Custom actions respect the same 150 ms rate-limit and 200 ms tap-debounce as system keys. Remapped keys show a distinct SF Symbol icon and updated tooltip in the popover.
👤 Profiles
Save and switch between named sets of key mappings:
- Right-click the menu-bar icon to instantly switch profiles (active profile shown with a checkmark)
- Create, duplicate, and delete profiles from the new Profiles tab in Settings
- The built-in Default profile has a stable UUID and cannot be deleted
- Switching profiles takes effect immediately across the entire popover
⚙️ Settings Window
Opens via ⌘, or the gear icon in the popover header.
- Keys tab — per-key segmented type picker, detail input field, per-key reset button, active profile name in the header, and a global "Reset All" button
- Profiles tab — full CRUD for profiles with inline creation
🚀 Launch at Login
A Login checkbox in the popover footer registers the app as a login item via SMAppService.mainApp (macOS 13+, no helper bundle required).
The app must be located in
/Applicationsfor this to take effect at runtime.
🔒 Auto-Dismiss
An Auto-close checkbox in the popover footer closes the popover automatically after any key is pressed. The popover waits for the spring-press animation to finish before dismissing.
📊 Live State Indicators
Brightness and volume levels are now visible directly on the relevant keys:
- F1 / F2 — brightness bar (polls via IOKit
IODisplayGetFloatParameter) - F11 / F12 — volume bar (polls via CoreAudio)
- F10 — bar turns red and empties when muted
State is polled every 1 second in a background Timer; no private APIs are used.
🗂️ New Source Files
| File | Description |
|---|---|
KeyAction.swift |
enum KeyAction with Codable conformance and display helpers |
KeyActionStore.swift |
ObservableObject delegating to ProfileManager |
KeyProfile.swift |
Identifiable + Codable profile model |
ProfileManager.swift |
Profile CRUD + active-profile persistence |
LaunchAtLoginManager.swift |
Thin SMAppService wrapper |
SystemStateMonitor.swift |
IOKit + CoreAudio polling |
SettingsView.swift |
Tabbed settings UI (Keys + Profiles) |
🔧 Modified Files
KeySimulator.swift · FunctionKeyView.swift · KeyboardView.swift · FnKeyboardApp.swift · Info.plist
Full Changelog: 1.1.0...1.2.0