From 1360677478e867034713e5d43d7a8a8f6bf1343d Mon Sep 17 00:00:00 2001 From: Vaxry Date: Mon, 17 Jun 2024 12:42:32 +0200 Subject: subcompositor/renderer: fixup handling of subsurfaces below the main one some apps (notably vlc 4) place a subsurface below the main surface (which is kinda cursed) but we have to accomodate for that --- src/protocols/core/Subcompositor.cpp | 48 ++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 10 deletions(-) (limited to 'src/protocols/core/Subcompositor.cpp') diff --git a/src/protocols/core/Subcompositor.cpp b/src/protocols/core/Subcompositor.cpp index d407636c..cbc4063a 100644 --- a/src/protocols/core/Subcompositor.cpp +++ b/src/protocols/core/Subcompositor.cpp @@ -23,15 +23,29 @@ CWLSubsurfaceResource::CWLSubsurfaceResource(SP resource_, SPsubsurfaces, self.lock()); + auto pushAboveIndex = [this](int idx) -> void { + for (auto& c : parent->subsurfaces) { + if (c->zIndex >= idx) + c->zIndex++; + } + }; + + std::erase_if(parent->subsurfaces, [this](const auto& e) { return e == self || !e; }); auto it = std::find(parent->subsurfaces.begin(), parent->subsurfaces.end(), SURF); if (it == parent->subsurfaces.end()) { - LOGM(ERR, "Invalid surface reference in placeAbove"); - parent->subsurfaces.emplace_back(self.lock()); - } else - parent->subsurfaces.insert(it, self.lock()); + LOGM(ERR, "Invalid surface reference in placeAbove, likely parent"); + pushAboveIndex(1); + parent->subsurfaces.emplace_back(self); + zIndex = 1; + } else { + pushAboveIndex((*it)->zIndex); + zIndex = (*it)->zIndex; + parent->subsurfaces.emplace_back(self); + } + + std::sort(parent->subsurfaces.begin(), parent->subsurfaces.end(), [](const auto& a, const auto& b) { return a->zIndex < b->zIndex; }); }); resource->setPlaceBelow([this](CWlSubsurface* r, wl_resource* surf) { @@ -40,15 +54,29 @@ CWLSubsurfaceResource::CWLSubsurfaceResource(SP resource_, SPsubsurfaces, self.lock()); + auto pushBelowIndex = [this](int idx) -> void { + for (auto& c : parent->subsurfaces) { + if (c->zIndex <= idx) + c->zIndex--; + } + }; + + std::erase_if(parent->subsurfaces, [this](const auto& e) { return e == self || !e; }); auto it = std::find(parent->subsurfaces.begin(), parent->subsurfaces.end(), SURF); if (it == parent->subsurfaces.end()) { - LOGM(ERR, "Invalid surface reference in placeBelow"); - parent->subsurfaces.emplace_back(self.lock()); - } else - parent->subsurfaces.insert(it--, self.lock()); + LOGM(ERR, "Invalid surface reference in placeBelow, likely parent"); + pushBelowIndex(-1); + parent->subsurfaces.emplace_back(self); + zIndex = -1; + } else { + pushBelowIndex((*it)->zIndex); + zIndex = (*it)->zIndex; + parent->subsurfaces.emplace_back(self); + } + + std::sort(parent->subsurfaces.begin(), parent->subsurfaces.end(), [](const auto& a, const auto& b) { return a->zIndex < b->zIndex; }); }); listeners.commitSurface = surface->events.commit.registerListener([this](std::any d) { -- cgit v1.2.3