Fix shm windows sometimes not showing after being hidden

QWaylandShmBackingStore installs a frame callback on flush, and subsequent
flushes will not attach a new buffer until the callback is fired.
If the window is hidden while we're waiting for the callback, we attach
a NULL buffer, so the compositor will not redraw the surface and will not
fire the frame callback. When showing the window again the backing store's
flush() will wait indefinitely for the frame callback to attach its buffer.
To fix it destroy the frame callback when the window is hidden.

This was easily noticeable when fast switching between popup menus.

Change-Id: Ic0c71ed79e2fab9faf452f63b05bc4576ea9a3ba
Reviewed-by: Jørgen Lind <jorgen.lind@digia.com>
This commit is contained in:
Giulio Camuffo 2014-10-06 11:05:23 +03:00
parent 5984e1e5c1
commit 1ed546004c
3 changed files with 17 additions and 0 deletions

View File

@ -140,6 +140,9 @@ QWaylandShmBackingStore::QWaylandShmBackingStore(QWindow *window)
QWaylandShmBackingStore::~QWaylandShmBackingStore()
{
if (QWaylandWindow *w = waylandWindow())
w->setBackingStore(Q_NULLPTR);
if (mFrameCallback)
wl_callback_destroy(mFrameCallback);
@ -175,6 +178,14 @@ void QWaylandShmBackingStore::endPaint()
waylandWindow()->setCanResize(true);
}
void QWaylandShmBackingStore::hidden()
{
if (mFrameCallback) {
wl_callback_destroy(mFrameCallback);
mFrameCallback = Q_NULLPTR;
}
}
void QWaylandShmBackingStore::ensureSize()
{
waylandWindow()->setBackingStore(this);

View File

@ -82,6 +82,7 @@ public:
void resize(const QSize &size);
void beginPaint(const QRegion &);
void endPaint();
void hidden();
QWaylandAbstractDecoration *windowDecoration() const;

View File

@ -54,6 +54,7 @@
#include "qwaylandwindowmanagerintegration_p.h"
#include "qwaylandnativeinterface_p.h"
#include "qwaylanddecorationfactory_p.h"
#include "qwaylandshmbackingstore_p.h"
#include <QtCore/QFileInfo>
#include <QtCore/QPointer>
@ -90,6 +91,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window)
, mMouseDevice(0)
, mMouseSerial(0)
, mState(Qt::WindowNoState)
, mBackingStore(Q_NULLPTR)
{
init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this)));
@ -248,6 +250,9 @@ void QWaylandWindow::setVisible(bool visible)
if (!deleteGuard.isNull()) {
attach(static_cast<QWaylandBuffer *>(0), 0, 0);
commit();
if (mBackingStore) {
mBackingStore->hidden();
}
}
}
}