| @@ -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<SharedKeyWindow> 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>; | |||
| 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<ComponentPeer*, SharedKeyWindow*>& getKeyWindows() | |||
| { | |||
| jassert (peerToLookFor != nullptr); | |||
| if (keyWindows == nullptr) | |||
| keyWindows = new HashMap<ComponentPeer*,SharedKeyWindow*>; | |||
| 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<ComponentPeer*, SharedKeyWindow*> keyWindows; | |||
| return keyWindows; | |||
| } | |||
| //============================================================================== | |||
| friend struct Ref; | |||
| static HashMap<ComponentPeer*, SharedKeyWindow*>* 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<ComponentPeer*,XEmbedComponent::Pimpl::SharedKeyWindow*>* XEmbedComponent::Pimpl::SharedKeyWindow::keyWindows = nullptr; | |||
| //============================================================================== | |||
| XEmbedComponent::XEmbedComponent (bool wantsKeyboardFocus, bool allowForeignWidgetToResizeComponent) | |||
| : pimpl (new Pimpl (*this, 0, wantsKeyboardFocus, false, allowForeignWidgetToResizeComponent)) | |||