diff options
| author | Vaxry <vaxry@vaxry.net> | 2026-04-07 14:09:06 +0100 |
|---|---|---|
| committer | Vaxry <43317083+vaxerski@users.noreply.github.com> | 2026-04-07 12:07:36 -0400 |
| commit | 0448e707fce798d6864320ef629ae681845bde26 (patch) | |
| tree | bea6ed92bcb2abef80bef756c60ca167598104ea /src/desktop | |
| parent | 8a97b11b22422bcb6907a66010388856317c7ff5 (diff) | |
desktop/popup: cache tree count
Diffstat (limited to 'src/desktop')
| -rw-r--r-- | src/desktop/view/LayerSurface.cpp | 6 | ||||
| -rw-r--r-- | src/desktop/view/Popup.cpp | 34 | ||||
| -rw-r--r-- | src/desktop/view/Popup.hpp | 7 | ||||
| -rw-r--r-- | src/desktop/view/Window.cpp | 9 |
4 files changed, 45 insertions, 11 deletions
diff --git a/src/desktop/view/LayerSurface.cpp b/src/desktop/view/LayerSurface.cpp index 90de4cdc..a69dd8e9 100644 --- a/src/desktop/view/LayerSurface.cpp +++ b/src/desktop/view/LayerSurface.cpp @@ -426,12 +426,10 @@ bool CLayerSurface::isFadedOut() { } int CLayerSurface::popupsCount() { - if (!m_layerSurface || !m_mapped || m_fadingOut) + if (!m_layerSurface || !m_mapped || m_fadingOut || !m_popupHead) return 0; - int no = -1; // we have one dummy - m_popupHead->breadthfirst([](WP<Desktop::View::CPopup> p, void* data) { *sc<int*>(data) += 1; }, &no); - return no; + return m_popupHead->popupTreeCount(); } MONITORID CLayerSurface::monitorID() { diff --git a/src/desktop/view/Popup.cpp b/src/desktop/view/Popup.cpp index cf0c981b..7791e921 100644 --- a/src/desktop/view/Popup.cpp +++ b/src/desktop/view/Popup.cpp @@ -418,7 +418,8 @@ void CPopup::invalidateTreeExtentsCache() { if (!head) return; - head->m_treeExtentsCacheDirty = true; + head->m_treeExtentsCacheDirty = true; + head->m_treePopupCountCacheDirty = true; } void CPopup::recheckTree() { @@ -561,6 +562,37 @@ const CBox& CPopup::popupTreeExtents() const { return head->m_cachedTreeExtents; } +int CPopup::popupTreeCount() const { + auto head = popupHead(); + if (!head) + return 0; + + if (!head->m_treePopupCountCacheDirty) + return head->m_cachedTreePopupCount; + + head->m_treePopupCountCacheDirty = false; + head->m_cachedTreePopupCount = 0; + + std::vector<SP<CPopup>> popups; + popups.emplace_back(head); + + for (size_t i = 0; i < popups.size(); ++i) { + const auto& popup = popups[i]; + if (!popup) + continue; + + for (const auto& c : popup->m_children) { + if (!c) + continue; + + popups.emplace_back(c); + head->m_cachedTreePopupCount++; + } + } + + return head->m_cachedTreePopupCount; +} + SP<CPopup> CPopup::at(const Vector2D& globalCoords, bool allowsInput) { thread_local std::vector<SP<CPopup>> popups; popups.clear(); diff --git a/src/desktop/view/Popup.hpp b/src/desktop/view/Popup.hpp index bc358707..a2a2e014 100644 --- a/src/desktop/view/Popup.hpp +++ b/src/desktop/view/Popup.hpp @@ -55,6 +55,7 @@ namespace Desktop::View { SP<Desktop::View::CPopup> at(const Vector2D& globalCoords, bool allowsInput = false); SP<Desktop::View::CPopup> popupHead() const; const CBox& popupTreeExtents() const; + int popupTreeCount() const; // WP<Desktop::View::CPopup> m_self; @@ -85,8 +86,10 @@ namespace Desktop::View { bool m_inert = false; - mutable CBox m_cachedTreeExtents = {}; - mutable bool m_treeExtentsCacheDirty = true; + mutable CBox m_cachedTreeExtents = {}; + mutable bool m_treeExtentsCacheDirty = true; + mutable int m_cachedTreePopupCount = 0; + mutable bool m_treePopupCountCacheDirty = true; // std::vector<SP<Desktop::View::CPopup>> m_children; diff --git a/src/desktop/view/Window.cpp b/src/desktop/view/Window.cpp index b9c90ac9..35a706a1 100644 --- a/src/desktop/view/Window.cpp +++ b/src/desktop/view/Window.cpp @@ -742,7 +742,10 @@ bool CWindow::isInCurvedCorner(double x, double y) { // checks if the wayland window has a popup at pos bool CWindow::hasPopupAt(const Vector2D& pos) { - if (m_isX11) + if (m_isX11 || !m_popupHead) + return false; + + if (m_popupHead->popupTreeCount() == 0) return false; auto popup = m_popupHead->at(pos); @@ -933,9 +936,7 @@ int CWindow::popupsCount() { if (m_isX11 || !m_popupHead) return 0; - int no = -1; - m_popupHead->breadthfirst([](WP<Desktop::View::CPopup> p, void* d) { *sc<int*>(d) += 1; }, &no); - return no; + return m_popupHead->popupTreeCount(); } int CWindow::surfacesCount() { |
