From 1ed546004cc082d211cfcdd5e2c2179623af4a53 Mon Sep 17 00:00:00 2001 From: Giulio Camuffo Date: Mon, 6 Oct 2014 11:05:23 +0300 Subject: [PATCH] Fix shm windows sometimes not showing after being hidden MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- .../platforms/wayland/qwaylandshmbackingstore.cpp | 11 +++++++++++ .../platforms/wayland/qwaylandshmbackingstore_p.h | 1 + src/plugins/platforms/wayland/qwaylandwindow.cpp | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp index 421fae91c6b..332ea9265d5 100644 --- a/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp +++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore.cpp @@ -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); diff --git a/src/plugins/platforms/wayland/qwaylandshmbackingstore_p.h b/src/plugins/platforms/wayland/qwaylandshmbackingstore_p.h index 5c3dbb5bc27..319acd9a982 100644 --- a/src/plugins/platforms/wayland/qwaylandshmbackingstore_p.h +++ b/src/plugins/platforms/wayland/qwaylandshmbackingstore_p.h @@ -82,6 +82,7 @@ public: void resize(const QSize &size); void beginPaint(const QRegion &); void endPaint(); + void hidden(); QWaylandAbstractDecoration *windowDecoration() const; diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 5786c1fb8ff..d1ea6c1f979 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -54,6 +54,7 @@ #include "qwaylandwindowmanagerintegration_p.h" #include "qwaylandnativeinterface_p.h" #include "qwaylanddecorationfactory_p.h" +#include "qwaylandshmbackingstore_p.h" #include #include @@ -90,6 +91,7 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mMouseDevice(0) , mMouseSerial(0) , mState(Qt::WindowNoState) + , mBackingStore(Q_NULLPTR) { init(mDisplay->createSurface(static_cast(this))); @@ -248,6 +250,9 @@ void QWaylandWindow::setVisible(bool visible) if (!deleteGuard.isNull()) { attach(static_cast(0), 0, 0); commit(); + if (mBackingStore) { + mBackingStore->hidden(); + } } } }