1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-09 23:34:20 +00:00

XEmbedComponent: Add new constructor taking XEmbedComponentOptions

This commit is contained in:
attila 2026-01-08 00:02:50 +01:00 committed by Attila Szarvas
parent 833b8c329f
commit fde2512f64
4 changed files with 88 additions and 23 deletions

View file

@ -563,7 +563,8 @@ private:
NSViewComponentWithParent embeddedComponent;
using HandleFormat = NSView*;
#elif JUCE_LINUX || JUCE_BSD
XEmbedComponent embeddedComponent { true, false };
XEmbedComponent embeddedComponent { XEmbedComponentOptions{}.withWantsKeyboardFocus (true)
.withAllowForeignWidgetToResizeComponent (false) };
using HandleFormat = Window;
#else
Component embeddedComponent;

View file

@ -728,7 +728,9 @@ private:
::Display* display = XWindowSystem::getInstance()->getDisplay();
Window pluginWindow = 0;
DesktopComponent desktopComponent;
XEmbedComponent xembedComponent { reinterpret_cast<Window> (desktopComponent.getPeer()->getNativeHandle()), true, false };
XEmbedComponent xembedComponent { XEmbedComponentOptions{}.withClientWindow (reinterpret_cast<Window> (desktopComponent.getPeer()->getNativeHandle()))
.withWantsKeyboardFocus (true)
.withAllowForeignWidgetToResizeComponent (false) };
#endif
#else
static constexpr auto nativeScaleFactor = 1.0f;

View file

