diff --git a/crates/vst3-host/src/ffi.rs b/crates/vst3-host/src/ffi.rs index f27ea390..38fa41dc 100644 --- a/crates/vst3-host/src/ffi.rs +++ b/crates/vst3-host/src/ffi.rs @@ -1749,7 +1749,7 @@ impl EditorLink { mod window { use objc2::rc::Retained; use objc2::{MainThreadMarker, MainThreadOnly}; - use objc2_app_kit::{NSApplication, NSBackingStoreType, NSFloatingWindowLevel, NSWindow, NSWindowStyleMask}; + use objc2_app_kit::{NSApplication, NSBackingStoreType, NSFloatingWindowLevel, NSWindow, NSWindowCollectionBehavior, NSWindowStyleMask}; use objc2_foundation::{NSPoint, NSRect, NSSize, NSString}; use std::ffi::{c_char, c_void}; @@ -1780,7 +1780,10 @@ mod window { let mtm = MainThreadMarker::new().ok_or_else(|| "not on the main thread".to_string())?; let _app = NSApplication::sharedApplication(mtm); let rect = NSRect::new(NSPoint::new(200.0, 200.0), NSSize::new(w, h)); - let style = NSWindowStyleMask::Titled | NSWindowStyleMask::Closable | NSWindowStyleMask::Miniaturizable; + // Plugin editors are transient utility windows. In particular they must not be + // minimizable: minimized NSWindows become persistent thumbnails in the macOS Dock, + // which made every editor visited in a session look like another running app. + let style = NSWindowStyleMask::Titled | NSWindowStyleMask::Closable | NSWindowStyleMask::UtilityWindow; // SAFETY: a freshly allocated window on the main thread; valid rect and style. let window = unsafe { NSWindow::initWithContentRect_styleMask_backing_defer(NSWindow::alloc(mtm), rect, style, NSBackingStoreType::Buffered, false) @@ -1791,6 +1794,8 @@ mod window { window.setTitle(&NSString::from_str(title)); window.setLevel(NSFloatingWindowLevel); window.setHidesOnDeactivate(true); + window.setExcludedFromWindowsMenu(true); + window.setCollectionBehavior(NSWindowCollectionBehavior::Transient | NSWindowCollectionBehavior::IgnoresCycle); window.center(); Ok(HostWindow { window: Retained::into_raw(window) }) }