-
Notifications
You must be signed in to change notification settings - Fork 0
MIDI Device Hot-Plug Detection Not Working on macOS #11
Description
MIDI Device Hot-Plug Detection Not Working on macOS
Problem Description
When using the MIDIMon GUI, newly connected or disconnected MIDI devices are not detected by the refresh button or auto-refresh (every 5 seconds). Users must restart the entire GUI application to see device changes.
Current Behavior
- ❌ Refresh button does not detect newly plugged MIDI devices
- ❌ Auto-refresh (5 second interval) does not detect device changes
- ❌ Removing a device shows "Unknown Device" in the list
- ✅ Restarting the GUI application picks up all device changes
Expected Behavior
- ✅ Refresh button should immediately detect newly connected/disconnected devices
- ✅ Auto-refresh should detect device changes without user interaction
- ✅ Device list should dynamically update as devices are plugged/unplugged
Root Cause
This is a known limitation of the midir crate on macOS, not a bug in MIDIMon.
Evidence
From midir GitHub Issue #78: "hotplug support with CoreMIDI?":
"On macOS (CoreMIDI), when you create a MidiInput/MidiOutput and iterate the available ports, devices that have been plugged in since the program started are not available (even when you create a new MidiInput/MidiOutput after the device was plugged in)."
Technical Details
- midir uses CoreMIDI internally on macOS but doesn't expose CoreMIDI's hot-plug notification system
- CoreMIDI itself DOES support hot-plug detection - the limitation is in midir's abstraction layer
- The coremidi Rust crate properly implements hot-plug notifications via CoreMIDI's device change callbacks
Impact
Severity: Medium
Affected Platforms: macOS only (Linux/Windows may have similar issues)
Workaround: Restart GUI application
User Impact:
- Minor inconvenience for users who frequently connect/disconnect MIDI devices
- Not critical for typical usage (devices rarely change during a session)
- Common behavior in many MIDI applications
Proposed Solutions
Option 1: Document the Limitation (Quick Fix)
Effort: Low (1 hour)
Impact: Minimal
Add a note to the UI:
ℹ️ Note: Restart the application to detect newly connected devices
Pros:
- ✅ No code changes required
- ✅ Maintains cross-platform simplicity
- ✅ Common behavior in MIDI apps
Cons:
- ❌ Doesn't solve the problem
- ❌ Poor UX compared to modern apps
Option 2: Hybrid Approach - Use coremidi for macOS (Recommended)
Effort: Medium (4-8 hours)
Impact: High
Use coremidi for device enumeration on macOS, keep midir for MIDI I/O:
// midimon-gui/src-tauri/src/commands.rs
#[cfg(target_os = "macos")]
async fn list_midi_devices_macos() -> Result<Vec<MidiDevice>, String> {
use coremidi::{Client, Sources};
let client = Client::new("MIDIMon Scanner")?;
let sources = Sources::new();
let mut devices = Vec::new();
for (index, source) in sources.enumerate() {
let name = source.display_name()?;
devices.push(MidiDevice {
index,
name,
connected: false,
});
}
Ok(devices)
}
#[cfg(not(target_os = "macos"))]
async fn list_midi_devices_cross_platform() -> Result<Vec<MidiDevice>, String> {
// Current midir implementation
}
#[tauri::command]
pub async fn list_midi_devices(_state: State<'_, AppState>) -> Result<Vec<MidiDevice>, String> {
#[cfg(target_os = "macos")]
return list_midi_devices_macos().await;
#[cfg(not(target_os = "macos"))]
return list_midi_devices_cross_platform().await;
}Pros:
- ✅ Proper hot-plug detection on macOS
- ✅ Maintains cross-platform support
- ✅ Better UX for macOS users
- ✅ Leverages existing
coremididependency (already in workspace)
Cons:
⚠️ Platform-specific code complexity⚠️ Need to test both code paths⚠️ Maintain two implementations
Option 3: Implement CoreMIDI Notifications (Advanced)
Effort: High (12-16 hours)
Impact: Very High
Implement full CoreMIDI device change notifications:
use coremidi::{Client, Notifications};
// Register for device change notifications
client.notifications().subscribe(|notification| {
match notification {
Notifications::SetupChanged => {
// Trigger device list refresh
refresh_device_list();
}
_ => {}
}
});Pros:
- ✅ Real-time device detection (no polling needed)
- ✅ Most efficient solution
- ✅ Best user experience
Cons:
- ❌ Significant implementation effort
- ❌ Requires event bus/callback architecture
- ❌ More complex testing
Recommendation
Implement Option 2 (Hybrid Approach) as it provides:
- Significant UX improvement with moderate effort
- Clean separation of concerns
- Maintains cross-platform support
- Leverages existing dependencies
Option 3 can be implemented later if polling-based refresh proves insufficient.
Implementation Checklist
- Add platform-specific device enumeration using
coremidion macOS - Keep
midirfor cross-platform fallback and MIDI I/O - Update
list_midi_devicescommand with conditional compilation - Test hot-plug detection on macOS
- Test cross-platform fallback on Linux/Windows
- Update auto-refresh to work with new enumeration
- Document platform-specific behavior
- Update MINOR_ISSUES_FIXED.md with final solution
Related Files
midimon-gui/src-tauri/src/commands.rs:357-408- Current device enumerationmidimon-gui/ui/src/lib/components/DeviceList.svelte- UI componentmidimon-gui/ui/src/lib/stores.js:168-176- Auto-refresh logicCargo.toml:73-coremidiworkspace dependency (already available)
References
- midir Issue #78 - hotplug support with CoreMIDI?
- coremidi crate documentation
- Apple CoreMIDI Framework
Labels: enhancement, macos, midi, good first issue (for Option 1), help wanted (for Option 2/3)