Skip to content

Commit

Permalink
Upgrade to latest baseview, fixing clap/Bitwig issues (#188)
Browse files Browse the repository at this point in the history
* WIP: upgrade baseview version

* WIP: update to latest baseview

* run cargo fmt

* clap: disable Bitwig GUI disabling hack
  • Loading branch information
greatest-ape authored Mar 17, 2024
1 parent f1a929f commit e1a2ba2
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 71 deletions.
39 changes: 11 additions & 28 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions octasine/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
1 change: 0 additions & 1 deletion octasine/src/audio/gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ impl<const W: usize> Default for VoiceData<W> {
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(),
}
Expand Down
10 changes: 5 additions & 5 deletions octasine/src/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1055,7 +1055,7 @@ pub fn get_iced_baseview_settings<H: GuiSyncHandle>(
}

#[cfg(target_os = "macos")]
struct CurrentWindowHandle(rwh05::RawWindowHandle);
struct CurrentWindowHandle(raw_window_handle::RawWindowHandle);

#[cfg(target_os = "macos")]
impl CurrentWindowHandle {
Expand All @@ -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
}
}
16 changes: 4 additions & 12 deletions octasine/src/plugin/clap/ext/gui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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),
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down
62 changes: 43 additions & 19 deletions octasine/src/plugin/vst2/editor.rs
Original file line number Diff line number Diff line change
@@ -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,
};
Expand All @@ -11,24 +14,17 @@ use crate::gui::OctaSineIcedApplication;

pub struct Editor<H: GuiSyncHandle> {
sync_state: H,
opened: bool,
window_handle: Option<WindowHandleWrapper>,
}

impl<H: GuiSyncHandle> Editor<H> {
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::<OctaSineIcedApplication<H>, ParentWindow>(
&parent,
get_iced_baseview_settings(sync_handle, PLUGIN_SEMVER_NAME.to_string()),
);
}

pub fn open_blocking(sync_handle: H) {
open_blocking::<OctaSineIcedApplication<H>>(get_iced_baseview_settings(
sync_handle,
Expand All @@ -47,30 +43,58 @@ impl<H: GuiSyncHandle> vst::editor::Editor for Editor<H> {
}

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::<OctaSineIcedApplication<H>, 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<Mutex<WindowHandle<Message>>>);

impl WindowHandleWrapper {
fn new(window_handle: WindowHandle<Message>) -> 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;

Expand All @@ -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;

Expand All @@ -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;

Expand Down

0 comments on commit e1a2ba2

Please sign in to comment.