scene/workspacescene: fix direct scanout checks with subsurfaces
The check ignored that subsurfaces could be not visible, not mapped, and also below the parent surface
This commit is contained in:
parent
da34191115
commit
9c2035ca63
1 changed files with 25 additions and 6 deletions
|
@ -153,12 +153,28 @@ Item *WorkspaceScene::overlayItem() const
|
|||
|
||||
static SurfaceItem *findTopMostSurface(SurfaceItem *item)
|
||||
{
|
||||
const QList<Item *> children = item->childItems();
|
||||
if (children.isEmpty()) {
|
||||
return item;
|
||||
} else {
|
||||
return findTopMostSurface(static_cast<SurfaceItem *>(children.constLast()));
|
||||
if (!item->isVisible()) {
|
||||
return nullptr;
|
||||
}
|
||||
const QList<Item *> children = item->sortedChildItems();
|
||||
for (const auto &child : children | std::views::reverse) {
|
||||
if (child->z() >= 0) {
|
||||
if (auto item = findTopMostSurface(static_cast<SurfaceItem *>(child))) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (item->pixmap()) {
|
||||
return item;
|
||||
}
|
||||
for (const auto &child : children | std::views::reverse) {
|
||||
if (child->z() < 0) {
|
||||
if (auto item = findTopMostSurface(static_cast<SurfaceItem *>(child))) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SurfaceItem *WorkspaceScene::scanoutCandidate() const
|
||||
|
@ -171,7 +187,7 @@ SurfaceItem *WorkspaceScene::scanoutCandidate() const
|
|||
for (int i = stacking_order.count() - 1; i >= 0; i--) {
|
||||
WindowItem *windowItem = stacking_order[i];
|
||||
Window *window = windowItem->window();
|
||||
if (window->isOnOutput(painted_screen) && window->opacity() > 0) {
|
||||
if (window->isOnOutput(painted_screen) && window->opacity() > 0 && windowItem->isVisible()) {
|
||||
if (!window->isClient() || !window->isFullScreen() || window->opacity() != 1.0) {
|
||||
break;
|
||||
}
|
||||
|
@ -179,6 +195,9 @@ SurfaceItem *WorkspaceScene::scanoutCandidate() const
|
|||
break;
|
||||
}
|
||||
SurfaceItem *topMost = findTopMostSurface(windowItem->surfaceItem());
|
||||
if (!topMost) {
|
||||
break;
|
||||
}
|
||||
// the subsurface has to be able to cover the whole window
|
||||
if (topMost->position() != QPoint(0, 0)) {
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue