Merge pull request #148 from grovebit/heal-shortcut

Cmd+H heals instead of hiding SoundCraft on macOS (#140)
This commit is contained in:
Brandon Thomas 2026-10-11 20:05:09 -04:00 committed by GitHub
commit 902220e4d4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 16 additions and 4 deletions

2
Cargo.lock generated
View File

@ -3418,6 +3418,8 @@ dependencies = [
"egui",
"log",
"muda",
"objc2 0.6.5",
"objc2-app-kit 0.3.2",
"rfd",
"serde_json",
"soundcraft-engine",

View File

@ -28,3 +28,5 @@ winresource = "0.1"
[target.'cfg(target_os = "macos")'.dependencies]
muda = { version = "0.19.2", default-features = false }
objc2 = "0.6"
objc2-app-kit = { version = "0.3", default-features = false, features = ["NSApplication", "NSResponder"] }

View File

@ -1,5 +1,7 @@
//! macOS system menu bar. All actions use the same menu dispatch as the egui host.
use muda::{CheckMenuItem, Menu, MenuEvent, PredefinedMenuItem, Submenu};
use muda::{CheckMenuItem, Menu, MenuEvent, MenuItem, PredefinedMenuItem, Submenu};
use objc2::MainThreadMarker;
use objc2_app_kit::NSApplication;
use soundcraft_ui_egui::{SoundApp, menus};
use std::sync::mpsc::{Receiver, channel};
@ -36,8 +38,9 @@ impl NativeMenu {
app_menu.append(&PredefinedMenuItem::separator())?;
app_menu.append(&PredefinedMenuItem::services(None))?;
app_menu.append(&PredefinedMenuItem::separator())?;
app_menu.append(&PredefinedMenuItem::hide(Some("Hide SoundCraft")))?;
app_menu.append(&PredefinedMenuItem::hide_others(None))?;
// muda's own Hide items take ⌘H and ⌥⌘H, which are Heal Separation and Copy to Send.
app_menu.append(&MenuItem::with_id("hide", "Hide SoundCraft", true, None))?;
app_menu.append(&MenuItem::with_id("hide_others", "Hide Others", true, None))?;
app_menu.append(&PredefinedMenuItem::show_all(None))?;
app_menu.append(&PredefinedMenuItem::separator())?;
native.add_item(app, &app_menu, "Quit SoundCraft", "", Some("app.quit".into()))?;
@ -82,7 +85,12 @@ impl NativeMenu {
while let Ok(event) = self.events.try_recv() {
// A click changes state (and Cocoa flips the item's check mark): sync on the next pass.
self.last_sync = None;
if let Some(entry) = self.entries.iter().find(|e| e.item.id() == &event.id)
if (event.id == "hide" || event.id == "hide_others")
&& let Some(mtm) = MainThreadMarker::new()
{
let ns = NSApplication::sharedApplication(mtm);
if event.id == "hide" { ns.hide(None) } else { ns.hideOtherApplications(None) }
} else if let Some(entry) = self.entries.iter().find(|e| e.item.id() == &event.id)
&& let Some(command) = &entry.command
&& menus::item_state(app, &entry.path, Some(command)).0
{