diff --git a/Cargo.lock b/Cargo.lock index e0d1c72d..b5139d39 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -400,14 +400,14 @@ dependencies = [ [[package]] name = "baseview" version = "0.1.0" -source = "git+https://github.com/RustAudio/baseview.git?rev=1d9806d#1d9806d5bd92275d0d8142d9c9c90198757b9b25" +source = "git+https://github.com/RustAudio/baseview.git?rev=2c1b1a7#2c1b1a7b0fef1a29a5150a6a8f6fef6a0cbab8c4" dependencies = [ "cocoa", "core-foundation", "keyboard-types", "nix 0.22.3", "objc", - "raw-window-handle 0.4.3", + "raw-window-handle", "uuid", "winapi", "x11", @@ -896,12 +896,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "cty" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35" - [[package]] name = "d3d12" version = "0.6.0" @@ -1643,7 +1637,7 @@ dependencies = [ [[package]] name = "iced_baseview" version = "0.0.3" -source = "git+https://github.com/BillyDM/iced_baseview.git?rev=9506c90#9506c90c15f53a9ff72eb775e6a9d85a82b0bba4" +source = "git+https://github.com/greatest-ape/iced_baseview.git?rev=055d88f#055d88f4f4e4eb601b1323ebc89ffed33293867a" dependencies = [ "baseview", "cfg-if", @@ -1656,8 +1650,7 @@ dependencies = [ "iced_wgpu", "keyboard-types", "log", - "raw-window-handle 0.4.3", - "raw-window-handle 0.5.2", + "raw-window-handle", "thiserror", ] @@ -1713,7 +1706,7 @@ dependencies = [ "iced_style", "log", "lyon", - "raw-window-handle 0.5.2", + "raw-window-handle", "thiserror", ] @@ -1759,7 +1752,7 @@ dependencies = [ "iced_graphics", "iced_native", "log", - "raw-window-handle 0.5.2", + "raw-window-handle", "wgpu", "wgpu_glyph", ] @@ -2328,8 +2321,7 @@ dependencies = [ "palette", "parking_lot 0.12.1", "quickcheck", - "raw-window-handle 0.4.3", - "raw-window-handle 0.5.2", + "raw-window-handle", "rfd", "ringbuf", "seahash", @@ -2735,15 +2727,6 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8a99fddc9f0ba0a85884b8d14e3592853e787d581ca1816c91349b10e4eeab" -[[package]] -name = "raw-window-handle" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41" -dependencies = [ - "cty", -] - [[package]] name = "raw-window-handle" version = "0.5.2" @@ -2862,7 +2845,7 @@ dependencies = [ "objc-foundation", "objc_id", "pollster", - "raw-window-handle 0.5.2", + "raw-window-handle", "urlencoding", "wasm-bindgen", "wasm-bindgen-futures", @@ -3759,7 +3742,7 @@ dependencies = [ "naga", "parking_lot 0.12.1", "profiling", - "raw-window-handle 0.5.2", + "raw-window-handle", "smallvec", "static_assertions", "wasm-bindgen", @@ -3785,7 +3768,7 @@ dependencies = [ "naga", "parking_lot 0.12.1", "profiling", - "raw-window-handle 0.5.2", + "raw-window-handle", "smallvec", "thiserror", "web-sys", @@ -3825,7 +3808,7 @@ dependencies = [ "parking_lot 0.12.1", "profiling", "range-alloc", - "raw-window-handle 0.5.2", + "raw-window-handle", "renderdoc-sys", "smallvec", "thiserror", diff --git a/octasine/Cargo.toml b/octasine/Cargo.toml index b6b61d25..cb467c71 100644 --- a/octasine/Cargo.toml +++ b/octasine/Cargo.toml @@ -10,13 +10,13 @@ default = ["glow"] # Enable clap plugin support clap = ["atomic_refcell", "bytemuck", "clap-sys", "parking_lot"] # Enable VST2 plugin support -vst2 = ["vst"] +vst2 = ["vst", "parking_lot"] # Use glow (OpenGL) for graphics glow = ["gui", "iced_baseview/glow", "iced_audio/glow"] # Use wgpu for graphics wgpu = ["gui", "iced_baseview/wgpu", "iced_audio/wgpu"] # Internal use only -gui = ["iced_baseview/canvas", "iced_audio", "iced_aw", "palette", "rwh04", "rwh05", "rfd", "tinyfiledialogs"] +gui = ["iced_baseview/canvas", "iced_audio", "iced_aw", "palette", "raw-window-handle", "rfd", "tinyfiledialogs"] [lib] name = "octasine" @@ -70,6 +70,8 @@ vst = { version = "0.4", optional = true } atomic_refcell = { version = "0.1", optional = true } bytemuck = { version = "1", optional = true } clap-sys = { version = "0.3", optional = true } + +# vst2 / clap parking_lot = { version = "0.12", optional = true } # GUI @@ -78,13 +80,12 @@ iced_audio = { version = "0.12", default-features = false, optional = true } iced_aw = { version = "0.5", features = ["modal", "card"], optional = true } palette = { version = "0.6", optional = true } rfd = { version = "0.11", optional = true, default-features = false, features = ["xdg-portal"] } -rwh04 = { package = "raw-window-handle", version = "0.4", optional = true } -rwh05 = { package = "raw-window-handle", version = "0.5", optional = true } +raw-window-handle = { version = "0.5", optional = true } tinyfiledialogs = { version = "3", optional = true } [dependencies.iced_baseview] -git = "https://github.com/BillyDM/iced_baseview.git" -rev = "9506c90" +git = "https://github.com/greatest-ape/iced_baseview.git" +rev = "055d88f" # branch octasine-0.9 default-features = false features = ["canvas"] optional = true diff --git a/octasine/src/audio/gen/mod.rs b/octasine/src/audio/gen/mod.rs index 5db71146..9e2b10b5 100644 --- a/octasine/src/audio/gen/mod.rs +++ b/octasine/src/audio/gen/mod.rs @@ -64,7 +64,6 @@ impl Default for VoiceData { Self { voice_index: 0, key_velocity: [0.0; W], - /// Master volume is calculated per-voice, since it can be an LFO target master_volume: [0.0; W], operators: Default::default(), } diff --git a/octasine/src/gui/mod.rs b/octasine/src/gui/mod.rs index d4d3ebe2..e3f74ccb 100644 --- a/octasine/src/gui/mod.rs +++ b/octasine/src/gui/mod.rs @@ -1055,7 +1055,7 @@ pub fn get_iced_baseview_settings( } #[cfg(target_os = "macos")] -struct CurrentWindowHandle(rwh05::RawWindowHandle); +struct CurrentWindowHandle(raw_window_handle::RawWindowHandle); #[cfg(target_os = "macos")] impl CurrentWindowHandle { @@ -1078,19 +1078,19 @@ impl CurrentWindowHandle { return None; } - let mut handle = rwh05::AppKitWindowHandle::empty(); + let mut handle = raw_window_handle::AppKitWindowHandle::empty(); handle.ns_window = ns_window as *mut core::ffi::c_void; handle.ns_view = ns_view as *mut core::ffi::c_void; - Some(Self(rwh05::RawWindowHandle::AppKit(handle))) + Some(Self(raw_window_handle::RawWindowHandle::AppKit(handle))) } } } #[cfg(target_os = "macos")] -unsafe impl rwh05::HasRawWindowHandle for CurrentWindowHandle { - fn raw_window_handle(&self) -> rwh05::RawWindowHandle { +unsafe impl raw_window_handle::HasRawWindowHandle for CurrentWindowHandle { + fn raw_window_handle(&self) -> raw_window_handle::RawWindowHandle { self.0 } } diff --git a/octasine/src/plugin/clap/ext/gui.rs b/octasine/src/plugin/clap/ext/gui.rs index bae6dd1f..d5a027d4 100644 --- a/octasine/src/plugin/clap/ext/gui.rs +++ b/octasine/src/plugin/clap/ext/gui.rs @@ -8,7 +8,7 @@ use clap_sys::{ ext::gui::{clap_gui_resize_hints, clap_plugin_gui, clap_window}, plugin::clap_plugin, }; -use rwh04::{HasRawWindowHandle, RawWindowHandle}; +use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; use crate::{ gui::{get_iced_baseview_settings, OctaSineIcedApplication, GUI_HEIGHT, GUI_WIDTH}, @@ -95,7 +95,6 @@ unsafe extern "C" fn adjust_size( false } -#[cfg(not(target_os = "macos"))] unsafe extern "C" fn set_size(_plugin: *const clap_plugin, _width: u32, _height: u32) -> bool { false } @@ -155,13 +154,6 @@ pub const CONFIG: clap_plugin_gui = clap_plugin_gui { can_resize: Some(can_resize), get_resize_hints: Some(get_resize_hints), adjust_size: Some(adjust_size), - // Hack to disable Bitwig GUI support on macOS until issues with - // cleaning up resources when destroying window are resolved. - // REAPER currently doesn't care if this field is a null pointer, - // while Bitwig disables GUI support if it is. - #[cfg(target_os = "macos")] - set_size: None, - #[cfg(not(target_os = "macos"))] set_size: Some(set_size), set_parent: Some(set_parent), set_transient: Some(set_transient), @@ -175,7 +167,7 @@ pub struct ParentWindow(clap_window); unsafe impl HasRawWindowHandle for ParentWindow { #[cfg(target_os = "macos")] fn raw_window_handle(&self) -> RawWindowHandle { - let mut handle = rwh04::AppKitHandle::empty(); + let mut handle = raw_window_handle::AppKitWindowHandle::empty(); unsafe { handle.ns_view = self.0.specific.cocoa; @@ -186,7 +178,7 @@ unsafe impl HasRawWindowHandle for ParentWindow { #[cfg(target_os = "windows")] fn raw_window_handle(&self) -> RawWindowHandle { - let mut handle = rwh04::Win32Handle::empty(); + let mut handle = raw_window_handle::Win32WindowHandle::empty(); unsafe { handle.hwnd = self.0.specific.win32; @@ -197,7 +189,7 @@ unsafe impl HasRawWindowHandle for ParentWindow { #[cfg(target_os = "linux")] fn raw_window_handle(&self) -> RawWindowHandle { - let mut handle = rwh04::XcbHandle::empty(); + let mut handle = raw_window_handle::XcbWindowHandle::empty(); unsafe { handle.window = self.0.specific.x11 as u32; diff --git a/octasine/src/plugin/vst2/editor.rs b/octasine/src/plugin/vst2/editor.rs index a7052cd0..1368cf39 100644 --- a/octasine/src/plugin/vst2/editor.rs +++ b/octasine/src/plugin/vst2/editor.rs @@ -1,8 +1,11 @@ -use iced_baseview::{open_blocking, open_parented}; -use rwh04::{HasRawWindowHandle, RawWindowHandle}; +use std::sync::Arc; + +use iced_baseview::{open_blocking, open_parented, window::WindowHandle}; +use parking_lot::Mutex; +use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; use crate::{ - gui::{get_iced_baseview_settings, GUI_HEIGHT, GUI_WIDTH}, + gui::{get_iced_baseview_settings, Message, GUI_HEIGHT, GUI_WIDTH}, plugin::vst2::PLUGIN_SEMVER_NAME, sync::GuiSyncHandle, }; @@ -11,24 +14,17 @@ use crate::gui::OctaSineIcedApplication; pub struct Editor { sync_state: H, - opened: bool, + window_handle: Option, } impl Editor { pub fn new(sync_state: H) -> Self { Self { sync_state, - opened: false, + window_handle: None, } } - pub fn open_parented(parent: ParentWindow, sync_handle: H) { - open_parented::, ParentWindow>( - &parent, - get_iced_baseview_settings(sync_handle, PLUGIN_SEMVER_NAME.to_string()), - ); - } - pub fn open_blocking(sync_handle: H) { open_blocking::>(get_iced_baseview_settings( sync_handle, @@ -47,30 +43,58 @@ impl vst::editor::Editor for Editor { } fn open(&mut self, parent: *mut ::core::ffi::c_void) -> bool { - if self.opened { + if self.window_handle.is_some() { return false; } - Self::open_parented(ParentWindow(parent), self.sync_state.clone()); + let window_handle = open_parented::, ParentWindow>( + &ParentWindow(parent), + get_iced_baseview_settings(self.sync_state.clone(), PLUGIN_SEMVER_NAME.to_string()), + ); + + self.window_handle = Some(WindowHandleWrapper::new(window_handle)); true } fn close(&mut self) { - self.opened = false; + if let Some(window_handle) = self.window_handle.take() { + window_handle.close(); + } } fn is_open(&mut self) -> bool { - self.opened + self.window_handle.is_some() } } +struct WindowHandleWrapper(Arc>>); + +impl WindowHandleWrapper { + fn new(window_handle: WindowHandle) -> Self { + Self(Arc::new(Mutex::new(window_handle))) + } + + fn close(&self) { + self.0.lock().close_window(); + } +} + +// Partly dubious workaround for Send requirement on vst::Plugin and the (new) +// baseview api contract requiring explicitly telling window to close. +// +// This is essentially a way of avoiding reimplementing vst2 support on top of +// vst2-sys. It should be noted that WindowHandleWrapper.close() is only called +// from a method that has mutable access to the editor object, e.g., Rust vst +// API authors assume it will only be called by the correct thread. +unsafe impl Send for WindowHandleWrapper {} + pub struct ParentWindow(pub *mut ::core::ffi::c_void); unsafe impl HasRawWindowHandle for ParentWindow { #[cfg(target_os = "macos")] fn raw_window_handle(&self) -> RawWindowHandle { - let mut handle = rwh04::AppKitHandle::empty(); + let mut handle = raw_window_handle::AppKitWindowHandle::empty(); handle.ns_view = self.0; @@ -79,7 +103,7 @@ unsafe impl HasRawWindowHandle for ParentWindow { #[cfg(target_os = "windows")] fn raw_window_handle(&self) -> RawWindowHandle { - let mut handle = rwh04::Win32Handle::empty(); + let mut handle = raw_window_handle::Win32WindowHandle::empty(); handle.hwnd = self.0; @@ -88,7 +112,7 @@ unsafe impl HasRawWindowHandle for ParentWindow { #[cfg(target_os = "linux")] fn raw_window_handle(&self) -> RawWindowHandle { - let mut handle = rwh04::XcbHandle::empty(); + let mut handle = raw_window_handle::XcbWindowHandle::empty(); handle.window = self.0 as u32;