From 79caa401d48142ba1e20522d364fbbf77baa1fde Mon Sep 17 00:00:00 2001 From: Paul Walker Date: Tue, 30 Jun 2020 14:46:27 -0400 Subject: [PATCH] Handle linux Hover and Hangup events the FDI based VST3 event loop would hang up, so kick it on the idle. Comment inline in source with more details Closes #1817 --- src/common/gui/SurgeGUIEditor.cpp | 17 ++++++++++---- src/linux/LinuxVST3Helpers.cpp | 38 +++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/common/gui/SurgeGUIEditor.cpp b/src/common/gui/SurgeGUIEditor.cpp index 7030aa43352..82004c4f914 100644 --- a/src/common/gui/SurgeGUIEditor.cpp +++ b/src/common/gui/SurgeGUIEditor.cpp @@ -41,6 +41,7 @@ #include "vstgui/lib/cvstguitimer.h" + template< typename T > struct RememberForgetGuard { RememberForgetGuard( T *tg ) @@ -100,6 +101,13 @@ const int yofs = 10; using namespace VSTGUI; using namespace std; +#if LINUX && TARGET_VST3 +extern void LinuxVST3Init(Steinberg::Linux::IRunLoop* pf); +extern void LinuxVST3Detatch(); +extern void LinuxVST3FrameOpen(CFrame* that, void*, const VSTGUI::PlatformType& pt); +extern void LinuxVST3Idle(); +#endif + CFontRef displayFont = NULL; CFontRef patchNameFont = NULL; CFontRef lfoTypeFont = NULL; @@ -358,6 +366,10 @@ void SurgeGUIEditor::idle() if (!super::idle2()) return; #endif +#if TARGET_VST3 && LINUX + LinuxVST3Idle(); +#endif + if (!synth) return; if (editor_open && frame && !synth->halt_engine) @@ -2109,11 +2121,6 @@ VSTGUI::CControl *SurgeGUIEditor::layoutTagWithSkin( int tag ) return nullptr; } -#if LINUX && TARGET_VST3 -extern void LinuxVST3Init(Steinberg::Linux::IRunLoop* pf); -extern void LinuxVST3Detatch(); -extern void LinuxVST3FrameOpen(CFrame* that, void*, const VSTGUI::PlatformType& pt); -#endif #if !TARGET_VST3 bool SurgeGUIEditor::open(void* parent) diff --git a/src/linux/LinuxVST3Helpers.cpp b/src/linux/LinuxVST3Helpers.cpp index 032b3c80852..c12809a804d 100644 --- a/src/linux/LinuxVST3Helpers.cpp +++ b/src/linux/LinuxVST3Helpers.cpp @@ -13,6 +13,7 @@ using namespace VSTGUI; +static int ct = 0; // Map Steinberg Vst Interface (Steinberg::Linux::IRunLoop) to VSTGUI Interface // (VSTGUI::X11::RunLoop) class RunLoop : public X11::IRunLoop, public AtomicReferenceCounted @@ -24,7 +25,7 @@ class RunLoop : public X11::IRunLoop, public AtomicReferenceCounted void PLUGIN_API onFDIsSet(Steinberg::Linux::FileDescriptor) override { - // std::cout << __func__ << " " << handler << std::endl; + // std::cout << __func__ << " " << handler << " " << ct++ << std::endl; if (handler) handler->onEvent(); // std::cout << __func__ << " END " << handler << std::endl; @@ -120,6 +121,13 @@ class RunLoop : public X11::IRunLoop, public AtomicReferenceCounted // std::cout << "RunLoop is " << runLoop << " " << _runLoop << std::endl; } + void idle() + { + // See comment in LInuxVST3Idle below + for( auto h : eventHandlers ) + h->handler->onEvent(); + } + private: using EventHandlers = std::vector>; using TimerHandlers = std::vector>; @@ -156,7 +164,7 @@ class IdleUpdateHandler auto& instance = get(); if (++instance.users == 1) { - instance.running = true; + instance.running = true; pthread_create(&instance.t, NULL, IdleUpdateHandler::doDefUp, NULL); } } @@ -177,8 +185,8 @@ class IdleUpdateHandler auto& instance = get(); if (--instance.users == 0) { - instance.running = false; - pthread_join(instance.t, NULL); + instance.running = false; + pthread_join(instance.t, NULL); } } @@ -219,4 +227,26 @@ void LinuxVST3Detatch() // We need to downcount the usage on the RunLoop to allow xcb to restart VSTGUI::X11::RunLoop::exit(); } + +void LinuxVST3Idle() +{ + /* + ** Why is this here? With the VST3 runloop we should be + ** parsimoniously notified by file descriptor polls and stuff right? + ** Well, of course, that doesn't work. If you listen to every + ** hover event somewhere in the bowls of vst3sdk, DAW runloops, + ** and so forth, you eventually hang up and lose events. + ** So what this does is, every idle, just give a kick to every + ** FDI poller to go and check. Basically just like VST2. + ** + ** If you decide one day to eliminate this to optimize something + ** or another, make sure that in bitwig and the juce host that + ** as you mouse over hover assets they keep working forever and + ** don't hang up after 10-50 seconds. See #1817 + */ + auto xrlp = VSTGUI::X11::RunLoop::get().get(); + auto rlp = dynamic_cast(xrlp); + if( rlp ) + rlp->idle(); +} #endif