summaryrefslogtreecommitdiff
path: root/src/desktop
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2026-04-07 14:09:06 +0100
committerVaxry <43317083+vaxerski@users.noreply.github.com>2026-04-07 12:07:36 -0400
commit0448e707fce798d6864320ef629ae681845bde26 (patch)
treebea6ed92bcb2abef80bef756c60ca167598104ea /src/desktop
parent8a97b11b22422bcb6907a66010388856317c7ff5 (diff)
desktop/popup: cache tree count
Diffstat (limited to 'src/desktop')
-rw-r--r--src/desktop/view/LayerSurface.cpp6
-rw-r--r--src/desktop/view/Popup.cpp34
-rw-r--r--src/desktop/view/Popup.hpp7
-rw-r--r--src/desktop/view/Window.cpp9
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() {