mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-01-10 23:44:24 +00:00
VST Host: Use a "wrapper" window on Linux so that the client does not have to be responsible for window position
Previously, on Linux, client plugin editors were embedded directly into the peer displaying the client's AudioProcessorEditor. Although this approach is simple and lightweight, it means that plugin editors are able to reposition themselves over controls in the parent window just by calling XMoveResizeWindow or similar on their own widget. It's more desirable that the client editor should be clipped if it attempts to draw outside the area of the AudioProcessorEditor.
This commit is contained in:
parent
cad3e2f054
commit
983cbdc441
1 changed files with 31 additions and 26 deletions
|
|
@ -42,8 +42,6 @@ namespace juce
|
|||
|
||||
#if JUCE_LINUX || JUCE_BSD
|
||||
|
||||
using EventProcPtr = void (*)(XEvent*);
|
||||
|
||||
static Window getChildWindow (Window windowToCheck)
|
||||
{
|
||||
Window rootWindow, parentWindow;
|
||||
|
|
@ -106,6 +104,8 @@ public:
|
|||
|
||||
#if JUCE_WINDOWS
|
||||
addAndMakeVisible (embeddedComponent);
|
||||
#elif JUCE_LINUX || JUCE_BSD
|
||||
addAndMakeVisible (xembedComponent);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -182,23 +182,7 @@ public:
|
|||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
#if JUCE_LINUX || JUCE_BSD
|
||||
if (isOpen)
|
||||
{
|
||||
if (pluginWindow != 0)
|
||||
{
|
||||
auto clip = componentToVstRect (*this, g.getClipBounds().toNearestInt());
|
||||
|
||||
X11Symbols::getInstance()->xClearArea (display, pluginWindow, clip.getX(), clip.getY(),
|
||||
static_cast<unsigned int> (clip.getWidth()),
|
||||
static_cast<unsigned int> (clip.getHeight()), True);
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
g.fillAll (Colours::black);
|
||||
}
|
||||
g.fillAll (Colours::black);
|
||||
}
|
||||
|
||||
void componentMovedOrResized (bool /*wasMoved*/, bool /*wasResized*/) override
|
||||
|
|
@ -213,17 +197,11 @@ public:
|
|||
#if JUCE_WINDOWS
|
||||
embeddedComponent.setBounds (getLocalBounds());
|
||||
#elif JUCE_LINUX || JUCE_BSD
|
||||
const auto pos = componentToVstRect (*this, getLocalBounds());
|
||||
xembedComponent.setBounds (getLocalBounds());
|
||||
|
||||
if (pluginWindow != 0)
|
||||
{
|
||||
auto* symbols = X11Symbols::getInstance();
|
||||
symbols->xMoveResizeWindow (display,
|
||||
pluginWindow,
|
||||
pos.getX(),
|
||||
pos.getY(),
|
||||
(unsigned int) pos.getWidth(),
|
||||
(unsigned int) pos.getHeight());
|
||||
symbols->xMapRaised (display, pluginWindow);
|
||||
symbols->xFlush (display);
|
||||
}
|
||||
|
|
@ -431,6 +409,8 @@ private:
|
|||
|
||||
#if JUCE_WINDOWS
|
||||
auto* handle = embeddedComponent.getHWND();
|
||||
#elif JUCE_LINUX || JUCE_BSD
|
||||
auto* handle = desktopComponent.getPeer()->getNativeHandle();
|
||||
#else
|
||||
auto* handle = getWindowHandle();
|
||||
#endif
|
||||
|
|
@ -722,8 +702,33 @@ private:
|
|||
void* originalWndProc = {};
|
||||
int sizeCheckCount = 0;
|
||||
#elif JUCE_LINUX || JUCE_BSD
|
||||
// This is to provide a consistent X11 window handle with the same lifetime as the
|
||||
// VSTPluginWindow. Using the VSTPluginWindow's peer directly would mean that the X11 window
|
||||
// handle could change if the same VST window instance is repeatedly added/removed from the
|
||||
// desktop.
|
||||
// We then XEmbed this stable window into the VSTPluginFormat, and also use the stable window
|
||||
// as the parent for the client VST window.
|
||||
// We're not XEmbedding the client VST window directly, because it's not clear that VST
|
||||
// hosts & clients expect to use the XEmbed protocol.
|
||||
class DesktopComponent : public Component
|
||||
{
|
||||
public:
|
||||
DesktopComponent()
|
||||
{
|
||||
setOpaque (true);
|
||||
addToDesktop (0);
|
||||
}
|
||||
|
||||
void paint (Graphics& g) override
|
||||
{
|
||||
g.fillAll (Colours::black);
|
||||
}
|
||||
};
|
||||
|
||||
::Display* display = XWindowSystem::getInstance()->getDisplay();
|
||||
Window pluginWindow = 0;
|
||||
DesktopComponent desktopComponent;
|
||||
XEmbedComponent xembedComponent { reinterpret_cast<Window> (desktopComponent.getPeer()->getNativeHandle()), true, false };
|
||||
#endif
|
||||
#else
|
||||
static constexpr auto nativeScaleFactor = 1.0f;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue