diff --git a/src/wrapper/vst3/context.rs b/src/wrapper/vst3/context.rs index 5ad1bacf..322f4d6b 100644 --- a/src/wrapper/vst3/context.rs +++ b/src/wrapper/vst3/context.rs @@ -30,10 +30,12 @@ pub(crate) struct WrapperProcessContext<'a, P: Vst3Plugin> { impl GuiContext for WrapperGuiContext

{ fn request_resize(&self) -> bool { - match &*self.inner.plug_view.read() { - Some(plug_view) => plug_view.request_resize(), - None => false, - } + let task_posted = self.inner.do_maybe_async(Task::RequestResize); + nih_debug_assert!(task_posted, "The task queue is full, dropping task..."); + + // TODO: We don't handle resize request failures right now. In practice this should however + // not happen. + true } // All of these functions are supposed to be called from the main thread, so we'll put some diff --git a/src/wrapper/vst3/inner.rs b/src/wrapper/vst3/inner.rs index 17048e51..fe91cc63 100644 --- a/src/wrapper/vst3/inner.rs +++ b/src/wrapper/vst3/inner.rs @@ -139,6 +139,9 @@ pub enum Task { /// Trigger a restart with the given restart flags. This is a bit set of the flags from /// [`vst3_sys::vst::RestartFlags`]. TriggerRestart(i32), + /// Request the editor to be resized according to its current size. Right now there is no way to + /// handle denied resize requestsyet. + RequestResize, } /// VST3 makes audio processing pretty complicated. In order to support both block splitting for @@ -479,6 +482,12 @@ impl MainThreadExecutor for WrapperInner

{ } None => nih_debug_assert_failure!("Component handler not yet set"), }, + Task::RequestResize => match &*self.plug_view.read() { + Some(plug_view) => { + plug_view.request_resize(); + } + None => nih_debug_assert_failure!("Can't resize a closed editor"), + }, } } } diff --git a/src/wrapper/vst3/view.rs b/src/wrapper/vst3/view.rs index da6402da..6d1d2bf8 100644 --- a/src/wrapper/vst3/view.rs +++ b/src/wrapper/vst3/view.rs @@ -107,8 +107,12 @@ impl WrapperView

{ } /// Ask the host to resize the view to the size specified by [Editor::size()]. Will return false - /// if the host doesn't like you. - pub fn request_resize(&self) -> bool { + /// if the host doesn't like you. This **needs** to be run from the GUI thread. + /// + /// # Safety + /// + /// May cause memory corruption in Linux REAPER when called from outside of the `IRunLoop`. + pub unsafe fn request_resize(&self) -> bool { // Don't do anything if the editor is not open, because that would be strange if self .editor_handle @@ -131,11 +135,8 @@ impl WrapperView

{ // The argument types are a bit wonky here because you can't construct a // `SharedVstPtr`. This _should_ work however. - // FIXME: Run this in the `IRonLoop` on Linux. Otherwise REAPER will be very cross - // with us. - let plug_view: SharedVstPtr = - unsafe { mem::transmute(self.__iplugviewvptr) }; - let result = unsafe { plug_frame.resize_view(plug_view, &mut size) }; + let plug_view: SharedVstPtr = mem::transmute(self.__iplugviewvptr); + let result = plug_frame.resize_view(plug_view, &mut size); result == kResultOk }