@ -42,6 +42,57 @@ unsigned long juce_getCurrentFocusWindow (ComponentPeer*);
#if JUCE_LINUX || JUCE_BSD || DOXYGEN
/** Options for constructing an XEmbedComponent.
@see XEmbedComponent
*/
class JUCE_API XEmbedComponentOptions
{
public:
/** Returns a copy of these options with the client window id specified. This corresponds to
the client initiated embedding workflow.
Omitting this option corresponds to the host initiated embedding workflow.
*/
[[nodiscard]] XEmbedComponentOptions withClientWindow (unsigned long x) const
{
jassert (x != 0);
return withMember (*this, &XEmbedComponentOptions::clientWindow, x);
}
/** Specifies that this Component wants to receive and forward keyboard focus.
The default value is true.
*/
[[nodiscard]] XEmbedComponentOptions withWantsKeyboardFocus (bool x) const
{
return withMember (*this, &XEmbedComponentOptions::wantsKeyboardFocus, x);
}
/** Specifies that the embedded window is allowed to resize the Component.
The default value is false.
*/
[[nodiscard]] XEmbedComponentOptions withAllowForeignWidgetToResizeComponent (bool x = true) const
{
return withMember (*this, &XEmbedComponentOptions::allowForeignWidgetToResizeComponent, x);
}
/** @see withClientWindow() */
[[nodiscard]] auto getClientWindow() const { return clientWindow; }
/** @see withWantsKeyboardFocus() */
[[nodiscard]] bool getWantsKeyboardFocus() const { return wantsKeyboardFocus; }
/** @see withAllowForeignWidgetToResizeComponent() */
[[nodiscard]] bool getAllowForeignWidgetToResizeComponent() const { return allowForeignWidgetToResizeComponent; }
private:
unsigned long clientWindow{};
bool wantsKeyboardFocus = true;
bool allowForeignWidgetToResizeComponent = false;
};
//==============================================================================
/**
A Linux-specific class that can embed a foreign X11 widget.
@ -75,6 +126,12 @@ class XEmbedComponent : public Component
{
public:
//==============================================================================
/** Creates a JUCE component wrapping a foreign widget.
Depending on the options passed, this constructor can be used for either
the host initiated or client initiated version of the XEmbedProtocol.
*/
explicit XEmbedComponent (const XEmbedComponentOptions& options);
/** Creates a JUCE component wrapping a foreign widget

View file

@ -143,23 +143,20 @@ public:
public:
//==============================================================================
Pimpl (XEmbedComponent& parent, Window x11Window,
bool wantsKeyboardFocus, bool isClientInitiated, bool shouldAllowResize)
Pimpl (XEmbedComponent& parent, const XEmbedComponentOptions& optionsIn)
: owner (parent),
infoAtom (XWindowSystem::getInstance()->getAtoms().XembedInfo),
messageTypeAtom (XWindowSystem::getInstance()->getAtoms().XembedMsgType),
clientInitiated (isClientInitiated),
wantsFocus (wantsKeyboardFocus),
allowResize (shouldAllowResize)
options (optionsIn)
{
getWidgets().add (this);
createHostWindow();
if (clientInitiated)
if (auto x11Window = options.getClientWindow(); x11Window != 0)
setClient (x11Window, true);
owner.setWantsKeyboardFocus (wantsFocus);
owner.setWantsKeyboardFocus (options.getWantsKeyboardFocus());
owner.addComponentListener (this);
}
@ -203,7 +200,7 @@ public:
// if the client has initiated the component then keep the clients size
// otherwise the client should use the host's window' size
if (clientInitiated)
if (options.getClientWindow() != 0)
{
configureNotify();
}
@ -236,7 +233,7 @@ public:
void focusGained (FocusChangeType changeType, FocusChangeDirection direction)
{
if (client != 0 && supportsXembed && wantsFocus)
if (client != 0 && supportsXembed && options.getWantsKeyboardFocus())
{
updateKeyFocus();
@ -258,7 +255,7 @@ public:
void focusLost (FocusChangeType)
{
if (client != 0 && supportsXembed && wantsFocus)
if (client != 0 && supportsXembed && options.getWantsKeyboardFocus())
{
sendXEmbedEvent (CurrentTime, XEMBED_FOCUS_OUT);
updateKeyFocus();
@ -276,7 +273,7 @@ public:
// You are using the client initiated version of the protocol. You cannot
// retrieve the window id of the host. Please read the documentation for
// the XEmebedComponent class.
jassert (! clientInitiated);
jassert (options.getClientWindow() == 0);
return host;
}
@ -354,9 +351,8 @@ private:
WindowMapper clientMapper { *this, client }, hostMapper { *this, host };
Atom infoAtom, messageTypeAtom;
bool clientInitiated;
bool wantsFocus = false;
bool allowResize = false;
XEmbedComponentOptions options;
bool supportsXembed = false;
int xembedVersion = maxXEmbedVersionToSupport;
@ -557,7 +553,7 @@ private:
if (newPeer != nullptr)
{
if (wantsFocus)
if (options.getWantsKeyboardFocus())
{
keyWindow = SharedKeyWindow::getKeyWindowForPeer (newPeer);
updateKeyFocus();
@ -583,6 +579,8 @@ private:
if (auto* peer = owner.getPeer())
peer->getCurrentModifiersRealtime();
const auto wantsFocus = options.getWantsKeyboardFocus();
switch (opcode)
{
case XEMBED_REQUEST_FOCUS:
@ -616,7 +614,7 @@ private:
return true;
case ConfigureNotify:
if (allowResize)
if (options.getAllowForeignWidgetToResizeComponent())
configureNotify();
else
MessageManager::callAsync ([this] { componentMovedOrResized (owner, true, true); });
@ -747,16 +745,23 @@ private:
};
//==============================================================================
XEmbedComponent::XEmbedComponent (bool wantsKeyboardFocus, bool allowForeignWidgetToResizeComponent)
: pimpl (new Pimpl (*this, 0, wantsKeyboardFocus, false, allowForeignWidgetToResizeComponent))
XEmbedComponent::XEmbedComponent (const XEmbedComponentOptions& options)
: pimpl (new Pimpl (*this, options))
{
setOpaque (true);
}
XEmbedComponent::XEmbedComponent (unsigned long wID, bool wantsKeyboardFocus, bool allowForeignWidgetToResizeComponent)
: pimpl (new Pimpl (*this, wID, wantsKeyboardFocus, true, allowForeignWidgetToResizeComponent))
XEmbedComponent::XEmbedComponent (bool wantsKeyboardFocus, bool allowForeignWidgetToResizeComponent)
: XEmbedComponent { XEmbedComponentOptions{}.withWantsKeyboardFocus (wantsKeyboardFocus)
.withAllowForeignWidgetToResizeComponent (allowForeignWidgetToResizeComponent) }
{
}
XEmbedComponent::XEmbedComponent (unsigned long wID, bool wantsKeyboardFocus, bool allowForeignWidgetToResizeComponent)
: XEmbedComponent { XEmbedComponentOptions{}.withClientWindow (wID)
.withWantsKeyboardFocus (wantsKeyboardFocus)
.withAllowForeignWidgetToResizeComponent (allowForeignWidgetToResizeComponent) }
{
setOpaque (true);
}
XEmbedComponent::~XEmbedComponent() {}