1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

VST2 Client: Hook onto host event loop when editor is open

This commit is contained in:
reuk 2022-03-07 19:49:06 +00:00
parent c91514f57f
commit e6efdaae0e
No known key found for this signature in database
GPG key ID: 9ADCD339CFC98A11

View file

@ -184,6 +184,35 @@ namespace
#endif
#if JUCE_LINUX || JUCE_BSD
class HostDrivenEventLoop
{
public:
HostDrivenEventLoop()
{
messageThread->stop();
MessageManager::getInstance()->setCurrentThreadAsMessageThread();
}
void processPendingEvents()
{
MessageManager::getInstance()->setCurrentThreadAsMessageThread();
for (;;)
if (! dispatchNextMessageOnSystemQueue (true))
return;
}
~HostDrivenEventLoop()
{
messageThread->start();
}
private:
SharedResourcePointer<MessageThread> messageThread;
};
#endif
//==============================================================================
// Ableton Live host specific commands
struct AbletonLiveHostSpecific
@ -961,6 +990,7 @@ public:
case Vst2::effSetProcessPrecision: return handleSetSampleFloatType (args);
case Vst2::effGetNumMidiInputChannels: return handleGetNumMidiInputChannels();
case Vst2::effGetNumMidiOutputChannels: return handleGetNumMidiOutputChannels();
case Vst2::effEditIdle: return handleEditIdle();
default: return 0;
}
}
@ -1103,6 +1133,7 @@ public:
void parentSizeChanged() override
{
updateWindowSize();
repaint();
}
void childBoundsChanged (Component*) override
@ -1127,41 +1158,11 @@ public:
return {};
}
void updateWindowSize()
void resizeHostWindow (juce::Rectangle<int> bounds)
{
if (! resizingParent
&& getEditorComp() != nullptr
&& hostWindow != HostWindowType{})
{
auto editorBounds = getSizeToContainChild();
resizeHostWindow (editorBounds.getWidth(), editorBounds.getHeight());
{
const ScopedValueSetter<bool> resizingParentSetter (resizingParent, true);
#if JUCE_LINUX || JUCE_BSD // setSize() on linux causes renoise and energyxt to fail.
auto rect = convertToHostBounds ({ 0, 0, (int16) editorBounds.getHeight(), (int16) editorBounds.getWidth() });
X11Symbols::getInstance()->xResizeWindow (display, (Window) getWindowHandle(),
static_cast<unsigned int> (rect.right - rect.left),
static_cast<unsigned int> (rect.bottom - rect.top));
#else
setSize (editorBounds.getWidth(), editorBounds.getHeight());
#endif
}
#if JUCE_MAC
resizeHostWindow (editorBounds.getWidth(), editorBounds.getHeight()); // (doing this a second time seems to be necessary in tracktion)
#endif
}
}
void resizeHostWindow (int newWidth, int newHeight)
{
auto rect = convertToHostBounds ({ 0, 0, (int16) newHeight, (int16) newWidth });
newWidth = rect.right - rect.left;
newHeight = rect.bottom - rect.top;
auto rect = convertToHostBounds ({ 0, 0, (int16) bounds.getHeight(), (int16) bounds.getWidth() });
const auto newWidth = rect.right - rect.left;
const auto newHeight = rect.bottom - rect.top;
bool sizeWasSuccessful = false;
@ -1233,6 +1234,12 @@ public:
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOOWNERZORDER);
#endif
}
#if JUCE_LINUX || JUCE_BSD
X11Symbols::getInstance()->xResizeWindow (display, (Window) getWindowHandle(),
static_cast<unsigned int> (rect.right - rect.left),
static_cast<unsigned int> (rect.bottom - rect.top));
#endif
}
void setContentScaleFactor (float scale)
@ -1294,6 +1301,34 @@ public:
#endif
private:
void updateWindowSize()
{
if (! resizingParent
&& getEditorComp() != nullptr
&& hostWindow != HostWindowType{})
{
const auto editorBounds = getSizeToContainChild();
resizeHostWindow (editorBounds);
{
const ScopedValueSetter<bool> resizingParentSetter (resizingParent, true);
// setSize() on linux causes renoise and energyxt to fail.
// We'll resize our peer during resizeHostWindow() instead.
#if ! (JUCE_LINUX || JUCE_BSD)
setSize (editorBounds.getWidth(), editorBounds.getHeight());
#endif
if (auto* p = getPeer())
p->updateBounds();
}
#if JUCE_MAC
resizeHostWindow (editorBounds); // (doing this a second time seems to be necessary in tracktion)
#endif
}
}
//==============================================================================
static Vst2::ERect convertToHostBounds (const Vst2::ERect& rect)
{
@ -1308,6 +1343,11 @@ public:
(int16) roundToInt (rect.right * desktopScale) };
}
//==============================================================================
#if JUCE_LINUX || JUCE_BSD
SharedResourcePointer<HostDrivenEventLoop> hostEventLoop;
#endif
//==============================================================================
JuceVSTWrapper& wrapper;
bool resizingChild = false, resizingParent = false;
@ -1616,7 +1656,11 @@ private:
pointer_sized_int handleGetEditorBounds (VstOpCodeArguments args)
{
checkWhetherMessageThreadIsCorrect();
#if JUCE_LINUX || JUCE_BSD
SharedResourcePointer<HostDrivenEventLoop> hostDrivenEventLoop;
#else
const MessageManagerLock mmLock;
#endif
createEditorComp();
if (editorComp != nullptr)
@ -1632,7 +1676,11 @@ private:
pointer_sized_int handleOpenEditor (VstOpCodeArguments args)
{
checkWhetherMessageThreadIsCorrect();
#if JUCE_LINUX || JUCE_BSD
SharedResourcePointer<HostDrivenEventLoop> hostDrivenEventLoop;
#else
const MessageManagerLock mmLock;
#endif
jassert (! recursionCheck);
startTimerHz (4); // performs misc housekeeping chores
@ -1652,8 +1700,15 @@ private:
pointer_sized_int handleCloseEditor (VstOpCodeArguments)
{
checkWhetherMessageThreadIsCorrect();
#if JUCE_LINUX || JUCE_BSD
SharedResourcePointer<HostDrivenEventLoop> hostDrivenEventLoop;
#else
const MessageManagerLock mmLock;
#endif
deleteEditor (true);
return 0;
}
@ -2011,7 +2066,11 @@ private:
pointer_sized_int handleSetContentScaleFactor (float scale)
{
checkWhetherMessageThreadIsCorrect();
#if JUCE_LINUX || JUCE_BSD
SharedResourcePointer<HostDrivenEventLoop> hostDrivenEventLoop;
#else
const MessageManagerLock mmLock;
#endif
#if ! JUCE_MAC
if (! approximatelyEqual (scale, editorScaleFactor))
@ -2076,6 +2135,16 @@ private:
#endif
}
pointer_sized_int handleEditIdle()
{
#if JUCE_LINUX || JUCE_BSD
SharedResourcePointer<HostDrivenEventLoop> hostDrivenEventLoop;
hostDrivenEventLoop->processPendingEvents();
#endif
return 0;
}
//==============================================================================
ScopedJuceInitialiser_GUI libraryInitialiser;
@ -2136,17 +2205,13 @@ namespace
ScopedJuceInitialiser_GUI libraryInitialiser;
#if JUCE_LINUX || JUCE_BSD
SharedResourcePointer<MessageThread> messageThread;
SharedResourcePointer<HostDrivenEventLoop> hostDrivenEventLoop;
#endif
try
{
if (audioMaster (nullptr, Vst2::audioMasterVersion, 0, 0, nullptr, 0) != 0)
{
#if JUCE_LINUX || JUCE_BSD
MessageManagerLock mmLock;
#endif
std::unique_ptr<AudioProcessor> processor { createPluginFilterOfType (AudioProcessor::wrapperType_VST) };
auto* processorPtr = processor.get();
auto* wrapper = new JuceVSTWrapper (audioMaster, std::move (processor));