summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Edmundson <[email protected]>2025-05-22 12:58:45 +0200
committerLiang Qi <[email protected]>2025-05-27 20:51:05 +0000
commit68562d9b2e8f5b66d3a1e9bac13bfc3c2981bc8a (patch)
treead9d5dc6d7ceb4d1352704b67ab10214d2de204d
parent4c8333a3537812885de02f2edfc5800c51ae56a0 (diff)
Wayland Client: explicitly attach a buffer in sendExposeEvent()
if an expose is not handled by application code. This primarily is a workaround for Qt unit tests using QWindow directly and wanting focus. Done-with: Liang Qi <[email protected]> Fixes: QTBUG-137021 Change-Id: Ibcbd931af9a3558cf7244699216bc716eba4850c Reviewed-by: Liang Qi <[email protected]> Reviewed-by: Eskil Abrahamsen Blomfeldt <[email protected]>
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow.cpp29
-rw-r--r--src/plugins/platforms/wayland/qwaylandwindow_p.h1
2 files changed, 26 insertions, 4 deletions
diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp
index 0dc55029631..49b4431ac98 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow.cpp
+++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp
@@ -588,12 +588,32 @@ void QWaylandWindow::resizeFromApplyConfigure(const QSize &sizeWithMargins, cons
void QWaylandWindow::sendExposeEvent(const QRect &rect)
{
- if (!(mShellSurface && mShellSurface->handleExpose(rect))) {
- mLastExposeGeometry = rect;
+ if (mShellSurface && mShellSurface->handleExpose(rect)) {
+ qCDebug(lcQpaWayland) << "sendExposeEvent: intercepted by shell extension, not sending";
+ return;
+ }
+
+ static bool sQtTestMode = qEnvironmentVariableIsSet("QT_QTESTLIB_RUNNING");
+ mLastExposeGeometry = rect;
+
+ if (sQtTestMode) {
+ mExposeEventNeedsAttachedBuffer = true;
+ QWindowSystemInterface::handleExposeEvent<QWindowSystemInterface::SynchronousDelivery>(window(), rect);
+ /**
+ * If an expose is not handled by application code, explicitly attach a buffer
+ * This primarily is a workaround for Qt unit tests using QWindow directly and
+ * wanting focus.
+ */
+ if (mExposeEventNeedsAttachedBuffer && !rect.isNull()) {
+ auto buffer = new QWaylandShmBuffer(mDisplay, rect.size(), QImage::Format_ARGB32);
+ buffer->image()->fill(Qt::transparent);
+ buffer->setDeleteOnRelease(true);
+ attach(buffer, 0, 0);
+ }
+ } else {
QWindowSystemInterface::handleExposeEvent(window(), rect);
}
- else
- qCDebug(lcQpaWayland) << "sendExposeEvent: intercepted by shell extension, not sending";
+
}
QPlatformScreen *QWaylandWindow::calculateScreenFromSurfaceEvents() const
@@ -1752,6 +1772,7 @@ void QWaylandWindow::requestUpdate()
// Can be called from the render thread (without locking anything) so make sure to not make races in this method.
void QWaylandWindow::handleUpdate()
{
+ mExposeEventNeedsAttachedBuffer = false;
qCDebug(lcWaylandBackingstore) << "handleUpdate" << QThread::currentThread();
// TODO: Should sync subsurfaces avoid requesting frame callbacks?
diff --git a/src/plugins/platforms/wayland/qwaylandwindow_p.h b/src/plugins/platforms/wayland/qwaylandwindow_p.h
index b28e087ff4a..2c5117a0db4 100644
--- a/src/plugins/platforms/wayland/qwaylandwindow_p.h
+++ b/src/plugins/platforms/wayland/qwaylandwindow_p.h
@@ -316,6 +316,7 @@ protected:
// True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer
std::atomic_bool mWaitingForUpdate = false;
bool mExposed = false;
+ std::atomic_bool mExposeEventNeedsAttachedBuffer = false;
// written from the main thread, read by the render thread
std::atomic_bool mWaitingToApplyConfigure = false;