76 keyProxy (juce_createKeyProxyWindow (keyPeer)),
83 juce_deleteKeyProxyWindow (keyProxy);
92 Window getHandle() {
return keyProxy; }
140 infoAtom (
XWindowSystem::getInstance()->getAtoms().XembedInfo),
141 messageTypeAtom (
XWindowSystem::getInstance()->getAtoms().XembedMsgType),
146 getWidgets().add (
this);
164 auto dpy = getDisplay();
166 X11Symbols::getInstance()->xDestroyWindow (
dpy, host);
167 X11Symbols::getInstance()->xSync (
dpy,
false);
175 while (X11Symbols::getInstance()->xCheckWindowEvent (
dpy, host, mask, &event) == True)
181 getWidgets().removeAllInstancesOf (
this);
191 auto dpy = getDisplay();
204 X11Symbols::getInstance()->xResizeWindow (
dpy, client,
static_cast<unsigned int> (
newBounds.getWidth()),
205 static_cast<unsigned int> (
newBounds.getHeight()));
211 X11Symbols::getInstance()->xGetWindowAttributes (
dpy, client, &
clientAttr);
216 getXEmbedMappedFlag();
219 X11Symbols::getInstance()->xReparentWindow (
dpy, client, host, 0, 0);
222 sendXEmbedEvent (
CurrentTime, XEMBED_EMBEDDED_NOTIFY, 0, (
long) host, xembedVersion);
230 if (client != 0 && supportsXembed && wantsFocus)
240 if (client != 0 && supportsXembed && wantsFocus)
247 void broughtToFront()
249 if (client != 0 && supportsXembed)
250 sendXEmbedEvent (
CurrentTime, XEMBED_WINDOW_ACTIVATE);
253 unsigned long getHostWindowID()
263 void updateEmbeddedBounds()
265 componentMovedOrResized (owner,
true,
true);
270 XEmbedComponent& owner;
271 Window client = 0, host = 0;
272 Atom infoAtom, messageTypeAtom;
274 bool clientInitiated;
275 bool wantsFocus =
false;
276 bool allowResize =
false;
277 bool supportsXembed =
false;
278 bool hasBeenMapped =
false;
279 int xembedVersion = maxXEmbedVersionToSupport;
281 ComponentPeer* lastPeer =
nullptr;
282 SharedKeyWindow::Ptr keyWindow;
285 void componentParentHierarchyChanged (
Component&)
override { peerChanged (owner.getPeer()); }
286 void componentMovedOrResized (
Component&,
bool,
bool)
override
288 if (host != 0 && lastPeer !=
nullptr)
290 auto dpy = getDisplay();
294 if (X11Symbols::getInstance()->xGetWindowAttributes (
dpy, host, &attr))
296 Rectangle<int> currentBounds (attr.x, attr.y, attr.width, attr.height);
300 static_cast<unsigned int> (
newBounds.getWidth()),
301 static_cast<unsigned int> (
newBounds.getHeight()));
305 if (client != 0 && X11Symbols::getInstance()->xGetWindowAttributes (
dpy, client, &attr))
307 Rectangle<int> currentBounds (attr.x, attr.y, attr.width, attr.height);
309 if ((currentBounds.getWidth() !=
newBounds.getWidth()
310 || currentBounds.getHeight() !=
newBounds.getHeight()))
312 X11Symbols::getInstance()->xMoveResizeWindow (
dpy, client, 0, 0,
313 static_cast<unsigned int> (
newBounds.getWidth()),
314 static_cast<unsigned int> (
newBounds.getHeight()));
321 void createHostWindow()
323 auto dpy = getDisplay();
328 swa.border_pixel = 0;
329 swa.background_pixmap = None;
330 swa.override_redirect = True;
333 host = X11Symbols::getInstance()->xCreateWindow (
dpy, root, 0, 0, 1, 1, 0,
CopyFromParent,
343 auto dpy = getDisplay();
344 X11Symbols::getInstance()->xSelectInput (
dpy, client, 0);
353 X11Symbols::getInstance()->xUnmapWindow (
dpy, client);
354 hasBeenMapped =
false;
357 X11Symbols::getInstance()->xReparentWindow (
dpy, client, root, 0, 0);
360 X11Symbols::getInstance()->xSync (
dpy, False);
375 X11Symbols::getInstance()->xMapWindow (getDisplay(), client);
377 X11Symbols::getInstance()->xUnmapWindow (getDisplay(), client);
382 Window getParentX11Window()
384 if (
auto* peer = owner.getPeer())
385 return reinterpret_cast<Window
> (peer->getNativeHandle());
390 Display* getDisplay() {
return XWindowSystem::getInstance()->getDisplay(); }
393 bool getXEmbedMappedFlag()
395 XWindowSystemUtilities::GetXProperty
embedInfo (getDisplay(), client, infoAtom, 0, 2,
false, infoAtom);
403 supportsXembed =
true;
404 xembedVersion =
jmin ((
int) maxXEmbedVersionToSupport, (
int) version);
409 return ((flags & XEMBED_MAPPED) != 0);
413 supportsXembed =
false;
414 xembedVersion = maxXEmbedVersionToSupport;
421 void propertyChanged (
const Atom& a)
427 void configureNotify()
430 auto dpy = getDisplay();
432 if (X11Symbols::getInstance()->xGetWindowAttributes (
dpy, client, &attr))
436 if (X11Symbols::getInstance()->xGetWindowAttributes (
dpy, host, &
hostAttr))
438 X11Symbols::getInstance()->xResizeWindow (
dpy, host, (
unsigned int) attr.width, (
unsigned int) attr.height);
443 auto* peer = owner.getPeer();
444 const double scale = (peer !=
nullptr ? peer->getPlatformScaleFactor()
445 : displays.getPrimaryDisplay()->scale);
448 = (peer !=
nullptr ? peer->getComponent().getLocalPoint (&owner, Point<int> (0, 0))
452 static_cast<int> (
static_cast<double> (attr.width) / scale),
453 static_cast<int> (
static_cast<double> (attr.height) / scale));
466 void peerChanged (ComponentPeer*
newPeer)
470 if (lastPeer !=
nullptr)
473 auto dpy = getDisplay();
475 Rectangle<int>
newBounds = getX11BoundsFromJuce();
478 X11Symbols::getInstance()->xUnmapWindow (
dpy, host);
489 keyWindow = SharedKeyWindow::getKeyWindowForPeer (
newPeer);
493 componentMovedOrResized (owner,
true,
true);
494 X11Symbols::getInstance()->xMapWindow (
dpy, host);
501 void updateKeyFocus()
503 if (lastPeer !=
nullptr && lastPeer->isFocused())
508 void handleXembedCmd (const ::Time& ,
long opcode,
long ,
long ,
long )
512 case XEMBED_REQUEST_FOCUS:
514 owner.grabKeyboardFocus();
517 case XEMBED_FOCUS_NEXT:
519 owner.moveKeyboardFocusToSibling (
true);
522 case XEMBED_FOCUS_PREV:
524 owner.moveKeyboardFocusToSibling (
false);
532 bool handleX11Event (
const XEvent& e)
534 if (e.xany.window == client && client != 0)
539 propertyChanged (e.xproperty.atom);
554 else if (e.xany.window == host && host != 0)
559 if (e.xreparent.parent == host && e.xreparent.window != client)
561 setClient (e.xreparent.window,
false);
567 if (e.xcreatewindow.parent != e.xcreatewindow.window && e.xcreatewindow.parent == host && e.xcreatewindow.window != client)
569 setClient (e.xcreatewindow.window,
false);
575 componentMovedOrResized (owner,
true,
true);
579 if (e.xclient.message_type == messageTypeAtom && e.xclient.format == 32)
581 handleXembedCmd ((::Time) e.xclient.data.l[0], e.xclient.data.l[1],
582 e.xclient.data.l[2], e.xclient.data.l[3],
583 e.xclient.data.l[4]);
597 void sendXEmbedEvent (const ::Time&
xTime,
long opcode,
598 long opcodeMinor = 0,
long data1 = 0,
long data2 = 0)
601 auto dpy = getDisplay();
606 msg.message_type = messageTypeAtom;
611 msg.data.l[3] = data1;
612 msg.data.l[4] = data2;
615 X11Symbols::getInstance()->xSync (
dpy, False);
618 Rectangle<int> getX11BoundsFromJuce()
620 if (
auto* peer = owner.getPeer())
622 auto r = peer->getComponent().getLocalArea (&owner, owner.getLocalBounds());
623 return r * peer->getPlatformScaleFactor() * peer->getComponent().getDesktopScaleFactor();
626 return owner.getLocalBounds();
630 friend bool juce::juce_handleXEmbedEvent (ComponentPeer*,
void*);
631 friend unsigned long juce::juce_getCurrentFocusWindow (ComponentPeer*);
639 static bool dispatchX11Event (ComponentPeer* p,
const XEvent*
eventArg)
645 if (
auto w = e.xany.window)
646 for (
auto*
widget : getWidgets())
652 for (
auto*
widget : getWidgets())
660 static Window getCurrentFocusWindow (ComponentPeer* p)
664 for (
auto*
widget : getWidgets())
669 return SharedKeyWindow::getCurrentFocusWindow (p);