diff --git a/modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp b/modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp index cd3fe4439e..d50a7704d3 100644 --- a/modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp +++ b/modules/juce_gui_extra/native/juce_linux_XEmbedComponent.cpp @@ -71,86 +71,45 @@ public: }; //============================================================================== - class SharedKeyWindow + class SharedKeyWindow : public ReferenceCountedObject { public: - //============================================================================== - struct Ref - { - Ref() {} - Ref (Pimpl& p) { keyWindow = getKeyWindowForPeer (p.owner.getPeer()); } - ~Ref() { free(); } - - //============================================================================== - Ref (const Ref& o) : keyWindow (o.keyWindow) { if (keyWindow != nullptr) keyWindow->numRefs++; } - Ref (Ref&& o) : keyWindow (o.keyWindow) { o.keyWindow = nullptr; } - Ref (std::nullptr_t) {} - - //============================================================================== - Ref& operator= (std::nullptr_t) { free(); return *this; } + typedef ReferenceCountedObjectPtr Ptr; - Ref& operator= (const Ref& o) - { - free(); - keyWindow = o.keyWindow; - - if (keyWindow != nullptr) - keyWindow->numRefs++; + //============================================================================== + Window getHandle() { return keyProxy; } - return *this; - } + static Window getCurrentFocusWindow (ComponentPeer* peerToLookFor) + { + auto& keyWindows = getKeyWindows(); - Ref& operator= (Ref && o) - { - if (keyWindow != o.keyWindow) - { - free(); - keyWindow = o.keyWindow; - } + if (peerToLookFor != nullptr) + if (auto* foundKeyWindow = keyWindows[peerToLookFor]) + return foundKeyWindow->keyProxy; - o.keyWindow = nullptr; - return *this; - } + return {}; + } - //============================================================================== - SharedKeyWindow& operator*() noexcept { return *keyWindow; } - SharedKeyWindow* operator->() noexcept { return keyWindow; } + static SharedKeyWindow::Ptr getKeyWindowForPeer (ComponentPeer* peerToLookFor) + { + jassert (peerToLookFor != nullptr); - //============================================================================== - bool operator== (std::nullptr_t) const noexcept { return (keyWindow == nullptr); } - bool operator!= (std::nullptr_t) const noexcept { return (keyWindow != nullptr); } + auto& keyWindows = getKeyWindows(); + auto foundKeyWindow = keyWindows[peerToLookFor]; - private: - //============================================================================== - void free() + if (foundKeyWindow == nullptr) { - if (keyWindow != nullptr) - { - if (--keyWindow->numRefs == 0) - delete keyWindow; - - keyWindow = nullptr; - } + foundKeyWindow = new SharedKeyWindow (peerToLookFor); + keyWindows.set (peerToLookFor, foundKeyWindow); } - SharedKeyWindow* keyWindow = nullptr; - }; - - public: - //============================================================================== - Window getHandle() { return keyProxy; } - - static Window getCurrentFocusWindow (ComponentPeer* peerToLookFor) - { - if (keyWindows != nullptr && peerToLookFor != nullptr) - if (auto* foundKeyWindow = (*keyWindows)[peerToLookFor]) - return foundKeyWindow->keyProxy; - - return {}; + return foundKeyWindow; } private: //============================================================================== + friend struct ContainerDeletePolicy; + SharedKeyWindow (ComponentPeer* peerToUse) : keyPeer (peerToUse), keyProxy (juce_createKeyProxyWindow (keyPeer)) @@ -160,43 +119,19 @@ public: { juce_deleteKeyProxyWindow (keyPeer); - if (keyWindows != nullptr) - { - keyWindows->remove (keyPeer); - - if (keyWindows->size() == 0) - { - delete keyWindows; - keyWindows = nullptr; - } - } + auto& keyWindows = getKeyWindows(); + keyWindows.remove (keyPeer); } ComponentPeer* keyPeer; Window keyProxy; - int numRefs = 1; - static SharedKeyWindow* getKeyWindowForPeer (ComponentPeer* peerToLookFor) + static HashMap& getKeyWindows() { - jassert (peerToLookFor != nullptr); - - if (keyWindows == nullptr) - keyWindows = new HashMap; - - auto foundKeyWindow = (*keyWindows)[peerToLookFor]; - - if (foundKeyWindow == nullptr) - { - foundKeyWindow = new SharedKeyWindow (peerToLookFor); - keyWindows->set (peerToLookFor, foundKeyWindow); - } - - return foundKeyWindow; + // store a weak reference to the shared key windows + static HashMap keyWindows; + return keyWindows; } - - //============================================================================== - friend struct Ref; - static HashMap* keyWindows; }; public: @@ -331,7 +266,7 @@ private: int xembedVersion = maxXEmbedVersionToSupport; ComponentPeer* lastPeer = nullptr; - SharedKeyWindow::Ref keyWindow; + SharedKeyWindow::Ptr keyWindow; //============================================================================== void componentParentHierarchyChanged (Component&) override { peerChanged (owner.getPeer()); } @@ -532,7 +467,7 @@ private: { if (wantsFocus) { - keyWindow = SharedKeyWindow::Ref (*this); + keyWindow = SharedKeyWindow::getKeyWindowForPeer (newPeer); updateKeyFocus(); } @@ -709,9 +644,6 @@ private: } }; -//============================================================================== -HashMap* XEmbedComponent::Pimpl::SharedKeyWindow::keyWindows = nullptr; - //============================================================================== XEmbedComponent::XEmbedComponent (bool wantsKeyboardFocus, bool allowForeignWidgetToResizeComponent) : pimpl (new Pimpl (*this, 0, wantsKeyboardFocus, false, allowForeignWidgetToResizeComponent))