Per-App Profiles
Automatically switch configurations based on the frontmost application. Use different MIDI mappings for VS Code, Photoshop, Final Cut Pro, etc.
Overview
Per-app profiles enable context-aware MIDI control:
- Automatic switching: Profiles activate when you switch apps
- App-specific mappings: Different buttons for different workflows
- Manual override: Force a specific profile when needed
- Profile inheritance: Share common mappings across profiles
Getting Started
1. Enable App Detection
# macOS: Grant Accessibility permissions
# System Settings → Privacy & Security → Accessibility → Conductor
# Verify app detection is working
conductorctl frontmost-app
2. Create Profiles
Via GUI
- Open Conductor GUI
- Navigate to Devices tab
- Click 🔄 Profiles
- Click + New Profile
- Enter profile name (e.g., “vscode-profile”)
- Configure mappings
- Save profile
Via Config File
Create separate profile files in ~/.config/conductor/profiles/:
~/.config/conductor/profiles/
├── default.toml # Fallback profile
├── vscode.toml # VS Code mappings
├── photoshop.toml # Photoshop mappings
└── fcpx.toml # Final Cut Pro mappings
3. Register App Associations
Map applications to profiles:
GUI Method
- In Profile Manager dialog
- Click Associate App
- Select profile
- Choose application from list
- Click Save
Config Method
Edit ~/.config/conductor/app_profiles.toml:
[app_associations]
"Visual Studio Code" = "vscode"
"Code" = "vscode" # Alternative app name
"Adobe Photoshop" = "photoshop"
"Final Cut Pro" = "fcpx"
Profile Configuration
Profile Structure
Each profile is a complete Conductor configuration:
# profiles/vscode.toml
[device]
name = "Mikro"
auto_connect = true
[[modes]]
name = "Coding"
color = "blue"
# Code navigation mappings
[[modes.mappings]]
[modes.mappings.trigger]
type = "Note"
note = 36
[modes.mappings.action]
type = "Keystroke"
modifiers = ["Ctrl"]
keys = "P" # Quick file open
[[modes.mappings]]
[modes.mappings.trigger]
type = "Note"
note = 37
[modes.mappings.action]
type = "Keystroke"
modifiers = ["Ctrl", "Shift"]
keys = "F" # Find in files
# Debug controls
[[modes.mappings]]
[modes.mappings.trigger]
type = "Note"
note = 38
[modes.mappings.action]
type = "Keystroke"
keys = "F5" # Start debugging
Shared Mappings
Use global mappings that work across all profiles:
# In each profile, include common mappings
[[global_mappings]]
[global_mappings.trigger]
type = "EncoderTurn"
cc = 7
direction = "Clockwise"
[global_mappings.action]
type = "VolumeControl"
action = "Up"
App Detection
Supported Platforms
- macOS: Full support via Accessibility API
- Linux: Full support via X11/Wayland
- Windows: Full support via Win32 API
App Name Matching
Conductor matches application names flexibly:
# All of these will match Visual Studio Code
"Visual Studio Code" = "vscode"
"Code" = "vscode"
"code" = "vscode"
"VSCode" = "vscode"
Wildcards
Use wildcards for partial matching:
"*Adobe*" = "adobe-suite" # Matches any Adobe app
"Chrome*" = "browser" # Matches Chrome variants
Profile Switching
Automatic Switching
When app detection is enabled:
- Focus changes to new application
- Conductor detects the frontmost app
- Looks up associated profile
- Loads and activates profile
- LED feedback shows profile change (optional)
Switching latency: ~50ms
Manual Override
Force a specific profile:
GUI Method
- Click 🔄 Profiles button
- Select profile from list
- Click Activate
CLI Method
conductorctl switch-profile vscode
Default Fallback
If no profile matches the current app, Conductor uses:
defaultprofile (if exists)- Main
config.toml
Use Cases
Software Development
# profiles/dev.toml
# Buttons for common IDE actions
[[modes.mappings]]
# Run tests
[modes.mappings.trigger]
type = "Note"
note = 36
[modes.mappings.action]
type = "Keystroke"
modifiers = ["Ctrl"]
keys = "T"
[[modes.mappings]]
# Git commit
[modes.mappings.trigger]
type = "Note"
note = 37
[modes.mappings.action]
type = "Shell"
command = "git commit"
[[modes.mappings]]
# Format code
[modes.mappings.trigger]
type = "Note"
note = 38
[modes.mappings.action]
type = "Keystroke"
modifiers = ["Shift", "Alt"]
keys = "F"
Video Editing
# profiles/video.toml
# Timeline control and playback
[[modes.mappings]]
# Play/Pause
[modes.mappings.trigger]
type = "Note"
note = 36
[modes.mappings.action]
type = "Keystroke"
keys = "Space"
[[modes.mappings]]
# Cut clip
[modes.mappings.trigger]
type = "Note"
note = 37
[modes.mappings.action]
type = "Keystroke"
modifiers = ["Cmd"]
keys = "B"
[[modes.mappings]]
# Ripple delete
[modes.mappings.trigger]
type = "LongPress"
note = 37
duration_ms = 1000
[modes.mappings.action]
type = "Keystroke"
modifiers = ["Shift"]
keys = "Delete"
Photo Editing
# profiles/photo.toml
# Brush size, zoom, undo/redo
[[modes.mappings]]
# Increase brush size
[modes.mappings.trigger]
type = "EncoderTurn"
cc = 1
direction = "Clockwise"
[modes.mappings.action]
type = "Keystroke"
keys = "]"
[[modes.mappings]]
# Decrease brush size
[modes.mappings.trigger]
type = "EncoderTurn"
cc = 1
direction = "CounterClockwise"
[modes.mappings.action]
type = "Keystroke"
keys = "["
[[modes.mappings]]
# Undo
[modes.mappings.trigger]
type = "Note"
note = 36
[modes.mappings.action]
type = "Keystroke"
modifiers = ["Cmd"]
keys = "Z"
Profile Management
Export Profiles
Share or back up profiles:
GUI Method
- Profile Manager → Select profile
- Click Export
- Choose format (TOML/JSON)
- Save file
CLI Method
conductorctl export-profile vscode > vscode-profile.toml
Import Profiles
Load profiles from files:
GUI Method
- Profile Manager → Import
- Select file
- Choose name for imported profile
- Click Import
CLI Method
conductorctl import-profile vscode-profile.toml
Profile Validation
Test profiles before activating:
conductorctl validate-profile vscode
Troubleshooting
App Not Detected
-
Check permissions:
- macOS: Accessibility permissions granted
- Linux: Running with sufficient privileges
- Windows: No UAC blocking
-
Verify app name:
conductorctl frontmost-app -
Check association:
- Ensure app name in config matches actual name
- Use wildcards if app name varies
Profile Not Switching
-
Check app detection is enabled:
conductorctl status -
Verify profile exists:
ls ~/.config/conductor/profiles/ -
Test manual switch:
conductorctl switch-profile vscode -
Check logs:
conductorctl logs | grep profile
Wrong Profile Activates
- Check association priority
- Verify no conflicting wildcards
- Review app name matching in logs
Best Practices
-
Start with defaults: Create a base profile with common mappings
-
Use inheritance: Share global mappings across profiles
-
Test thoroughly: Verify each profile works in target app
-
Name clearly: Use descriptive profile names (e.g., “davinci-resolve” not “prof1”)
-
Document mappings: Add comments in TOML files
-
Version control: Keep profiles in git for history
-
Export regularly: Back up working profiles
-
Share templates: Contribute profiles for popular apps
Advanced Features
Conditional Switching
Switch based on multiple criteria:
[switching_rules]
# Only switch to fcpx profile if specific project is open
[[switching_rules.conditions]]
app = "Final Cut Pro"
window_title = "*MyProject*"
profile = "fcpx-myproject"
Profile Chains
Load multiple profiles in sequence:
[profile_chain]
base = "default"
overlay = "vscode"
# Loads default, then overlays vscode-specific mappings
Hot Reload
Profiles support hot reload:
- Edit profile file
- Save changes
- Switch to different app and back
- Profile reloads automatically
Next Steps
- Learn about MIDI Learn to quickly create profile mappings
- Set up device templates for consistent layouts
- Use the event console to test profile mappings
- Explore LED feedback for visual profile indication