diff --git a/autotests/client/test_wayland_surface.cpp b/autotests/client/test_wayland_surface.cpp --- a/autotests/client/test_wayland_surface.cpp +++ b/autotests/client/test_wayland_surface.cpp @@ -400,9 +400,12 @@ s->commit(KWayland::Client::Surface::CommitFlag::None); QSignalSpy damageSpy(serverSurface, SIGNAL(damaged(QRegion))); QVERIFY(damageSpy.isValid()); + QSignalSpy mappedSpy(serverSurface, SIGNAL(mapped())); + QVERIFY(mappedSpy.isValid()); QSignalSpy unmappedSpy(serverSurface, SIGNAL(unmapped())); QVERIFY(unmappedSpy.isValid()); QVERIFY(damageSpy.wait()); + QCOMPARE(mappedSpy.count(), 1); QVERIFY(unmappedSpy.isEmpty()); // now the ServerSurface should have the black image attached as a buffer @@ -418,6 +421,7 @@ s->commit(KWayland::Client::Surface::CommitFlag::None); damageSpy.clear(); QVERIFY(damageSpy.wait()); + QCOMPARE(mappedSpy.count(), 1); QVERIFY(unmappedSpy.isEmpty()); KWayland::Server::BufferInterface *buffer2 = serverSurface->buffer(); buffer2->ref(); @@ -445,6 +449,7 @@ s->commit(); damageSpy.clear(); QVERIFY(damageSpy.wait()); + QCOMPARE(mappedSpy.count(), 1); QVERIFY(unmappedSpy.isEmpty()); QVERIFY(!buffer2->isReferenced()); delete buffer2; @@ -485,6 +490,7 @@ QCOMPARE(serverSurface->input(), QRegion(0, 0, 24, 24)); QCOMPARE(serverSurface->buffer(), buffer3); QVERIFY(damageSpy.isEmpty()); + QCOMPARE(mappedSpy.count(), 1); QVERIFY(unmappedSpy.isEmpty()); QVERIFY(serverSurface->isMapped()); @@ -496,7 +502,7 @@ s->damage(QRect(0, 0, 10, 10)); s->commit(KWayland::Client::Surface::CommitFlag::None); QVERIFY(unmappedSpy.wait()); - QVERIFY(!unmappedSpy.isEmpty()); + QCOMPARE(mappedSpy.count(), 1); QCOMPARE(unmappedSpy.count(), 1); QVERIFY(damageSpy.isEmpty()); QVERIFY(!serverSurface->isMapped()); diff --git a/src/server/surface_interface.h b/src/server/surface_interface.h --- a/src/server/surface_interface.h +++ b/src/server/surface_interface.h @@ -301,6 +301,12 @@ void inputChanged(const QRegion&); void scaleChanged(qint32); void transformChanged(KWayland::Server::OutputInterface::Transform); + /** + * Emitted when the Surface becomes visible, i.e. a non-null buffer has been attached. + * + * @since 5.70 + **/ + void mapped(); /** * Emitted when the Surface removes its content **/ diff --git a/src/server/surface_interface.cpp b/src/server/surface_interface.cpp --- a/src/server/surface_interface.cpp +++ b/src/server/surface_interface.cpp @@ -330,6 +330,7 @@ const bool contrastChanged = source->contrastIsSet; const bool slideChanged = source->slideIsSet; const bool childrenChanged = source->childrenChanged; + const bool visibilityChanged = bufferChanged && (bool(source->buffer) != bool(target->buffer)); bool sizeChanged = false; auto buffer = target->buffer; if (bufferChanged) { @@ -459,6 +460,9 @@ target->damage = windowRegion.intersected(target->damage.united(bufferDamage)); if (emitChanged) { subSurfaceIsMapped = true; + if (visibilityChanged) { + emit q->mapped(); + } trackedDamage = trackedDamage.united(target->damage); emit q->damaged(target->damage); // workaround for https://bugreports.qt.io/browse/QTBUG-52092