Client: Reset mFrameCallbackTimedOut when showing a window

When a window is hidden, the corresponding expose event is sent
asynchronously. So, a buffer (and a frame callback) can be attached
after the window is hidden.

QWaylandWindow::initWindow() handles that case by attaching a nil buffer
to the surface, but it skips resetting the frame callback things.

If mFrameCallbackTimedOut is not reset, then the window can get stuck
in the unexposed state and not show up after the second setVisible(true).

This change makes the initWindow() function also reset frame callback
data. It fixes some windows not showing up after remapping them.

Pick-to: 6.9
Change-Id: I8952ffed24844c73721c4f689786146c317e014d
Reviewed-by: David Edmundson <davidedmundson@kde.org>
This commit is contained in:
Vlad Zahorodnii 2025-03-31 11:40:12 +03:00
parent 727e115a81
commit 6580ad906a
2 changed files with 11 additions and 3 deletions

View File

@ -107,6 +107,7 @@ void QWaylandWindow::initWindow()
*/
mSurface->attach(nullptr, 0, 0);
mSurface->commit();
resetFrameCallback();
if (window()->type() == Qt::Desktop)
return;
@ -354,6 +355,15 @@ void QWaylandWindow::resetSurfaceRole()
delete std::exchange(mShellSurface, nullptr);
delete std::exchange(mSubSurfaceWindow, nullptr);
emit surfaceRoleDestroyed();
resetFrameCallback();
mInFrameRender = false;
mWaitingToApplyConfigure = false;
mExposed = false;
}
void QWaylandWindow::resetFrameCallback()
{
{
QMutexLocker lock(&mFrameSyncMutex);
if (mFrameCallback) {
@ -367,10 +377,7 @@ void QWaylandWindow::resetSurfaceRole()
killTimer(mFrameCallbackCheckIntervalTimerId);
mFrameCallbackCheckIntervalTimerId = -1;
}
mInFrameRender = false;
mFrameCallbackTimedOut = false;
mWaitingToApplyConfigure = false;
mExposed = false;
}
QWaylandWindow *QWaylandWindow::fromWlSurface(::wl_surface *surface)

View File

@ -359,6 +359,7 @@ private:
bool shouldCreateShellSurface() const;
bool shouldCreateSubSurface() const;
void resetSurfaceRole();
void resetFrameCallback();
QPlatformScreen *calculateScreenFromSurfaceEvents() const;
void setOpaqueArea(const QRegion &opaqueArea);
bool isOpaque() const;