summaryrefslogtreecommitdiff
path: root/src/protocols/core/Subcompositor.cpp
diff options
context:
space:
mode:
authorVaxry <vaxry@vaxry.net>2024-06-17 12:42:32 +0200
committerVaxry <vaxry@vaxry.net>2024-06-17 12:42:39 +0200
commit1360677478e867034713e5d43d7a8a8f6bf1343d (patch)
tree27bd309676fcb1391e712a10ddd399687abeeddc /src/protocols/core/Subcompositor.cpp
parent14ab0ecc5eb3c437dd62f92629fc29e33679043b (diff)
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
Diffstat (limited to 'src/protocols/core/Subcompositor.cpp')
-rw-r--r--src/protocols/core/Subcompositor.cpp48
1 files changed, 38 insertions, 10 deletions
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<CWlSubsurface> resource_, SP<CWL
if (!parent)
return;
- std::erase(parent->subsurfaces, 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<CWlSubsurface> resource_, SP<CWL
if (!parent)
return;
- std::erase(parent->subsurfaces, 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) {