diff --git a/src/wrapper/vst3/view.rs b/src/wrapper/vst3/view.rs index 69ba7127..3d29d452 100644 --- a/src/wrapper/vst3/view.rs +++ b/src/wrapper/vst3/view.rs @@ -6,9 +6,9 @@ use std::ffi::{c_void, CStr}; use std::mem; use std::sync::atomic::Ordering; use std::sync::Arc; -use vst3_com::utils::SharedVstPtr; use vst3_sys::base::{kInvalidArgument, kResultFalse, kResultOk, tresult, TBool}; use vst3_sys::gui::{IPlugFrame, IPlugView, IPlugViewContentScaleSupport, ViewRect}; +use vst3_sys::utils::SharedVstPtr; use vst3_sys::VST3; use super::inner::WrapperInner; @@ -21,7 +21,7 @@ use vst3_sys as vst3_com; // Thanks for putting this behind a platform-specific ifdef... // NOTE: This should also be used on the BSDs, but vst3-sys exposes these interfaces only for Linux #[cfg(all(target_os = "linux"))] -use vst3_sys::gui::linux::IRunLoop; +use vst3_sys::gui::linux::{FileDescriptor, IEventHandler, IRunLoop}; // Window handle type constants missing from vst3-sys #[allow(unused)] @@ -45,8 +45,11 @@ pub(crate) struct WrapperView { /// The `IPlugFrame` instance passed by the host during [IPlugView::set_frame()]. plug_frame: RwLock>>, + /// Allows handling events events on the host's GUI thread when using Linux. Needed because + /// otherwise REAPER doesn't like us very much. The event handler could be implemented directly + /// on this object but vst3-sys does not let us conditionally implement interfaces. #[cfg(all(target_os = "linux"))] - run_loop: RwLock>>, + run_loop_event_handler: RwLock>>, /// The DPI scaling factor as passed to the [IPlugViewContentScaleSupport::set_scale_factor()] /// function. Defaults to 1.0, and will be kept there on macOS. When reporting and handling size @@ -55,6 +58,14 @@ pub(crate) struct WrapperView { scaling_factor: AtomicF32, } +// This doesn't need to be a separate struct, but vst3-sys does not let us implement interfaces +// conditionally and the interface is only exposed when compiling on Linux +#[cfg(all(target_os = "linux"))] +#[VST3(implements(IEventHandler))] +struct RunLoopEventHandler { + run_loop: VstPtr, +} + impl WrapperView

{ pub fn new(inner: Arc>, editor: Arc) -> Box { Self::allocate( @@ -277,14 +288,16 @@ impl IPlugView for WrapperView

{ // host's GUI thread. REAPER will segfault when we don't do this for resizes. #[cfg(all(target_os = "linux"))] { - *self.run_loop.write() = frame.cast().map(VstPtr::from); + *self.run_loop_event_handler.write() = frame + .cast() + .map(|run_loop| RunLoopEventHandler::allocate(VstPtr::from(run_loop))); } *self.plug_frame.write() = Some(VstPtr::from(frame)); } None => { #[cfg(all(target_os = "linux"))] { - *self.run_loop.write() = None; + *self.run_loop_event_handler.write() = None; } *self.plug_frame.write() = None; } @@ -326,3 +339,10 @@ impl IPlugViewContentScaleSupport for WrapperView

{ } } } + +#[cfg(all(target_os = "linux"))] +impl IEventHandler for RunLoopEventHandler { + unsafe fn on_fd_is_set(&self, fd: FileDescriptor) { + todo!() + } +}