aboutsummarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorDonald Carr2016-11-17 14:12:41 -0800
committerDonald Carr2017-01-13 06:17:51 -0800
commit590f253f5606e788c728539204521b5cf1545c81 (patch)
tree725f1abcfa3dabca8ea6deaaae0e45cfa8d6a80c
parent996be7e619f65277974bc0094482ab13ef08fa4c (diff)
downloadaur-590f253f5606e788c728539204521b5cf1545c81.tar.gz
Yes! Wayland crash plaguing us/me since 5.7.0-beta1 should be dead
Thank you Robin, for your eagle eyed, vaguely well targeted suggestions, you beautiful son of a bitch Change-Id: I33c852f340d468a66e76ed9c0b50a82504472e67
-rw-r--r--5.8.0-beta1-5b807802866c8df00cb3340d4f9bcc343be5973a.patch2207
-rw-r--r--PKGBUILD3
2 files changed, 2209 insertions, 1 deletions
diff --git a/5.8.0-beta1-5b807802866c8df00cb3340d4f9bcc343be5973a.patch b/5.8.0-beta1-5b807802866c8df00cb3340d4f9bcc343be5973a.patch
new file mode 100644
index 000000000000..98e9fb23d47f
--- /dev/null
+++ b/5.8.0-beta1-5b807802866c8df00cb3340d4f9bcc343be5973a.patch
@@ -0,0 +1,2207 @@
+diff --git a/examples/wayland/pure-qml/qml/Chrome.qml b/examples/wayland/pure-qml/qml/Chrome.qml
+index d2ff5cc..dc3ad47 100644
+--- a/examples/wayland/pure-qml/qml/Chrome.qml
++++ b/examples/wayland/pure-qml/qml/Chrome.qml
+@@ -44,6 +44,8 @@ import QtWayland.Compositor 1.0
+ ShellSurfaceItem {
+ id: rootChrome
+
++ property bool isChild: parent.shellSurface !== undefined
++
+ onSurfaceDestroyed: {
+ bufferLocked = true;
+ destroyAnimation.start();
+@@ -67,6 +69,7 @@ ShellSurfaceItem {
+ ParallelAnimation {
+ NumberAnimation { target: scaleTransform; property: "yScale"; to: 2/height; duration: 150 }
+ NumberAnimation { target: scaleTransform; property: "xScale"; to: 0.4; duration: 150 }
++ NumberAnimation { target: rootChrome; property: "opacity"; to: rootChrome.isChild ? 0 : 1; duration: 150 }
+ }
+ NumberAnimation { target: scaleTransform; property: "xScale"; to: 0; duration: 150 }
+ ScriptAction { script: { rootChrome.destroy(); } }
+diff --git a/examples/wayland/pure-qml/qml/main.qml b/examples/wayland/pure-qml/qml/main.qml
+index 9bce7bc..5eece07 100644
+--- a/examples/wayland/pure-qml/qml/main.qml
++++ b/examples/wayland/pure-qml/qml/main.qml
+@@ -81,7 +81,8 @@ WaylandCompositor {
+ }
+ onXdgPopupCreated: {
+ var parentView = viewsBySurface[xdgPopup.parentSurface];
+- chromeComponent.createObject(parentView, { "shellSurface": xdgPopup } );
++ var item = chromeComponent.createObject(parentView, { "shellSurface": xdgPopup } );
++ viewsBySurface[xdgPopup.surface] = item;
+ }
+ }
+
+diff --git a/src/client/client.pro b/src/client/client.pro
+index 34955df..5ae01c0 100644
+--- a/src/client/client.pro
++++ b/src/client/client.pro
+@@ -66,7 +66,7 @@ SOURCES += qwaylandintegration.cpp \
+ qwaylandwlshellintegration.cpp \
+ qwaylandxdgshell.cpp \
+ qwaylandxdgsurface.cpp \
+- qwaylandxdgpopup_p.cpp \
++ qwaylandxdgpopup.cpp \
+ qwaylandxdgshellintegration.cpp \
+ qwaylandextendedsurface.cpp \
+ qwaylandsubsurface.cpp \
+diff --git a/src/client/qwaylandclipboard.cpp b/src/client/qwaylandclipboard.cpp
+index 2e3c204..409abaa 100644
+--- a/src/client/qwaylandclipboard.cpp
++++ b/src/client/qwaylandclipboard.cpp
+@@ -44,6 +44,8 @@
+ #include "qwaylanddatasource_p.h"
+ #include "qwaylanddatadevice_p.h"
+
++#ifndef QT_NO_DRAGANDDROP
++
+ QT_BEGIN_NAMESPACE
+
+ namespace QtWaylandClient {
+@@ -60,11 +62,11 @@ QWaylandClipboard::~QWaylandClipboard()
+ QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode)
+ {
+ if (mode != QClipboard::Clipboard)
+- return 0;
++ return &m_emptyData;
+
+ QWaylandInputDevice *inputDevice = mDisplay->currentInputDevice();
+ if (!inputDevice || !inputDevice->dataDevice())
+- return 0;
++ return &m_emptyData;
+
+ QWaylandDataSource *source = inputDevice->dataDevice()->selectionSource();
+ if (source) {
+@@ -74,7 +76,7 @@ QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode)
+ if (inputDevice->dataDevice()->selectionOffer())
+ return inputDevice->dataDevice()->selectionOffer()->mimeData();
+
+- return 0;
++ return &m_emptyData;
+ }
+
+ void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
+@@ -115,3 +117,5 @@ bool QWaylandClipboard::ownsMode(QClipboard::Mode mode) const
+ }
+
+ QT_END_NAMESPACE
++
++#endif // QT_NO_DRAGANDDROP
+diff --git a/src/client/qwaylandclipboard_p.h b/src/client/qwaylandclipboard_p.h
+index aa008ee..6468613 100644
+--- a/src/client/qwaylandclipboard_p.h
++++ b/src/client/qwaylandclipboard_p.h
+@@ -53,9 +53,11 @@
+
+ #include <qpa/qplatformclipboard.h>
+ #include <QtCore/QVariant>
++#include <QtCore/QMimeData>
+
+ #include <QtWaylandClient/qwaylandclientexport.h>
+
++#ifndef QT_NO_DRAGANDDROP
+ QT_BEGIN_NAMESPACE
+
+ namespace QtWaylandClient {
+@@ -76,10 +78,13 @@ public:
+
+ private:
+ QWaylandDisplay *mDisplay;
++ QMimeData m_emptyData;
+ };
+
+ }
+
+ QT_END_NAMESPACE
+
++#endif // QT_NO_DRAGANDDROP
++
+ #endif // QWAYLANDCLIPBOARD_H
+diff --git a/src/client/qwaylanddatadevice.cpp b/src/client/qwaylanddatadevice.cpp
+index d04c20b..f1a1ba6 100644
+--- a/src/client/qwaylanddatadevice.cpp
++++ b/src/client/qwaylanddatadevice.cpp
+@@ -56,6 +56,8 @@
+ #include <qpa/qplatformdrag.h>
+ #include <qpa/qwindowsysteminterface.h>
+
++#ifndef QT_NO_DRAGANDDROP
++
+ QT_BEGIN_NAMESPACE
+
+ namespace QtWaylandClient {
+@@ -268,3 +270,5 @@ QPoint QWaylandDataDevice::calculateDragPosition(int x, int y, QWindow *wnd) con
+ }
+
+ QT_END_NAMESPACE
++
++#endif // QT_NO_DRAGANDDROP
+diff --git a/src/client/qwaylanddatadevice_p.h b/src/client/qwaylanddatadevice_p.h
+index 7daa9f0..318636d 100644
+--- a/src/client/qwaylanddatadevice_p.h
++++ b/src/client/qwaylanddatadevice_p.h
+@@ -58,6 +58,8 @@
+
+ #include <QtWaylandClient/private/qwayland-wayland.h>
+
++#ifndef QT_NO_DRAGANDDROP
++
+ QT_BEGIN_NAMESPACE
+
+ class QMimeData;
+@@ -120,4 +122,6 @@ private:
+
+ QT_END_NAMESPACE
+
++#endif // QT_NO_DRAGANDDROP
++
+ #endif // QWAYLANDDATADEVICE_H
+diff --git a/src/client/qwaylanddatadevicemanager.cpp b/src/client/qwaylanddatadevicemanager.cpp
+index 35d6730..5c6f741 100644
+--- a/src/client/qwaylanddatadevicemanager.cpp
++++ b/src/client/qwaylanddatadevicemanager.cpp
+@@ -46,6 +46,8 @@
+
+ #include <QtCore/QDebug>
+
++#ifndef QT_NO_DRAGANDDROP
++
+ QT_BEGIN_NAMESPACE
+
+ namespace QtWaylandClient {
+@@ -80,3 +82,5 @@ QWaylandDisplay *QWaylandDataDeviceManager::display() const
+ }
+
+ QT_END_NAMESPACE
++
++#endif // QT_NO_DRAGANDDROP
+diff --git a/src/client/qwaylanddatadevicemanager_p.h b/src/client/qwaylanddatadevicemanager_p.h
+index 0c1d95d..90ca301 100644
+--- a/src/client/qwaylanddatadevicemanager_p.h
++++ b/src/client/qwaylanddatadevicemanager_p.h
+@@ -54,6 +54,8 @@
+ #include <QtWaylandClient/qwaylandclientexport.h>
+ #include <QtWaylandClient/private/qwayland-wayland.h>
+
++#ifndef QT_NO_DRAGANDDROP
++
+ QT_BEGIN_NAMESPACE
+
+ namespace QtWaylandClient {
+@@ -81,4 +83,6 @@ private:
+
+ QT_END_NAMESPACE
+
++#endif // QT_NO_DRAGANDDROP
++
+ #endif // QWAYLANDDATADEVICEMANAGER_H
+diff --git a/src/client/qwaylanddataoffer.cpp b/src/client/qwaylanddataoffer.cpp
+index 2491c65..b33a98e 100644
+--- a/src/client/qwaylanddataoffer.cpp
++++ b/src/client/qwaylanddataoffer.cpp
+@@ -47,6 +47,8 @@
+
+ #include <QtCore/QDebug>
+
++#ifndef QT_NO_DRAGANDDROP
++
+ QT_BEGIN_NAMESPACE
+
+ namespace QtWaylandClient {
+@@ -181,3 +183,5 @@ int QWaylandMimeData::readData(int fd, QByteArray &data) const
+ }
+
+ QT_END_NAMESPACE
++
++#endif // QT_NO_DRAGANDDROP
+diff --git a/src/client/qwaylanddataoffer_p.h b/src/client/qwaylanddataoffer_p.h
+index 5e635c1..6368bff 100644
+--- a/src/client/qwaylanddataoffer_p.h
++++ b/src/client/qwaylanddataoffer_p.h
+@@ -56,6 +56,7 @@
+ #include <QtWaylandClient/qwaylandclientexport.h>
+ #include <QtWaylandClient/private/qwayland-wayland.h>
+
++#ifndef QT_NO_DRAGANDDROP
+ QT_BEGIN_NAMESPACE
+
+ namespace QtWaylandClient {
+@@ -105,5 +106,5 @@ private:
+ }
+
+ QT_END_NAMESPACE
+-
++#endif // QT_NO_DRAGANDDROP
+ #endif
+diff --git a/src/client/qwaylanddatasource.cpp b/src/client/qwaylanddatasource.cpp
+index 40beea3..bada694 100644
+--- a/src/client/qwaylanddatasource.cpp
++++ b/src/client/qwaylanddatasource.cpp
+@@ -49,6 +49,8 @@
+
+ #include <unistd.h>
+
++#ifndef QT_NO_DRAGANDDROP
++
+ QT_BEGIN_NAMESPACE
+
+ namespace QtWaylandClient {
+@@ -96,3 +98,5 @@ void QWaylandDataSource::data_source_target(const QString &mime_type)
+ }
+
+ QT_END_NAMESPACE
++
++#endif // QT_NO_DRAGANDDROP
+diff --git a/src/client/qwaylanddatasource_p.h b/src/client/qwaylanddatasource_p.h
+index c099ff6..9e29ae8 100644
+--- a/src/client/qwaylanddatasource_p.h
++++ b/src/client/qwaylanddatasource_p.h
+@@ -56,6 +56,8 @@
+ #include <QtWaylandClient/private/qwayland-wayland.h>
+ #include <QtWaylandClient/qwaylandclientexport.h>
+
++#ifndef QT_NO_DRAGANDDROP
++
+ QT_BEGIN_NAMESPACE
+
+ class QMimeData;
+@@ -92,4 +94,6 @@ private:
+
+ QT_END_NAMESPACE
+
++#endif // QT_NO_DRAGANDDROP
++
+ #endif // QWAYLANDDATASOURCE_H
+diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp
+index 3fd2aa5..de38e3f 100644
+--- a/src/client/qwaylanddisplay.cpp
++++ b/src/client/qwaylanddisplay.cpp
+@@ -120,7 +120,9 @@ QWaylandWindowManagerIntegration *QWaylandDisplay::windowManagerIntegration() co
+
+ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration)
+ : mWaylandIntegration(waylandIntegration)
++#ifndef QT_NO_DRAGANDDROP
+ , mDndSelectionHandler(0)
++#endif
+ , mWindowExtension(0)
+ , mSubCompositor(0)
+ , mTouchExtension(0)
+@@ -158,7 +160,9 @@ QWaylandDisplay::~QWaylandDisplay(void)
+ mWaylandIntegration->destroyScreen(screen);
+ }
+ mScreens.clear();
++#ifndef QT_NO_DRAGANDDROP
+ delete mDndSelectionHandler.take();
++#endif
+ wl_display_disconnect(mDisplay);
+ }
+
+@@ -251,8 +255,10 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin
+ } else if (interface == QStringLiteral("wl_seat")) {
+ QWaylandInputDevice *inputDevice = mWaylandIntegration->createInputDevice(this, version, id);
+ mInputDevices.append(inputDevice);
++#ifndef QT_NO_DRAGANDDROP
+ } else if (interface == QStringLiteral("wl_data_device_manager")) {
+ mDndSelectionHandler.reset(new QWaylandDataDeviceManager(this, id));
++#endif
+ } else if (interface == QStringLiteral("qt_surface_extension")) {
+ mWindowExtension.reset(new QtWayland::qt_surface_extension(registry, id, 1));
+ } else if (interface == QStringLiteral("wl_subcompositor")) {
+@@ -413,11 +419,7 @@ void QWaylandDisplay::handleKeyboardFocusChanged(QWaylandInputDevice *inputDevic
+ if (mLastKeyboardFocus == keyboardFocus)
+ return;
+
+- if (keyboardFocus && !keyboardFocus->shellManagesActiveState())
+- handleWindowActivated(keyboardFocus);
+-
+- if (mLastKeyboardFocus && !mLastKeyboardFocus->shellManagesActiveState())
+- handleWindowDeactivated(mLastKeyboardFocus);
++ mWaylandIntegration->mShellIntegration->handleKeyboardFocusChanged(keyboardFocus, mLastKeyboardFocus);
+
+ mLastKeyboardFocus = keyboardFocus;
+ }
+diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h
+index 2864b35..fae17d5 100644
+--- a/src/client/qwaylanddisplay_p.h
++++ b/src/client/qwaylanddisplay_p.h
+@@ -137,9 +137,9 @@ public:
+ QList<QWaylandInputDevice *> inputDevices() const { return mInputDevices; }
+ QWaylandInputDevice *defaultInputDevice() const;
+ QWaylandInputDevice *currentInputDevice() const { return defaultInputDevice(); }
+-
++#ifndef QT_NO_DRAGANDDROP
+ QWaylandDataDeviceManager *dndSelectionHandler() const { return mDndSelectionHandler.data(); }
+-
++#endif
+ QtWayland::qt_surface_extension *windowExtension() const { return mWindowExtension.data(); }
+ QWaylandTouchExtension *touchExtension() const { return mTouchExtension.data(); }
+ QtWayland::zwp_text_input_manager_v2 *textInputManager() const { return mTextInputManager.data(); }
+@@ -202,7 +202,9 @@ private:
+ QList<QWaylandInputDevice *> mInputDevices;
+ QList<Listener> mRegistryListeners;
+ QWaylandIntegration *mWaylandIntegration;
++#ifndef QT_NO_DRAGANDDROP
+ QScopedPointer<QWaylandDataDeviceManager> mDndSelectionHandler;
++#endif
+ QScopedPointer<QtWayland::qt_surface_extension> mWindowExtension;
+ QScopedPointer<QtWayland::wl_subcompositor> mSubCompositor;
+ QScopedPointer<QWaylandTouchExtension> mTouchExtension;
+diff --git a/src/client/qwaylanddnd.cpp b/src/client/qwaylanddnd.cpp
+index b59ac6d..e29267f 100644
+--- a/src/client/qwaylanddnd.cpp
++++ b/src/client/qwaylanddnd.cpp
+@@ -50,7 +50,7 @@
+ #include <QDebug>
+
+ QT_BEGIN_NAMESPACE
+-
++#ifndef QT_NO_DRAGANDDROP
+ namespace QtWaylandClient {
+
+ QWaylandDrag::QWaylandDrag(QWaylandDisplay *display)
+@@ -98,7 +98,7 @@ void QWaylandDrag::drop(const QPoint &globalPos)
+
+ void QWaylandDrag::endDrag()
+ {
+- // Do nothing
++ m_display->currentInputDevice()->handleEndDrag();
+ }
+
+ void QWaylandDrag::updateTarget(const QString &mimeType)
+@@ -131,5 +131,5 @@ void QWaylandDrag::finishDrag(const QPlatformDropQtResponse &response)
+ }
+
+ }
+-
++#endif // QT_NO_DRAGANDDROP
+ QT_END_NAMESPACE
+diff --git a/src/client/qwaylanddnd_p.h b/src/client/qwaylanddnd_p.h
+index 2ff00b9..464b983 100644
+--- a/src/client/qwaylanddnd_p.h
++++ b/src/client/qwaylanddnd_p.h
+@@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE
+ namespace QtWaylandClient {
+
+ class QWaylandDisplay;
+-
++#ifndef QT_NO_DRAGANDDROP
+ class Q_WAYLAND_CLIENT_EXPORT QWaylandDrag : public QBasicDrag
+ {
+ public:
+@@ -88,7 +88,7 @@ protected:
+ private:
+ QWaylandDisplay *m_display;
+ };
+-
++#endif
+ }
+
+ QT_END_NAMESPACE
+diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
+index f490f07..94316ba 100644
+--- a/src/client/qwaylandinputdevice.cpp
++++ b/src/client/qwaylandinputdevice.cpp
+@@ -188,9 +188,11 @@ QWaylandInputDevice::QWaylandInputDevice(QWaylandDisplay *display, int version,
+ , mSerial(0)
+ , mTouchDevice(0)
+ {
++#ifndef QT_NO_DRAGANDDROP
+ if (mQDisplay->dndSelectionHandler()) {
+ mDataDevice = mQDisplay->dndSelectionHandler()->getDataDevice(this);
+ }
++#endif
+
+ if (mQDisplay->textInputManager()) {
+ mTextInput = new QWaylandTextInput(mQDisplay, mQDisplay->textInputManager()->get_text_input(wl_seat()));
+@@ -268,6 +270,14 @@ void QWaylandInputDevice::handleWindowDestroyed(QWaylandWindow *window)
+ mTouch->mFocus = 0;
+ }
+
++void QWaylandInputDevice::handleEndDrag()
++{
++ if (mTouch)
++ mTouch->releasePoints();
++ if (mPointer)
++ mPointer->releaseButtons();
++}
++
+ void QWaylandInputDevice::setDataDevice(QWaylandDataDevice *device)
+ {
+ mDataDevice = device;
+@@ -532,6 +542,14 @@ void QWaylandInputDevice::Pointer::pointer_button(uint32_t serial, uint32_t time
+ }
+ }
+
++void QWaylandInputDevice::Pointer::releaseButtons()
++{
++ mButtons = Qt::NoButton;
++ MotionEvent e(mParent->mTime, mSurfacePos, mGlobalPos, mButtons, mParent->modifiers());
++ if (mFocus)
++ mFocus->handleMouse(mParent, e);
++}
++
+ class WheelEvent : public QWaylandPointerEvent
+ {
+ public:
+@@ -845,6 +863,16 @@ bool QWaylandInputDevice::Touch::allTouchPointsReleased()
+ return true;
+ }
+
++void QWaylandInputDevice::Touch::releasePoints()
++{
++ Q_FOREACH (const QWindowSystemInterface::TouchPoint &previousPoint, mPrevTouchPoints) {
++ QWindowSystemInterface::TouchPoint tp = previousPoint;
++ tp.state = Qt::TouchPointReleased;
++ mTouchPoints.append(tp);
++ }
++ touch_frame();
++}
++
+ void QWaylandInputDevice::Touch::touch_frame()
+ {
+ // Copy all points, that are in the previous but not in the current list, as stationary.
+diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h
+index ea68522..2f39bc5 100644
+--- a/src/client/qwaylandinputdevice_p.h
++++ b/src/client/qwaylandinputdevice_p.h
+@@ -105,6 +105,7 @@ public:
+ void setCursor(struct wl_buffer *buffer, const QPoint &hotSpot, const QSize &size);
+ void setCursor(const QSharedPointer<QWaylandBuffer> &buffer, const QPoint &hotSpot);
+ void handleWindowDestroyed(QWaylandWindow *window);
++ void handleEndDrag();
+
+ void setDataDevice(QWaylandDataDevice *device);
+ QWaylandDataDevice *dataDevice() const;
+@@ -239,6 +240,8 @@ public:
+ uint32_t axis,
+ wl_fixed_t value) Q_DECL_OVERRIDE;
+
++ void releaseButtons();
++
+ QWaylandInputDevice *mParent;
+ QWaylandWindow *mFocus;
+ uint32_t mEnterSerial;
+@@ -271,6 +274,7 @@ public:
+ void touch_cancel() Q_DECL_OVERRIDE;
+
+ bool allTouchPointsReleased();
++ void releasePoints();
+
+ QWaylandInputDevice *mParent;
+ QWaylandWindow *mFocus;
+diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
+index 48517fc..32b4b89 100644
+--- a/src/client/qwaylandintegration.cpp
++++ b/src/client/qwaylandintegration.cpp
+@@ -119,7 +119,6 @@ public:
+
+ QWaylandIntegration::QWaylandIntegration()
+ : mClientBufferIntegration(0)
+- , mShellIntegration(Q_NULLPTR)
+ , mInputDeviceIntegration(Q_NULLPTR)
+ , mFontDb(new QGenericUnixFontDatabase())
+ , mNativeInterface(new QWaylandNativeInterface(this))
+@@ -131,16 +130,17 @@ QWaylandIntegration::QWaylandIntegration()
+ , mShellIntegrationInitialized(false)
+ {
+ initializeInputDeviceIntegration();
+- mDisplay = new QWaylandDisplay(this);
+- mClipboard = new QWaylandClipboard(mDisplay);
+- mDrag = new QWaylandDrag(mDisplay);
+-
++ mDisplay.reset(new QWaylandDisplay(this));
++#ifndef QT_NO_DRAGANDDROP
++ mClipboard.reset(new QWaylandClipboard(mDisplay.data()));
++ mDrag.reset(new QWaylandDrag(mDisplay.data()));
++#endif
+ QString icStr = QPlatformInputContextFactory::requested();
+ if (!icStr.isNull()) {
+ mInputContext.reset(QPlatformInputContextFactory::create(icStr));
+ } else {
+ //try to use the input context using the wl_text_input interface
+- QPlatformInputContext *ctx = new QWaylandInputContext(mDisplay);
++ QPlatformInputContext *ctx = new QWaylandInputContext(mDisplay.data());
+ mInputContext.reset(ctx);
+
+ //use the traditional way for on screen keyboards for now
+@@ -153,18 +153,11 @@ QWaylandIntegration::QWaylandIntegration()
+
+ QWaylandIntegration::~QWaylandIntegration()
+ {
+- delete mDrag;
+- delete mClipboard;
+-#ifndef QT_NO_ACCESSIBILITY
+- delete mAccessibility;
+-#endif
+- delete mNativeInterface;
+- delete mDisplay;
+ }
+
+ QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const
+ {
+- return mNativeInterface;
++ return mNativeInterface.data();
+ }
+
+ bool QWaylandIntegration::hasCapability(QPlatformIntegration::Capability cap) const
+@@ -217,28 +210,30 @@ QAbstractEventDispatcher *QWaylandIntegration::createEventDispatcher() const
+ void QWaylandIntegration::initialize()
+ {
+ QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
+- QObject::connect(dispatcher, SIGNAL(aboutToBlock()), mDisplay, SLOT(flushRequests()));
+- QObject::connect(dispatcher, SIGNAL(awake()), mDisplay, SLOT(flushRequests()));
++ QObject::connect(dispatcher, SIGNAL(aboutToBlock()), mDisplay.data(), SLOT(flushRequests()));
++ QObject::connect(dispatcher, SIGNAL(awake()), mDisplay.data(), SLOT(flushRequests()));
+
+ int fd = wl_display_get_fd(mDisplay->wl_display());
+- QSocketNotifier *sn = new QSocketNotifier(fd, QSocketNotifier::Read, mDisplay);
+- QObject::connect(sn, SIGNAL(activated(int)), mDisplay, SLOT(flushRequests()));
++ QSocketNotifier *sn = new QSocketNotifier(fd, QSocketNotifier::Read, mDisplay.data());
++ QObject::connect(sn, SIGNAL(activated(int)), mDisplay.data(), SLOT(flushRequests()));
+ }
+
+ QPlatformFontDatabase *QWaylandIntegration::fontDatabase() const
+ {
+- return mFontDb;
++ return mFontDb.data();
+ }
+
++#ifndef QT_NO_DRAGANDDROP
+ QPlatformClipboard *QWaylandIntegration::clipboard() const
+ {
+- return mClipboard;
++ return mClipboard.data();
+ }
+
+ QPlatformDrag *QWaylandIntegration::drag() const
+ {
+- return mDrag;
++ return mDrag.data();
+ }
++#endif // QT_NO_DRAGANDDROP
+
+ QPlatformInputContext *QWaylandIntegration::inputContext() const
+ {
+@@ -263,7 +258,7 @@ QVariant QWaylandIntegration::styleHint(StyleHint hint) const
+ #ifndef QT_NO_ACCESSIBILITY
+ QPlatformAccessibility *QWaylandIntegration::accessibility() const
+ {
+- return mAccessibility;
++ return mAccessibility.data();
+ }
+ #endif
+
+@@ -274,7 +269,7 @@ QPlatformServices *QWaylandIntegration::services() const
+
+ QWaylandDisplay *QWaylandIntegration::display() const
+ {
+- return mDisplay;
++ return mDisplay.data();
+ }
+
+ QStringList QWaylandIntegration::themeNames() const
+@@ -292,7 +287,7 @@ QWaylandClientBufferIntegration *QWaylandIntegration::clientBufferIntegration()
+ if (!mClientBufferIntegrationInitialized)
+ const_cast<QWaylandIntegration *>(this)->initializeClientBufferIntegration();
+
+- return mClientBufferIntegration && mClientBufferIntegration->isValid() ? mClientBufferIntegration : 0;
++ return mClientBufferIntegration && mClientBufferIntegration->isValid() ? mClientBufferIntegration.data() : nullptr;
+ }
+
+ QWaylandServerBufferIntegration *QWaylandIntegration::serverBufferIntegration() const
+@@ -300,7 +295,7 @@ QWaylandServerBufferIntegration *QWaylandIntegration::serverBufferIntegration()
+ if (!mServerBufferIntegrationInitialized)
+ const_cast<QWaylandIntegration *>(this)->initializeServerBufferIntegration();
+
+- return mServerBufferIntegration;
++ return mServerBufferIntegration.data();
+ }
+
+ QWaylandShellIntegration *QWaylandIntegration::shellIntegration() const
+@@ -308,7 +303,7 @@ QWaylandShellIntegration *QWaylandIntegration::shellIntegration() const
+ if (!mShellIntegrationInitialized)
+ const_cast<QWaylandIntegration *>(this)->initializeShellIntegration();
+
+- return mShellIntegration;
++ return mShellIntegration.data();
+ }
+
+ void QWaylandIntegration::initializeClientBufferIntegration()
+@@ -334,10 +329,10 @@ void QWaylandIntegration::initializeClientBufferIntegration()
+
+ QStringList keys = QWaylandClientBufferIntegrationFactory::keys();
+ if (keys.contains(targetKey)) {
+- mClientBufferIntegration = QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList());
++ mClientBufferIntegration.reset(QWaylandClientBufferIntegrationFactory::create(targetKey, QStringList()));
+ }
+ if (mClientBufferIntegration)
+- mClientBufferIntegration->initialize(mDisplay);
++ mClientBufferIntegration->initialize(mDisplay.data());
+ else
+ qWarning("Failed to load client buffer integration: %s\n", qPrintable(targetKey));
+ }
+@@ -364,10 +359,10 @@ void QWaylandIntegration::initializeServerBufferIntegration()
+
+ QStringList keys = QWaylandServerBufferIntegrationFactory::keys();
+ if (keys.contains(targetKey)) {
+- mServerBufferIntegration = QWaylandServerBufferIntegrationFactory::create(targetKey, QStringList());
++ mServerBufferIntegration.reset(QWaylandServerBufferIntegrationFactory::create(targetKey, QStringList()));
+ }
+ if (mServerBufferIntegration)
+- mServerBufferIntegration->initialize(mDisplay);
++ mServerBufferIntegration->initialize(mDisplay.data());
+ else
+ qWarning("Failed to load server buffer integration %s\n", qPrintable(targetKey));
+ }
+@@ -383,7 +378,7 @@ void QWaylandIntegration::initializeShellIntegration()
+ QStringList keys = QWaylandShellIntegrationFactory::keys();
+ if (keys.contains(targetKey)) {
+ qDebug("Using the '%s' shell integration", qPrintable(targetKey));
+- mShellIntegration = QWaylandShellIntegrationFactory::create(targetKey, QStringList());
++ mShellIntegration.reset(QWaylandShellIntegrationFactory::create(targetKey, QStringList()));
+ }
+ } else {
+ QStringList preferredShells;
+@@ -393,15 +388,14 @@ void QWaylandIntegration::initializeShellIntegration()
+
+ Q_FOREACH (QString preferredShell, preferredShells) {
+ if (mDisplay->hasRegistryGlobal(preferredShell)) {
+- mShellIntegration = createShellIntegration(preferredShell);
++ mShellIntegration.reset(createShellIntegration(preferredShell));
+ break;
+ }
+ }
+ }
+
+- if (!mShellIntegration || !mShellIntegration->initialize(mDisplay)) {
+- delete mShellIntegration;
+- mShellIntegration = Q_NULLPTR;
++ if (!mShellIntegration || !mShellIntegration->initialize(mDisplay.data())) {
++ mShellIntegration.reset();
+ qWarning("Failed to load shell integration %s", qPrintable(targetKey));
+ }
+ }
+@@ -425,7 +419,7 @@ void QWaylandIntegration::initializeInputDeviceIntegration()
+
+ QStringList keys = QWaylandInputDeviceIntegrationFactory::keys();
+ if (keys.contains(targetKey)) {
+- mInputDeviceIntegration = QWaylandInputDeviceIntegrationFactory::create(targetKey, QStringList());
++ mInputDeviceIntegration.reset(QWaylandInputDeviceIntegrationFactory::create(targetKey, QStringList()));
+ qDebug("Using the '%s' input device integration", qPrintable(targetKey));
+ } else {
+ qWarning("Wayland inputdevice integration '%s' not found, using default", qPrintable(targetKey));
+@@ -435,9 +429,9 @@ void QWaylandIntegration::initializeInputDeviceIntegration()
+ QWaylandShellIntegration *QWaylandIntegration::createShellIntegration(const QString &interfaceName)
+ {
+ if (interfaceName == QLatin1Literal("wl_shell")) {
+- return new QWaylandWlShellIntegration(mDisplay);
++ return new QWaylandWlShellIntegration(mDisplay.data());
+ } else if (interfaceName == QLatin1Literal("xdg_shell")) {
+- return new QWaylandXdgShellIntegration(mDisplay);
++ return new QWaylandXdgShellIntegration(mDisplay.data());
+ } else {
+ return Q_NULLPTR;
+ }
+diff --git a/src/client/qwaylandintegration_p.h b/src/client/qwaylandintegration_p.h
+index 9a49902..3b91313 100644
+--- a/src/client/qwaylandintegration_p.h
++++ b/src/client/qwaylandintegration_p.h
+@@ -54,6 +54,8 @@
+ #include <qpa/qplatformintegration.h>
+
+ #include <QtWaylandClient/qwaylandclientexport.h>
++#include <QtCore/QScopedPointer>
++
+ QT_BEGIN_NAMESPACE
+
+ namespace QtWaylandClient {
+@@ -85,11 +87,10 @@ public:
+ QPlatformFontDatabase *fontDatabase() const Q_DECL_OVERRIDE;
+
+ QPlatformNativeInterface *nativeInterface() const Q_DECL_OVERRIDE;
+-
++#ifndef QT_NO_DRAGANDDROP
+ QPlatformClipboard *clipboard() const Q_DECL_OVERRIDE;
+-
+ QPlatformDrag *drag() const Q_DECL_OVERRIDE;
+-
++#endif
+ QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE;
+
+ QVariant styleHint(StyleHint hint) const Q_DECL_OVERRIDE;
+@@ -113,10 +114,10 @@ public:
+ virtual QWaylandShellIntegration *shellIntegration() const;
+
+ protected:
+- QWaylandClientBufferIntegration *mClientBufferIntegration;
+- QWaylandServerBufferIntegration *mServerBufferIntegration;
+- QWaylandShellIntegration *mShellIntegration;
+- QWaylandInputDeviceIntegration *mInputDeviceIntegration;
++ QScopedPointer<QWaylandClientBufferIntegration> mClientBufferIntegration;
++ QScopedPointer<QWaylandServerBufferIntegration> mServerBufferIntegration;
++ QScopedPointer<QWaylandShellIntegration> mShellIntegration;
++ QScopedPointer<QWaylandInputDeviceIntegration> mInputDeviceIntegration;
+
+ private:
+ void initializeClientBufferIntegration();
+@@ -125,14 +126,16 @@ private:
+ void initializeInputDeviceIntegration();
+ QWaylandShellIntegration *createShellIntegration(const QString& interfaceName);
+
+- QPlatformFontDatabase *mFontDb;
+- QPlatformClipboard *mClipboard;
+- QPlatformDrag *mDrag;
+- QWaylandDisplay *mDisplay;
+- QPlatformNativeInterface *mNativeInterface;
++ QScopedPointer<QPlatformFontDatabase> mFontDb;
++#ifndef QT_NO_DRAGANDDROP
++ QScopedPointer<QPlatformClipboard> mClipboard;
++ QScopedPointer<QPlatformDrag> mDrag;
++#endif
++ QScopedPointer<QWaylandDisplay> mDisplay;
++ QScopedPointer<QPlatformNativeInterface> mNativeInterface;
+ QScopedPointer<QPlatformInputContext> mInputContext;
+ #ifndef QT_NO_ACCESSIBILITY
+- QPlatformAccessibility *mAccessibility;
++ QScopedPointer<QPlatformAccessibility> mAccessibility;
+ #endif
+ bool mClientBufferIntegrationInitialized;
+ bool mServerBufferIntegrationInitialized;
+diff --git a/src/client/qwaylandnativeinterface.cpp b/src/client/qwaylandnativeinterface.cpp
+index 4a79fb5..52c61ee 100644
+--- a/src/client/qwaylandnativeinterface.cpp
++++ b/src/client/qwaylandnativeinterface.cpp
+@@ -116,6 +116,7 @@ void *QWaylandNativeInterface::nativeResourceForScreen(const QByteArray &resourc
+ return nullptr;
+ }
+
++#ifndef QT_NO_OPENGL
+ void *QWaylandNativeInterface::nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context)
+ {
+ #ifdef QT_WAYLAND_GL_SUPPORT
+@@ -133,6 +134,7 @@ void *QWaylandNativeInterface::nativeResourceForContext(const QByteArray &resour
+
+ return nullptr;
+ }
++#endif // QT_NO_OPENGL
+
+ QVariantMap QWaylandNativeInterface::windowProperties(QPlatformWindow *window) const
+ {
+diff --git a/src/client/qwaylandnativeinterface_p.h b/src/client/qwaylandnativeinterface_p.h
+index 83e3fe5..49e52cd 100644
+--- a/src/client/qwaylandnativeinterface_p.h
++++ b/src/client/qwaylandnativeinterface_p.h
+@@ -72,8 +72,9 @@ public:
+ QWindow *window) Q_DECL_OVERRIDE;
+ void *nativeResourceForScreen(const QByteArray &resourceString,
+ QScreen *screen) Q_DECL_OVERRIDE;
++#ifndef QT_NO_OPENGL
+ void *nativeResourceForContext(const QByteArray &resource, QOpenGLContext *context) Q_DECL_OVERRIDE;
+-
++#endif
+ QVariantMap windowProperties(QPlatformWindow *window) const Q_DECL_OVERRIDE;
+ QVariant windowProperty(QPlatformWindow *window, const QString &name) const Q_DECL_OVERRIDE;
+ QVariant windowProperty(QPlatformWindow *window, const QString &name, const QVariant &defaultValue) const Q_DECL_OVERRIDE;
+diff --git a/src/client/qwaylandshellsurface_p.h b/src/client/qwaylandshellsurface_p.h
+index 79f65b1..b51c252 100644
+--- a/src/client/qwaylandshellsurface_p.h
++++ b/src/client/qwaylandshellsurface_p.h
+@@ -91,19 +91,17 @@ public:
+ virtual void setContentOrientationMask(Qt::ScreenOrientations orientation) { Q_UNUSED(orientation) }
+
+ virtual void sendProperty(const QString &name, const QVariant &value);
+- virtual bool shellManagesActiveState() const { return false; }
+
+ inline QWaylandWindow *window() { return m_window; }
+
++ virtual void setType(Qt::WindowType type, QWaylandWindow *transientParent) = 0;
++
+ protected:
+ virtual void setMaximized() {}
+ virtual void setFullscreen() {}
+ virtual void setNormal() {}
+ virtual void setMinimized() {}
+
+- virtual void setTopLevel() {}
+- virtual void updateTransientParent(QWindow * /*parent*/) {}
+-
+ private:
+ QWaylandWindow *m_window;
+ friend class QWaylandWindow;
+diff --git a/src/client/qwaylandshmbackingstore.cpp b/src/client/qwaylandshmbackingstore.cpp
+index 13f823e..d0d6cfd 100644
+--- a/src/client/qwaylandshmbackingstore.cpp
++++ b/src/client/qwaylandshmbackingstore.cpp
+@@ -185,10 +185,6 @@ void QWaylandShmBackingStore::endPaint()
+ waylandWindow()->setCanResize(true);
+ }
+
+-void QWaylandShmBackingStore::hidden()
+-{
+-}
+-
+ void QWaylandShmBackingStore::ensureSize()
+ {
+ waylandWindow()->setBackingStore(this);
+@@ -215,13 +211,7 @@ void QWaylandShmBackingStore::flush(QWindow *window, const QRegion &region, cons
+
+ QMargins margins = windowDecorationMargins();
+
+- waylandWindow()->attachOffset(mFrontBuffer);
+- mFrontBuffer->setBusy();
+-
+- QVector<QRect> rects = region.rects();
+- foreach (const QRect &rect, rects)
+- waylandWindow()->damage(rect.translated(margins.left(), margins.top()));
+- waylandWindow()->commit();
++ waylandWindow()->commit(mFrontBuffer, region.translated(margins.left(), margins.top()));
+ }
+
+ void QWaylandShmBackingStore::resize(const QSize &size, const QRegion &)
+diff --git a/src/client/qwaylandshmbackingstore_p.h b/src/client/qwaylandshmbackingstore_p.h
+index c3e7635..5068519 100644
+--- a/src/client/qwaylandshmbackingstore_p.h
++++ b/src/client/qwaylandshmbackingstore_p.h
+@@ -96,7 +96,6 @@ public:
+ void resize(const QSize &size);
+ void beginPaint(const QRegion &) Q_DECL_OVERRIDE;
+ void endPaint() Q_DECL_OVERRIDE;
+- void hidden();
+
+ QWaylandAbstractDecoration *windowDecoration() const;
+
+diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
+index 2b7d81f..1ff6686 100644
+--- a/src/client/qwaylandwindow.cpp
++++ b/src/client/qwaylandwindow.cpp
+@@ -96,8 +96,6 @@ QWaylandWindow::QWaylandWindow(QWindow *window)
+ {
+ static WId id = 1;
+ mWindowId = id++;
+- if (window->type() != Qt::Desktop)
+- initWindow();
+ }
+
+ QWaylandWindow::~QWaylandWindow()
+@@ -126,20 +124,30 @@ QWaylandWindow::~QWaylandWindow()
+
+ void QWaylandWindow::initWindow()
+ {
+- init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this)));
++ if (window()->type() == Qt::Desktop)
++ return;
++
++ if (!isInitialized())
++ init(mDisplay->createSurface(static_cast<QtWayland::wl_surface *>(this)));
+
+ if (shouldCreateSubSurface()) {
++ Q_ASSERT(!mSubSurfaceWindow);
++
+ QWaylandWindow *p = static_cast<QWaylandWindow *>(QPlatformWindow::parent());
+ if (::wl_subsurface *ss = mDisplay->createSubSurface(this, p)) {
+ mSubSurfaceWindow = new QWaylandSubSurface(this, p, ss);
+ }
+ } else if (shouldCreateShellSurface()) {
++ Q_ASSERT(!mShellSurface);
++
+ mShellSurface = mDisplay->createShellSurface(this);
+- }
++ if (!mShellSurface)
++ qFatal("Could not create a shell surface object.");
++
++ mShellSurface->setType(window()->type(), transientParent());
+
+- if (mShellSurface) {
+ // Set initial surface title
+- mShellSurface->setTitle(window()->title());
++ setWindowTitle(window()->title());
+
+ // The appId is the desktop entry identifier that should follow the
+ // reverse DNS convention (see http://standards.freedesktop.org/desktop-entry-spec/latest/ar01s02.html).
+@@ -171,17 +179,6 @@ void QWaylandWindow::initWindow()
+ }
+ }
+
+- if (mShellSurface) {
+- if (window()->transientParent()) {
+- if (window()->type() != Qt::Popup) {
+- mShellSurface->updateTransientParent(window()->transientParent());
+- }
+- } else {
+- if (window()->type() != Qt::ToolTip)
+- mShellSurface->setTopLevel();
+- }
+- }
+-
+ // Enable high-dpi rendering. Scale() returns the screen scale factor and will
+ // typically be integer 1 (normal-dpi) or 2 (high-dpi). Call set_buffer_scale()
+ // to inform the compositor that high-resolution buffers will be provided.
+@@ -244,6 +241,9 @@ WId QWaylandWindow::winId() const
+
+ void QWaylandWindow::setParent(const QPlatformWindow *parent)
+ {
++ if (!window()->isVisible())
++ return;
++
+ QWaylandWindow *oldparent = mSubSurfaceWindow ? mSubSurfaceWindow->parent() : 0;
+ if (oldparent == parent)
+ return;
+@@ -261,7 +261,8 @@ void QWaylandWindow::setParent(const QPlatformWindow *parent)
+ void QWaylandWindow::setWindowTitle(const QString &title)
+ {
+ if (mShellSurface) {
+- mShellSurface->setTitle(title);
++ const QString separator = QString::fromUtf8(" \xe2\x80\x94 "); // unicode character U+2014, EM DASH
++ mShellSurface->setTitle(formatWindowTitle(title, separator));
+ }
+
+ if (mWindowDecoration && window()->isVisible())
+@@ -285,8 +286,8 @@ void QWaylandWindow::setGeometry_helper(const QRect &rect)
+ if (mSubSurfaceWindow) {
+ QMargins m = QPlatformWindow::parent()->frameMargins();
+ mSubSurfaceWindow->set_position(rect.x() + m.left(), rect.y() + m.top());
+- } else if (shellSurface() && window()->transientParent() && window()->type() != Qt::Popup)
+- shellSurface()->updateTransientParent(window()->transientParent());
++ mSubSurfaceWindow->parent()->window()->requestUpdate();
++ }
+ }
+
+ void QWaylandWindow::setGeometry(const QRect &rect)
+@@ -311,20 +312,8 @@ void QWaylandWindow::setGeometry(const QRect &rect)
+ void QWaylandWindow::setVisible(bool visible)
+ {
+ if (visible) {
+- if (mShellSurface) {
+- if (window()->type() == Qt::Popup) {
+- QWaylandWindow *parent = transientParent();
+- if (parent) {
+- QWaylandWlShellSurface *wlshellSurface = qobject_cast<QWaylandWlShellSurface*>(mShellSurface);
+- if (wlshellSurface)
+- wlshellSurface->setPopup(parent, mDisplay->lastInputDevice(), mDisplay->lastInputSerial());
+- }
+- } else if (window()->type() == Qt::ToolTip) {
+- if (QWaylandWindow *parent = transientParent()) {
+- mShellSurface->updateTransientParent(parent->window());
+- }
+- }
+- }
++ initWindow();
++ mDisplay->flushRequests();
+
+ setGeometry(window()->geometry());
+ // Don't flush the events here, or else the newly visible window may start drawing, but since
+@@ -336,13 +325,8 @@ void QWaylandWindow::setVisible(bool visible)
+ // case 'this' will be deleted. When that happens, we must abort right away.
+ QPointer<QWaylandWindow> deleteGuard(this);
+ QWindowSystemInterface::flushWindowSystemEvents();
+- if (!deleteGuard.isNull()) {
+- attach(static_cast<QWaylandBuffer *>(0), 0, 0);
+- commit();
+- if (mBackingStore) {
+- mBackingStore->hidden();
+- }
+- }
++ if (!deleteGuard.isNull())
++ reset();
+ }
+ }
+
+@@ -375,7 +359,7 @@ void QWaylandWindow::setMask(const QRegion &mask)
+ wl_region_destroy(region);
+ }
+
+- commit();
++ wl_surface::commit();
+ }
+
+ void QWaylandWindow::configure(uint32_t edges, int32_t width, int32_t height)
+@@ -462,6 +446,7 @@ void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
+ wl_callback_add_listener(callback, &QWaylandWindow::callbackListener, this);
+ mFrameCallback = callback;
+ mWaitingForFrameSync = true;
++ buffer->setBusy();
+
+ attach(buffer->buffer(), x, y);
+ } else {
+@@ -480,6 +465,18 @@ void QWaylandWindow::damage(const QRect &rect)
+ damage(rect.x(), rect.y(), rect.width(), rect.height());
+ }
+
++void QWaylandWindow::commit(QWaylandBuffer *buffer, const QRegion &damage)
++{
++ if (!isInitialized())
++ return;
++
++ attachOffset(buffer);
++ const QVector<QRect> rects = damage.rects();
++ for (const QRect &rect: rects)
++ wl_surface::damage(rect.x(), rect.y(), rect.width(), rect.height());
++ wl_surface::commit();
++}
++
+ const wl_callback_listener QWaylandWindow::callbackListener = {
+ QWaylandWindow::frameCallback
+ };
+@@ -528,11 +525,6 @@ QWaylandSubSurface *QWaylandWindow::subSurfaceWindow() const
+ return mSubSurfaceWindow;
+ }
+
+-bool QWaylandWindow::shellManagesActiveState() const
+-{
+- return mShellSurface && mShellSurface->shellManagesActiveState();
+-}
+-
+ void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orientation)
+ {
+ if (mDisplay->compositorVersion() < 2)
+@@ -561,7 +553,7 @@ void QWaylandWindow::handleContentOrientationChange(Qt::ScreenOrientation orient
+ }
+ set_buffer_transform(transform);
+ // set_buffer_transform is double buffered, we need to commit.
+- commit();
++ wl_surface::commit();
+ }
+
+ void QWaylandWindow::setOrientationMask(Qt::ScreenOrientations mask)
+@@ -687,15 +679,13 @@ static QWindow *topLevelWindow(QWindow *window)
+
+ QWaylandWindow *QWaylandWindow::transientParent() const
+ {
+- if (window()->transientParent()) {
+- // Take the top level window here, since the transient parent may be a QWidgetWindow
+- // or some other window without a shell surface, which is then not able to get mouse
+- // events.
+- return static_cast<QWaylandWindow *>(topLevelWindow(window()->transientParent())->handle());
+- }
+- // Try with the current focus window. It should be the right one and anyway
+- // better than having no parent at all.
+- return mDisplay->lastInputWindow();
++ // Take the top level window here, since the transient parent may be a QWidgetWindow
++ // or some other window without a shell surface, which is then not able to get mouse
++ // events.
++ if (auto transientParent = window()->transientParent())
++ return static_cast<QWaylandWindow *>(topLevelWindow(transientParent)->handle());
++
++ return nullptr;
+ }
+
+ void QWaylandWindow::handleMouse(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e)
+@@ -809,10 +799,12 @@ void QWaylandWindow::requestActivateWindow()
+
+ void QWaylandWindow::unfocus()
+ {
++#ifndef QT_NO_DRAGANDDROP
+ QWaylandInputDevice *inputDevice = mDisplay->currentInputDevice();
+ if (inputDevice && inputDevice->dataDevice()) {
+ inputDevice->dataDevice()->invalidateSelectionOffer();
+ }
++#endif
+ }
+
+ bool QWaylandWindow::isExposed() const
+diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
+index e0c42ac..7e7078f 100644
+--- a/src/client/qwaylandwindow_p.h
++++ b/src/client/qwaylandwindow_p.h
+@@ -132,6 +132,8 @@ public:
+ using QtWayland::wl_surface::damage;
+ void damage(const QRect &rect);
+
++ void commit(QWaylandBuffer *buffer, const QRegion &damage);
++
+ void waitForFrameSync();
+
+ QMargins frameMargins() const Q_DECL_OVERRIDE;
+@@ -143,8 +145,6 @@ public:
+ QWaylandSubSurface *subSurfaceWindow() const;
+ QWaylandScreen *screen() const { return mScreen; }
+
+- bool shellManagesActiveState() const;
+-
+ void handleContentOrientationChange(Qt::ScreenOrientation orientation) Q_DECL_OVERRIDE;
+ void setOrientationMask(Qt::ScreenOrientations mask);
+
+diff --git a/src/client/qwaylandwlshellintegration.cpp b/src/client/qwaylandwlshellintegration.cpp
+index 6a9220d..ce7c783 100644
+--- a/src/client/qwaylandwlshellintegration.cpp
++++ b/src/client/qwaylandwlshellintegration.cpp
+@@ -52,6 +52,12 @@ QWaylandWlShellIntegration::QWaylandWlShellIntegration(QWaylandDisplay *display)
+ }
+ }
+
++bool QWaylandWlShellIntegration::initialize(QWaylandDisplay *display)
++{
++ QWaylandShellIntegration::initialize(display);
++ return m_wlShell != nullptr;
++};
++
+ QWaylandShellSurface *QWaylandWlShellIntegration::createShellSurface(QWaylandWindow *window)
+ {
+ return new QWaylandWlShellSurface(m_wlShell->get_shell_surface(window->object()), window);
+diff --git a/src/client/qwaylandwlshellintegration_p.h b/src/client/qwaylandwlshellintegration_p.h
+index 8531eb3..9082c76 100644
+--- a/src/client/qwaylandwlshellintegration_p.h
++++ b/src/client/qwaylandwlshellintegration_p.h
+@@ -58,7 +58,7 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandWlShellIntegration : public QWaylandShellI
+ {
+ public:
+ QWaylandWlShellIntegration(QWaylandDisplay* display);
+- bool initialize(QWaylandDisplay *) Q_DECL_OVERRIDE { return m_wlShell != Q_NULLPTR; }
++ bool initialize(QWaylandDisplay *) Q_DECL_OVERRIDE;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) Q_DECL_OVERRIDE;
+
+ private:
+diff --git a/src/client/qwaylandwlshellsurface.cpp b/src/client/qwaylandwlshellsurface.cpp
+index 3527015..77434e9 100644
+--- a/src/client/qwaylandwlshellsurface.cpp
++++ b/src/client/qwaylandwlshellsurface.cpp
+@@ -215,6 +215,16 @@ void QWaylandWlShellSurface::setPopup(QWaylandWindow *parent, QWaylandInputDevic
+ transientPos.x(), transientPos.y(), 0);
+ }
+
++void QWaylandWlShellSurface::setType(Qt::WindowType type, QWaylandWindow *transientParent)
++{
++ if (type == Qt::Popup && transientParent)
++ setPopup(transientParent, m_window->display()->lastInputDevice(), m_window->display()->lastInputSerial());
++ else if (transientParent)
++ updateTransientParent(transientParent->window());
++ else
++ setTopLevel();
++}
++
+ void QWaylandWlShellSurface::shell_surface_ping(uint32_t serial)
+ {
+ pong(serial);
+diff --git a/src/client/qwaylandwlshellsurface_p.h b/src/client/qwaylandwlshellsurface_p.h
+index ef732ef..af86276 100644
+--- a/src/client/qwaylandwlshellsurface_p.h
++++ b/src/client/qwaylandwlshellsurface_p.h
+@@ -92,14 +92,16 @@ public:
+ void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE;
+ void sendProperty(const QString &name, const QVariant &value) Q_DECL_OVERRIDE;
+
++ void setType(Qt::WindowType type, QWaylandWindow *transientParent) override;
++
+ private:
+ void setMaximized() Q_DECL_OVERRIDE;
+ void setFullscreen() Q_DECL_OVERRIDE;
+ void setNormal() Q_DECL_OVERRIDE;
+ void setMinimized() Q_DECL_OVERRIDE;
+
+- void setTopLevel() Q_DECL_OVERRIDE;
+- void updateTransientParent(QWindow *parent) Q_DECL_OVERRIDE;
++ void setTopLevel();
++ void updateTransientParent(QWindow *parent);
+ void setPopup(QWaylandWindow *parent, QWaylandInputDevice *device, int serial);
+
+ QWaylandWindow *m_window;
+diff --git a/src/client/qwaylandxdgpopup_p.cpp b/src/client/qwaylandxdgpopup.cpp
+similarity index 93%
+rename from src/client/qwaylandxdgpopup_p.cpp
+rename to src/client/qwaylandxdgpopup.cpp
+index abc2527..57800f1 100644
+--- a/src/client/qwaylandxdgpopup_p.cpp
++++ b/src/client/qwaylandxdgpopup.cpp
+@@ -56,6 +56,12 @@ QWaylandXdgPopup::~QWaylandXdgPopup()
+ delete m_extendedWindow;
+ }
+
++void QWaylandXdgPopup::setType(Qt::WindowType type, QWaylandWindow *transientParent)
++{
++ Q_UNUSED(type);
++ Q_UNUSED(transientParent);
++}
++
+ }
+
+ QT_END_NAMESPACE
+diff --git a/src/client/qwaylandxdgpopup_p.h b/src/client/qwaylandxdgpopup_p.h
+index ff58041..64bb4d9 100644
+--- a/src/client/qwaylandxdgpopup_p.h
++++ b/src/client/qwaylandxdgpopup_p.h
+@@ -68,6 +68,8 @@ public:
+ QWaylandXdgPopup(struct ::xdg_popup *popup, QWaylandWindow *window);
+ virtual ~QWaylandXdgPopup();
+
++ void setType(Qt::WindowType type, QWaylandWindow *transientParent) override;
++
+ private:
+ QWaylandExtendedSurface *m_extendedWindow;
+ };
+diff --git a/src/client/qwaylandxdgshell.cpp b/src/client/qwaylandxdgshell.cpp
+index 6a378b8..6a99306 100644
+--- a/src/client/qwaylandxdgshell.cpp
++++ b/src/client/qwaylandxdgshell.cpp
+@@ -54,11 +54,13 @@ namespace QtWaylandClient {
+
+ QWaylandXdgShell::QWaylandXdgShell(struct ::xdg_shell *shell)
+ : QtWayland::xdg_shell(shell)
++ , m_popupSerial(0)
+ {
+ }
+
+ QWaylandXdgShell::QWaylandXdgShell(struct ::wl_registry *registry, uint32_t id)
+ : QtWayland::xdg_shell(registry, id, 1)
++ , m_popupSerial(0)
+ {
+ use_unstable_version(QtWayland::xdg_shell::version_current);
+ }
+@@ -75,15 +77,26 @@ QWaylandXdgSurface *QWaylandXdgShell::createXdgSurface(QWaylandWindow *window)
+
+ QWaylandXdgPopup *QWaylandXdgShell::createXdgPopup(QWaylandWindow *window)
+ {
+- QWaylandWindow *parentWindow = window->transientParent();
++ QWaylandWindow *parentWindow = m_popups.empty() ? window->transientParent() : m_popups.last();
+ ::wl_surface *parentSurface = parentWindow->object();
++
+ QWaylandInputDevice *inputDevice = window->display()->lastInputDevice();
++ if (m_popupSerial == 0)
++ m_popupSerial = inputDevice->serial();
+ ::wl_seat *seat = inputDevice->wl_seat();
+- uint serial = inputDevice->serial();
+- QPoint position = window->geometry().topLeft();
++
++ QPoint position = window->geometry().topLeft() - parentWindow->geometry().topLeft();
+ int x = position.x() + parentWindow->frameMargins().left();
+ int y = position.y() + parentWindow->frameMargins().top();
+- return new QWaylandXdgPopup(get_xdg_popup(window->object(), parentSurface, seat, serial, x, y), window);
++
++ auto popup = new QWaylandXdgPopup(get_xdg_popup(window->object(), parentSurface, seat, m_popupSerial, x, y), window);
++ m_popups.append(window);
++ QObject::connect(popup, &QWaylandXdgPopup::destroyed, [this, window](){
++ m_popups.removeOne(window);
++ if (m_popups.empty())
++ m_popupSerial = 0;
++ });
++ return popup;
+ }
+
+ void QWaylandXdgShell::xdg_shell_ping(uint32_t serial)
+diff --git a/src/client/qwaylandxdgshell_p.h b/src/client/qwaylandxdgshell_p.h
+index c04a9ce..8b35e36 100644
+--- a/src/client/qwaylandxdgshell_p.h
++++ b/src/client/qwaylandxdgshell_p.h
+@@ -52,6 +52,7 @@
+ //
+
+ #include <QtCore/QSize>
++#include <QtCore/QVector>
+
+ #include <wayland-client.h>
+
+@@ -82,6 +83,9 @@ public:
+
+ private:
+ void xdg_shell_ping(uint32_t serial) Q_DECL_OVERRIDE;
++
++ QVector<QWaylandWindow *> m_popups;
++ uint m_popupSerial;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/src/client/qwaylandxdgshellintegration.cpp b/src/client/qwaylandxdgshellintegration.cpp
+index b6b1d9d..a48157d 100644
+--- a/src/client/qwaylandxdgshellintegration.cpp
++++ b/src/client/qwaylandxdgshellintegration.cpp
+@@ -54,6 +54,12 @@ QWaylandXdgShellIntegration::QWaylandXdgShellIntegration(QWaylandDisplay *displa
+ }
+ }
+
++bool QWaylandXdgShellIntegration::initialize(QWaylandDisplay *display)
++{
++ QWaylandShellIntegration::initialize(display);
++ return m_xdgShell != nullptr;
++}
++
+ QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWindow *window)
+ {
+ if (window->window()->type() == Qt::WindowType::Popup)
+@@ -62,6 +68,13 @@ QWaylandShellSurface *QWaylandXdgShellIntegration::createShellSurface(QWaylandWi
+ return m_xdgShell->createXdgSurface(window);
+ }
+
++void QWaylandXdgShellIntegration::handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
++ if (newFocus && qobject_cast<QWaylandXdgPopup *>(newFocus->shellSurface()))
++ m_display->handleWindowActivated(newFocus);
++ if (oldFocus && qobject_cast<QWaylandXdgPopup *>(oldFocus->shellSurface()))
++ m_display->handleWindowDeactivated(oldFocus);
++}
++
+ }
+
+ QT_END_NAMESPACE
+diff --git a/src/client/qwaylandxdgshellintegration_p.h b/src/client/qwaylandxdgshellintegration_p.h
+index 29374ff..e0e6bda 100644
+--- a/src/client/qwaylandxdgshellintegration_p.h
++++ b/src/client/qwaylandxdgshellintegration_p.h
+@@ -59,8 +59,9 @@ class Q_WAYLAND_CLIENT_EXPORT QWaylandXdgShellIntegration : public QWaylandShell
+ {
+ public:
+ QWaylandXdgShellIntegration(QWaylandDisplay *display);
+- bool initialize(QWaylandDisplay *) Q_DECL_OVERRIDE { return m_xdgShell != Q_NULLPTR; }
++ bool initialize(QWaylandDisplay *display) Q_DECL_OVERRIDE;
+ QWaylandShellSurface *createShellSurface(QWaylandWindow *window) Q_DECL_OVERRIDE;
++ void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) Q_DECL_OVERRIDE;
+
+ private:
+ QWaylandXdgShell *m_xdgShell;
+diff --git a/src/client/qwaylandxdgsurface.cpp b/src/client/qwaylandxdgsurface.cpp
+index 4f9d8cf..fe8761e 100644
+--- a/src/client/qwaylandxdgsurface.cpp
++++ b/src/client/qwaylandxdgsurface.cpp
+@@ -128,17 +128,13 @@ void QWaylandXdgSurface::setMinimized()
+ set_minimized();
+ }
+
+-void QWaylandXdgSurface::setTopLevel()
++void QWaylandXdgSurface::updateTransientParent(QWaylandWindow *parent)
+ {
+- // There's no xdg_shell_surface API for this, ignoring
+-}
+-
+-void QWaylandXdgSurface::updateTransientParent(QWindow *parent)
+-{
+- QWaylandWindow *parent_wayland_window = static_cast<QWaylandWindow *>(parent->handle());
+- if (!parent_wayland_window)
++ if (!parent)
+ return;
+- set_parent(m_shell->get_xdg_surface(parent_wayland_window->object()));
++ auto parentXdgSurface = qobject_cast<QWaylandXdgSurface *>(parent->shellSurface());
++ Q_ASSERT(parentXdgSurface);
++ set_parent(parentXdgSurface->object());
+ }
+
+ void QWaylandXdgSurface::setTitle(const QString & title)
+@@ -181,6 +177,13 @@ void QWaylandXdgSurface::sendProperty(const QString &name, const QVariant &value
+ m_extendedWindow->updateGenericProperty(name, value);
+ }
+
++void QWaylandXdgSurface::setType(Qt::WindowType type, QWaylandWindow *transientParent)
++{
++ Q_UNUSED(type)
++ if (transientParent)
++ updateTransientParent(transientParent);
++}
++
+ void QWaylandXdgSurface::xdg_surface_configure(int32_t width, int32_t height, struct wl_array *states,uint32_t serial)
+ {
+ uint32_t *state = reinterpret_cast<uint32_t*>(states->data);
+diff --git a/src/client/qwaylandxdgsurface_p.h b/src/client/qwaylandxdgsurface_p.h
+index 27decab..265d3ba 100644
+--- a/src/client/qwaylandxdgsurface_p.h
++++ b/src/client/qwaylandxdgsurface_p.h
+@@ -96,19 +96,18 @@ public:
+ void setWindowFlags(Qt::WindowFlags flags) Q_DECL_OVERRIDE;
+ void sendProperty(const QString &name, const QVariant &value) Q_DECL_OVERRIDE;
+
+- bool shellManagesActiveState() const Q_DECL_OVERRIDE { return true; }
+-
+ bool isFullscreen() const { return m_fullscreen; }
+ bool isMaximized() const { return m_maximized; }
+
++ void setType(Qt::WindowType type, QWaylandWindow *transientParent) override;
++
+ private:
+ void setMaximized() Q_DECL_OVERRIDE;
+ void setFullscreen() Q_DECL_OVERRIDE;
+ void setNormal() Q_DECL_OVERRIDE;
+ void setMinimized() Q_DECL_OVERRIDE;
+
+- void setTopLevel() Q_DECL_OVERRIDE;
+- void updateTransientParent(QWindow *parent) Q_DECL_OVERRIDE;
++ void updateTransientParent(QWaylandWindow *parent);
+
+ private:
+ QWaylandWindow *m_window;
+diff --git a/src/client/shellintegration/qwaylandshellintegration_p.h b/src/client/shellintegration/qwaylandshellintegration_p.h
+index e8e46ec..144e583 100644
+--- a/src/client/shellintegration/qwaylandshellintegration_p.h
++++ b/src/client/shellintegration/qwaylandshellintegration_p.h
+@@ -53,6 +53,7 @@
+
+ #include <QtCore/qglobal.h>
+ #include <QtWaylandClient/qwaylandclientexport.h>
++#include <QtWaylandClient/private/qwaylanddisplay_p.h>
+
+ QT_BEGIN_NAMESPACE
+
+@@ -68,8 +69,20 @@ public:
+ QWaylandShellIntegration() {}
+ virtual ~QWaylandShellIntegration() {}
+
+- virtual bool initialize(QWaylandDisplay *display) = 0;
++ virtual bool initialize(QWaylandDisplay *display) {
++ m_display = display;
++ return true;
++ }
+ virtual QWaylandShellSurface *createShellSurface(QWaylandWindow *window) = 0;
++ virtual void handleKeyboardFocusChanged(QWaylandWindow *newFocus, QWaylandWindow *oldFocus) {
++ if (newFocus)
++ m_display->handleWindowActivated(newFocus);
++ if (oldFocus)
++ m_display->handleWindowDeactivated(oldFocus);
++ }
++
++protected:
++ QWaylandDisplay *m_display;
+ };
+
+ }
+diff --git a/src/compositor/compositor_api/qwaylandoutputmode.h b/src/compositor/compositor_api/qwaylandoutputmode.h
+index 4ef57f2..aa44be9 100644
+--- a/src/compositor/compositor_api/qwaylandoutputmode.h
++++ b/src/compositor/compositor_api/qwaylandoutputmode.h
+@@ -66,6 +66,7 @@ private:
+ void setWidth(int width);
+ void setHeight(int height);
+ };
++Q_DECLARE_TYPEINFO(QWaylandOutputMode, Q_MOVABLE_TYPE);
+
+ QT_END_NAMESPACE
+
+diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp
+index f0454b7..d57cbb4 100644
+--- a/src/compositor/compositor_api/qwaylandquickitem.cpp
++++ b/src/compositor/compositor_api/qwaylandquickitem.cpp
+@@ -653,6 +653,9 @@ void QWaylandQuickItem::touchEvent(QTouchEvent *event)
+ seat->sendMouseMoveEvent(d->view.data(), pointPos, mapToScene(pointPos));
+ }
+ seat->sendFullTouchEvent(surface(), event);
++
++ if (event->type() == QEvent::TouchBegin && d->focusOnClick)
++ takeFocus(seat);
+ } else {
+ event->ignore();
+ }
+@@ -921,7 +924,7 @@ void QWaylandQuickItem::updateSize()
+ * \qmlproperty bool QtWaylandCompositor::WaylandQuickItem::focusOnClick
+ *
+ * This property specifies whether the WaylandQuickItem should take focus when
+- * it is clicked.
++ * it is clicked or touched.
+ *
+ * The default is \c true.
+ */
+@@ -930,7 +933,7 @@ void QWaylandQuickItem::updateSize()
+ * \property QWaylandQuickItem::focusOnClick
+ *
+ * This property specifies whether the QWaylandQuickItem should take focus when
+- * it is clicked.
++ * it is clicked or touched.
+ *
+ * The default is \c true.
+ */
+@@ -1071,11 +1074,16 @@ void QWaylandQuickItem::updateBuffer(bool hasBuffer)
+ void QWaylandQuickItem::updateWindow()
+ {
+ Q_D(QWaylandQuickItem);
++
++ QQuickWindow *newWindow = window();
++ if (newWindow == d->connectedWindow)
++ return;
++
+ if (d->connectedWindow) {
+ disconnect(d->connectedWindow, &QQuickWindow::beforeSynchronizing, this, &QWaylandQuickItem::beforeSync);
+ }
+
+- d->connectedWindow = window();
++ d->connectedWindow = newWindow;
+
+ if (d->connectedWindow) {
+ connect(d->connectedWindow, &QQuickWindow::beforeSynchronizing, this, &QWaylandQuickItem::beforeSync, Qt::DirectConnection);
+diff --git a/src/compositor/compositor_api/qwaylandquickitem_p.h b/src/compositor/compositor_api/qwaylandquickitem_p.h
+index c308299..441ac97 100644
+--- a/src/compositor/compositor_api/qwaylandquickitem_p.h
++++ b/src/compositor/compositor_api/qwaylandquickitem_p.h
+@@ -110,7 +110,7 @@ public:
+ , oldSurface(Q_NULLPTR)
+ , provider(Q_NULLPTR)
+ , paintEnabled(true)
+- , touchEventsEnabled(false)
++ , touchEventsEnabled(true)
+ , inputEventsEnabled(true)
+ , isDragging(false)
+ , newTexture(false)
+@@ -142,6 +142,8 @@ public:
+ QObject::connect(view.data(), &QWaylandView::outputChanged, q, &QWaylandQuickItem::outputChanged);
+ QObject::connect(view.data(), &QWaylandView::bufferLockedChanged, q, &QWaylandQuickItem::bufferLockedChanged);
+ QObject::connect(view.data(), &QWaylandView::allowDiscardFrontBufferChanged, q, &QWaylandQuickItem::allowDiscardFrontBuffer);
++
++ q->updateWindow();
+ }
+
+ void setInputEventsEnabled(bool enable)
+diff --git a/src/compositor/compositor_api/qwaylandseat.cpp b/src/compositor/compositor_api/qwaylandseat.cpp
+index 169d5de..f6a5276 100644
+--- a/src/compositor/compositor_api/qwaylandseat.cpp
++++ b/src/compositor/compositor_api/qwaylandseat.cpp
+@@ -257,8 +257,8 @@ void QWaylandSeat::sendKeyReleaseEvent(uint code)
+ }
+
+ /*!
+- * Sends a touch point event with the given \a id and \a state to the touch device. The position
+- * of the touch point is given by \a point.
++ * Sends a touch point event to the \a surface on a touch device with the given
++ * \a id, \a point and \a state.
+ *
+ * Returns the serial for the touch up or touch down event.
+ */
+@@ -273,7 +273,7 @@ uint QWaylandSeat::sendTouchPointEvent(QWaylandSurface *surface, int id, const Q
+ }
+
+ /*!
+- * Sends a frame event to the touch device.
++ * Sends a frame event to the touch device of a \a client.
+ */
+ void QWaylandSeat::sendTouchFrameEvent(QWaylandClient *client)
+ {
+@@ -283,7 +283,7 @@ void QWaylandSeat::sendTouchFrameEvent(QWaylandClient *client)
+ }
+
+ /*!
+- * Sends a cancel event to the touch device.
++ * Sends a cancel event to the touch device of a \a client.
+ */
+ void QWaylandSeat::sendTouchCancelEvent(QWaylandClient *client)
+ {
+@@ -293,7 +293,7 @@ void QWaylandSeat::sendTouchCancelEvent(QWaylandClient *client)
+ }
+
+ /*!
+- * Sends the \a event to the touch device.
++ * Sends the \a event to the specified \a surface on the touch device.
+ */
+ void QWaylandSeat::sendFullTouchEvent(QWaylandSurface *surface, QTouchEvent *event)
+ {
+diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp
+index 80e8715..f79fd57 100644
+--- a/src/compositor/compositor_api/qwaylandsurface.cpp
++++ b/src/compositor/compositor_api/qwaylandsurface.cpp
+@@ -269,7 +269,7 @@ void QWaylandSurfacePrivate::surface_commit(Resource *)
+ {
+ Q_Q(QWaylandSurface);
+
+- if (pending.buffer.hasBuffer())
++ if (pending.buffer.hasBuffer() || pending.newlyAttached)
+ bufferRef = pending.buffer;
+
+ auto buffer = bufferRef.buffer();
+@@ -872,13 +872,13 @@ void QWaylandSurfacePrivate::Subsurface::subsurface_set_desync(wl_subsurface::Re
+ /*!
+ * \qmlsignal void QtWaylandCompositor::WaylandSurface::dragStarted(object drag)
+ *
+- * This signal is emitted when a drag has started from this surface.
++ * This signal is emitted when a \a drag has started from this surface.
+ */
+
+ /*!
+ * \fn void QWaylandSurface::dragStarted(QWaylandDrag *drag)
+ *
+- * This signal is emitted when a drag has started from this surface.
++ * This signal is emitted when a \a drag has started from this surface.
+ */
+
+ QT_END_NAMESPACE
+diff --git a/src/compositor/compositor_api/qwaylandtouch.cpp b/src/compositor/compositor_api/qwaylandtouch.cpp
+index 168edc4..92a8f5c 100644
+--- a/src/compositor/compositor_api/qwaylandtouch.cpp
++++ b/src/compositor/compositor_api/qwaylandtouch.cpp
+@@ -133,7 +133,7 @@ QWaylandCompositor *QWaylandTouch::compositor() const
+ }
+
+ /*!
+- * Sends a touch point event for the touch device with the given \a id,
++ * Sends a touch point event to the touch device of \a surface with the given \a id,
+ * \a position, and \a state.
+ *
+ * Returns the serial of the down or up event if sent, otherwise 0.
+@@ -162,7 +162,7 @@ uint QWaylandTouch::sendTouchPointEvent(QWaylandSurface *surface, int id, const
+ }
+
+ /*!
+- * Sends a touch frame event for the touch device. This indicates the end of a
++ * Sends a touch frame event to the touch device of a \a client. This indicates the end of a
+ * contact point list.
+ */
+ void QWaylandTouch::sendFrameEvent(QWaylandClient *client)
+@@ -174,7 +174,7 @@ void QWaylandTouch::sendFrameEvent(QWaylandClient *client)
+ }
+
+ /*!
+- * Sends a touch cancel event for the touch device.
++ * Sends a touch cancel event to the touch device of a \a client.
+ */
+ void QWaylandTouch::sendCancelEvent(QWaylandClient *client)
+ {
+@@ -185,8 +185,8 @@ void QWaylandTouch::sendCancelEvent(QWaylandClient *client)
+ }
+
+ /*!
+- * Sends all the touch points in \a event for this touch device, followed
+- * by a touch frame event.
++ * Sends all touch points in \a event to the specified \a surface,
++ * followed by a touch frame event.
+ *
+ * \sa sendTouchPointEvent(), sendFrameEvent()
+ */
+diff --git a/src/compositor/extensions/qwaylandivisurface.cpp b/src/compositor/extensions/qwaylandivisurface.cpp
+index fc3102d..06e12a5 100644
+--- a/src/compositor/extensions/qwaylandivisurface.cpp
++++ b/src/compositor/extensions/qwaylandivisurface.cpp
+@@ -68,7 +68,7 @@ QWaylandIviSurface::QWaylandIviSurface()
+
+ /*!
+ * Constructs a QWaylandIviSurface for \a surface and initializes it with the
+- * given \a application, \a surface, \a iviId, and resource \a res.
++ * given \a application, \a surface, \a iviId, and \a resource.
+ */
+ QWaylandIviSurface::QWaylandIviSurface(QWaylandIviApplication *application, QWaylandSurface *surface, uint iviId, const QWaylandResource &resource)
+ : QWaylandShellSurfaceTemplate<QWaylandIviSurface>(*new QWaylandIviSurfacePrivate())
+@@ -129,7 +129,7 @@ QWaylandSurface *QWaylandIviSurface::surface() const
+ */
+
+ /*!
+- * \property QWaylandClient::iviId
++ * \property QWaylandIviSurface::iviId
+ *
+ * This property holds the ivi id of this QWaylandIviSurface.
+ */
+diff --git a/src/compositor/extensions/qwaylandivisurface.h b/src/compositor/extensions/qwaylandivisurface.h
+index 37c37c0..ec53650 100644
+--- a/src/compositor/extensions/qwaylandivisurface.h
++++ b/src/compositor/extensions/qwaylandivisurface.h
+@@ -81,7 +81,7 @@ Q_SIGNALS:
+ void iviIdChanged();
+
+ private:
+- void initialize();
++ void initialize() Q_DECL_OVERRIDE;
+ };
+
+ QT_END_NAMESPACE
+diff --git a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp
+index f6a88e4..91f9d77 100644
+--- a/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp
++++ b/src/compositor/extensions/qwaylandquickshellsurfaceitem.cpp
+@@ -208,7 +208,7 @@ bool QWaylandQuickShellEventFilter::eventFilter(QObject *receiver, QEvent *e)
+ QMouseEvent *event = static_cast<QMouseEvent*>(e);
+ QWaylandQuickShellSurfaceItem *shellSurfaceItem = qobject_cast<QWaylandQuickShellSurfaceItem*>(item);
+ bool finalRelease = (event->type() == QEvent::MouseButtonRelease) && (event->buttons() == Qt::NoButton);
+- bool popupClient = shellSurfaceItem && shellSurfaceItem->surface()->client() == client;
++ bool popupClient = shellSurfaceItem && shellSurfaceItem->surface() && shellSurfaceItem->surface()->client() == client;
+
+ if (waitForRelease) {
+ // We are eating events until all mouse buttons are released
+diff --git a/src/compositor/extensions/qwaylandwlshell.cpp b/src/compositor/extensions/qwaylandwlshell.cpp
+index 3145c66..9b43467 100644
+--- a/src/compositor/extensions/qwaylandwlshell.cpp
++++ b/src/compositor/extensions/qwaylandwlshell.cpp
+@@ -335,7 +335,7 @@ QList<QWaylandWlShellSurface *> QWaylandWlShell::shellSurfacesForClient(QWayland
+ Q_D(const QWaylandWlShell);
+ QList<QWaylandWlShellSurface *> surfsForClient;
+ Q_FOREACH (QWaylandWlShellSurface *shellSurface, d->m_shellSurfaces) {
+- if (shellSurface->surface()->client() == client)
++ if (shellSurface->surface() && shellSurface->surface()->client() == client)
+ surfsForClient.append(shellSurface);
+ }
+ return surfsForClient;
+@@ -347,7 +347,7 @@ QList<QWaylandWlShellSurface *> QWaylandWlShell::mappedPopups() const
+ QList<QWaylandWlShellSurface *> popupSurfaces;
+ Q_FOREACH (QWaylandWlShellSurface *shellSurface, d->m_shellSurfaces) {
+ if (shellSurface->windowType() == Qt::WindowType::Popup
+- && shellSurface->surface()->hasContent()) {
++ && shellSurface->surface() && shellSurface->surface()->hasContent()) {
+ popupSurfaces.append(shellSurface);
+ }
+ }
+@@ -359,7 +359,7 @@ QWaylandClient *QWaylandWlShell::popupClient() const
+ Q_D(const QWaylandWlShell);
+ Q_FOREACH (QWaylandWlShellSurface *shellSurface, d->m_shellSurfaces) {
+ if (shellSurface->windowType() == Qt::WindowType::Popup
+- && shellSurface->surface()->hasContent()) {
++ && shellSurface->surface() && shellSurface->surface()->hasContent()) {
+ return shellSurface->surface()->client();
+ }
+ }
+diff --git a/src/compositor/extensions/qwaylandwlshell_p.h b/src/compositor/extensions/qwaylandwlshell_p.h
+index 5e89030..a087f6f 100644
+--- a/src/compositor/extensions/qwaylandwlshell_p.h
++++ b/src/compositor/extensions/qwaylandwlshell_p.h
+@@ -98,7 +98,7 @@ public:
+
+ private:
+ QWaylandWlShell *m_shell;
+- QWaylandSurface *m_surface;
++ QPointer<QWaylandSurface> m_surface;
+
+ QSet<uint32_t> m_pings;
+
+diff --git a/src/compositor/extensions/qwaylandwlshellintegration.cpp b/src/compositor/extensions/qwaylandwlshellintegration.cpp
+index 30e4704..761a902 100644
+--- a/src/compositor/extensions/qwaylandwlshellintegration.cpp
++++ b/src/compositor/extensions/qwaylandwlshellintegration.cpp
+@@ -55,17 +55,17 @@ WlShellIntegration::WlShellIntegration(QWaylandQuickShellSurfaceItem *item)
+ , nextState(State::Windowed)
+ {
+ m_item->setSurface(m_shellSurface->surface());
+- connect(m_shellSurface, &QWaylandWlShellSurface::startMove, this, &WlShellIntegration::handleStartMove);
+- connect(m_shellSurface, &QWaylandWlShellSurface::startResize, this, &WlShellIntegration::handleStartResize);
++ connect(m_shellSurface.data(), &QWaylandWlShellSurface::startMove, this, &WlShellIntegration::handleStartMove);
++ connect(m_shellSurface.data(), &QWaylandWlShellSurface::startResize, this, &WlShellIntegration::handleStartResize);
+ connect(m_shellSurface->surface(), &QWaylandSurface::redraw, this, &WlShellIntegration::handleRedraw);
+ connect(m_shellSurface->surface(), &QWaylandSurface::offsetForNextFrame, this, &WlShellIntegration::adjustOffsetForNextFrame);
+ connect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged, this, &WlShellIntegration::handleSurfaceHasContentChanged);
+- connect(m_shellSurface, &QWaylandWlShellSurface::setDefaultToplevel, this, &WlShellIntegration::handleSetDefaultTopLevel);
+- connect(m_shellSurface, &QWaylandWlShellSurface::setTransient, this, &WlShellIntegration::handleSetTransient);
+- connect(m_shellSurface, &QWaylandWlShellSurface::setMaximized, this, &WlShellIntegration::handleSetMaximized);
+- connect(m_shellSurface, &QWaylandWlShellSurface::setFullScreen, this, &WlShellIntegration::handleSetFullScreen);
+- connect(m_shellSurface, &QWaylandWlShellSurface::setPopup, this, &WlShellIntegration::handleSetPopup);
+- connect(m_shellSurface, &QWaylandWlShellSurface::destroyed, this, &WlShellIntegration::handleShellSurfaceDestroyed);
++ connect(m_shellSurface.data(), &QWaylandWlShellSurface::setDefaultToplevel, this, &WlShellIntegration::handleSetDefaultTopLevel);
++ connect(m_shellSurface.data(), &QWaylandWlShellSurface::setTransient, this, &WlShellIntegration::handleSetTransient);
++ connect(m_shellSurface.data(), &QWaylandWlShellSurface::setMaximized, this, &WlShellIntegration::handleSetMaximized);
++ connect(m_shellSurface.data(), &QWaylandWlShellSurface::setFullScreen, this, &WlShellIntegration::handleSetFullScreen);
++ connect(m_shellSurface.data(), &QWaylandWlShellSurface::setPopup, this, &WlShellIntegration::handleSetPopup);
++ connect(m_shellSurface.data(), &QWaylandWlShellSurface::destroyed, this, &WlShellIntegration::handleShellSurfaceDestroyed);
+ }
+
+ void WlShellIntegration::handleStartMove(QWaylandSeat *seat)
+@@ -182,8 +182,9 @@ void WlShellIntegration::handleSetPopup(QWaylandSeat *seat, QWaylandSurface *par
+ }
+
+ isPopup = true;
+- QWaylandQuickShellEventFilter::startFilter(m_shellSurface->surface()->client(), [&]() {
+- m_shellSurface->shell()->closeAllPopups();
++ auto shell = m_shellSurface->shell();
++ QWaylandQuickShellEventFilter::startFilter(m_shellSurface->surface()->client(), [shell]() {
++ shell->closeAllPopups();
+ });
+
+ QObject::connect(m_shellSurface->surface(), &QWaylandSurface::hasContentChanged,
+diff --git a/src/compositor/extensions/qwaylandwlshellintegration_p.h b/src/compositor/extensions/qwaylandwlshellintegration_p.h
+index bbdfbd7..c0bbcfd 100644
+--- a/src/compositor/extensions/qwaylandwlshellintegration_p.h
++++ b/src/compositor/extensions/qwaylandwlshellintegration_p.h
+@@ -88,7 +88,7 @@ private:
+ void handlePopupRemoved();
+
+ QWaylandQuickShellSurfaceItem *m_item;
+- QWaylandWlShellSurface *m_shellSurface;
++ QPointer<QWaylandWlShellSurface> m_shellSurface;
+ GrabberState grabberState;
+ struct {
+ QWaylandSeat *seat;
+diff --git a/src/compositor/extensions/qwaylandxdgshellv5.cpp b/src/compositor/extensions/qwaylandxdgshellv5.cpp
+index b73b84d..fd23865 100644
+--- a/src/compositor/extensions/qwaylandxdgshellv5.cpp
++++ b/src/compositor/extensions/qwaylandxdgshellv5.cpp
+@@ -912,13 +912,15 @@ QSize QWaylandXdgSurfaceV5::sizeForResize(const QSizeF &size, const QPointF &del
+ }
+
+ /*!
+- * \qmlmethod int QtWaylandCompositor::XdgSurface::sendConfigure(size size, List<uint>)
++ * \qmlmethod int QtWaylandCompositor::XdgSurface::sendConfigure(size size, list<uint> states)
+ *
+- * Sends a configure event to the client. Known states are enumerated in XdgSurface::State
++ * Sends a configure event to the client. \a size contains the pixel size of the surface.
++ * Known \a states are enumerated in XdgSurface::State.
+ */
+
+ /*!
+- * Sends a configure event to the client. Known states are enumerated in QWaylandXdgSurfaceV5::State
++ * Sends a configure event to the client. Parameter \a size contains the pixel size
++ * of the surface. Known \a states are enumerated in QWaylandXdgSurfaceV5::State.
+ */
+ uint QWaylandXdgSurfaceV5::sendConfigure(const QSize &size, const QVector<uint> &states)
+ {
+@@ -1038,8 +1040,8 @@ QWaylandXdgPopupV5::QWaylandXdgPopupV5()
+ }
+
+ /*!
+- * Constructs a QWaylandXdgPopupV5 for \a surface and initializes it with the
+- * given \a parentSurface and \a resource.
++ * Constructs a QWaylandXdgPopupV5, associating it with \a xdgShell at the specified \a position
++ * for \a surface and initializes it with the given \a parentSurface and \a resource.
+ */
+ QWaylandXdgPopupV5::QWaylandXdgPopupV5(QWaylandXdgShellV5 *xdgShell, QWaylandSurface *surface,
+ QWaylandSurface *parentSurface, const QPoint &position, const QWaylandResource &resource)
+diff --git a/src/compositor/extensions/qwaylandxdgshellv5integration.cpp b/src/compositor/extensions/qwaylandxdgshellv5integration.cpp
+index b317033..e2aa6b3 100644
+--- a/src/compositor/extensions/qwaylandxdgshellv5integration.cpp
++++ b/src/compositor/extensions/qwaylandxdgshellv5integration.cpp
+@@ -194,10 +194,14 @@ XdgPopupV5Integration::XdgPopupV5Integration(QWaylandQuickShellSurfaceItem *item
+ , m_xdgShell(QWaylandXdgPopupV5Private::get(m_xdgPopup)->m_xdgShell)
+ {
+ item->setSurface(m_xdgPopup->surface());
+- item->moveItem()->setPosition(QPointF(m_xdgPopup->position() * item->view()->output()->scaleFactor()));
++ if (item->view()->output())
++ item->moveItem()->setPosition(QPointF(m_xdgPopup->position() * item->view()->output()->scaleFactor()));
++ else
++ qWarning() << "XdgPopupV5Integration popup item without output" << item;
+
+ QWaylandClient *client = m_xdgPopup->surface()->client();
+- QWaylandQuickShellEventFilter::startFilter(client, [&]() { m_xdgShell->closeAllPopups(); });
++ auto shell = m_xdgShell;
++ QWaylandQuickShellEventFilter::startFilter(client, [shell]() { shell->closeAllPopups(); });
+
+ connect(m_xdgPopup, &QWaylandXdgPopupV5::destroyed, this, &XdgPopupV5Integration::handlePopupDestroyed);
+ }
+diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
+index 236218e..6b5c532 100644
+--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
++++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp
+@@ -159,6 +159,12 @@ void QWaylandEglWindow::setVisible(bool visible)
+ {
+ QWaylandWindow::setVisible(visible);
+ if (!visible)
++ QMetaObject::invokeMethod(this, "doInvalidateSurface", Qt::QueuedConnection);
++}
++
++void QWaylandEglWindow::doInvalidateSurface()
++{
++ if (!window()->isVisible())
+ invalidateSurface();
+ }
+
+@@ -168,6 +174,10 @@ void QWaylandEglWindow::invalidateSurface()
+ eglDestroySurface(m_clientBufferIntegration->eglDisplay(), m_eglSurface);
+ m_eglSurface = 0;
+ }
++ if (m_waylandEglWindow) {
++ wl_egl_window_destroy(m_waylandEglWindow);
++ m_waylandEglWindow = nullptr;
++ }
+ }
+
+ EGLSurface QWaylandEglWindow::eglSurface() const
+diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+index 556ed68..bf65668 100644
+--- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
++++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.h
+@@ -54,6 +54,7 @@ class QWaylandGLContext;
+
+ class QWaylandEglWindow : public QWaylandWindow
+ {
++ Q_OBJECT
+ public:
+ QWaylandEglWindow(QWindow *window);
+ ~QWaylandEglWindow();
+@@ -75,6 +76,9 @@ public:
+ void invalidateSurface() Q_DECL_OVERRIDE;
+ void setVisible(bool visible) Q_DECL_OVERRIDE;
+
++private Q_SLOTS:
++ void doInvalidateSurface();
++
+ private:
+ QWaylandEglClientBufferIntegration *m_clientBufferIntegration;
+ struct wl_egl_window *m_waylandEglWindow;
+diff --git a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.cpp b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.cpp
+index e2e2f55..c07ad53 100644
+--- a/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.cpp
++++ b/src/hardwareintegration/client/xcomposite-egl/qwaylandxcompositeeglcontext.cpp
+@@ -64,9 +64,7 @@ void QWaylandXCompositeEGLContext::swapBuffers(QPlatformSurface *surface)
+
+ QSize size = w->geometry().size();
+
+- w->attach(w->buffer(), 0, 0);
+- w->damage(QRect(QPoint(), size));
+- w->commit();
++ w->commit(w->buffer(), QRegion(0, 0, size.width(), size.height()));
+ w->waitForFrameSync();
+ }
+
+diff --git a/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxcontext.cpp b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxcontext.cpp
+index bc6e94f..439acc0 100644
+--- a/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxcontext.cpp
++++ b/src/hardwareintegration/client/xcomposite-glx/qwaylandxcompositeglxcontext.cpp
+@@ -90,9 +90,7 @@ void QWaylandXCompositeGLXContext::swapBuffers(QPlatformSurface *surface)
+
+ glXSwapBuffers(m_display, w->xWindow());
+
+- w->attach(w->buffer(), 0, 0);
+- w->damage(QRect(QPoint(), size));
+- w->commit();
++ w->commit(w->buffer(), QRegion(0, 0, size.width(), size.height()));
+ w->waitForFrameSync();
+ }
+
+diff --git a/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.cpp b/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.cpp
+index 6876385..6103e6b 100644
+--- a/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.cpp
++++ b/src/plugins/shellintegration/ivi-shell/qwaylandivishellintegration.cpp
+@@ -66,6 +66,7 @@ QWaylandIviShellIntegration::~QWaylandIviShellIntegration()
+
+ bool QWaylandIviShellIntegration::initialize(QWaylandDisplay *display)
+ {
++ QWaylandShellIntegration::initialize(display);
+ display->addRegistryListener(registryIvi, this);
+
+ return true;
+diff --git a/src/plugins/shellintegration/ivi-shell/qwaylandivisurface.cpp b/src/plugins/shellintegration/ivi-shell/qwaylandivisurface.cpp
+index f8871fa..ecc47e0 100644
+--- a/src/plugins/shellintegration/ivi-shell/qwaylandivisurface.cpp
++++ b/src/plugins/shellintegration/ivi-shell/qwaylandivisurface.cpp
+@@ -71,6 +71,13 @@ QWaylandIviSurface::~QWaylandIviSurface()
+ delete m_extendedWindow;
+ }
+
++void QWaylandIviSurface::setType(Qt::WindowType type, QWaylandWindow *transientParent)
++{
++
++ Q_UNUSED(type)
++ Q_UNUSED(transientParent)
++}
++
+ void QWaylandIviSurface::createExtendedSurface(QWaylandWindow *window)
+ {
+ if (window->display()->windowExtension())
+diff --git a/src/plugins/shellintegration/ivi-shell/qwaylandivisurface_p.h b/src/plugins/shellintegration/ivi-shell/qwaylandivisurface_p.h
+index 96978e2..9ac81ad 100644
+--- a/src/plugins/shellintegration/ivi-shell/qwaylandivisurface_p.h
++++ b/src/plugins/shellintegration/ivi-shell/qwaylandivisurface_p.h
+@@ -56,6 +56,8 @@ public:
+ struct ::ivi_controller_surface *iviControllerSurface);
+ virtual ~QWaylandIviSurface();
+
++ void setType(Qt::WindowType type, QWaylandWindow *transientParent) override;
++
+ private:
+ void createExtendedSurface(QWaylandWindow *window);
+ virtual void ivi_surface_configure(int32_t width, int32_t height) Q_DECL_OVERRIDE;
+diff --git a/sync.profile b/sync.profile
+index 6fee67e..1276df0 100644
+--- a/sync.profile
++++ b/sync.profile
+@@ -8,18 +8,6 @@
+ );
+ %deprecatedheaders = (
+ );
+-# Module dependencies.
+-# Every module that is required to build this module should have one entry.
+-# Each of the module version specifiers can take one of the following values:
+-# - A specific Git revision.
+-# - any git symbolic ref resolvable from the module's repository (e.g. "refs/heads/master" to track master branch)
+-# - an empty string to use the same branch under test (dependencies will become "refs/heads/master" if we are in the master branch)
+-#
+-%dependencies = (
+- "qtbase" => "",
+- "qtdeclarative" => "",
+-);
+-
+ %classnames = (
+ "qwaylandquickextension.h" => "QWaylandQuickExtension",
+ );
+diff --git a/tests/auto/client/client/tst_client.cpp b/tests/auto/client/client/tst_client.cpp
+index 74363ef..6aad25b 100644
+--- a/tests/auto/client/client/tst_client.cpp
++++ b/tests/auto/client/client/tst_client.cpp
+@@ -248,8 +248,8 @@ void tst_WaylandClient::backingStore()
+
+ window.hide();
+
+- // hiding the window should detach the buffer
+- QTRY_VERIFY(surface->image.isNull());
++ // hiding the window should destroy the surface
++ QTRY_VERIFY(!compositor->surface());
+ }
+
+ class DndWindow : public QWindow
+diff --git a/tests/manual/qmlclient/main.cpp b/tests/manual/qmlclient/main.cpp
+new file mode 100644
+index 0000000..cb2044c
+--- /dev/null
++++ b/tests/manual/qmlclient/main.cpp
+@@ -0,0 +1,51 @@
++/****************************************************************************
++**
++** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
++** Contact: http://www.qt-project.org/legal
++**
++** This file is part of the examples of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:BSD$
++** You may use this file under the terms of the BSD license as follows:
++**
++** "Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are
++** met:
++** * Redistributions of source code must retain the above copyright
++** notice, this list of conditions and the following disclaimer.
++** * Redistributions in binary form must reproduce the above copyright
++** notice, this list of conditions and the following disclaimer in
++** the documentation and/or other materials provided with the
++** distribution.
++** * Neither the name of The Qt Company Ltd nor the names of its
++** contributors may be used to endorse or promote products derived
++** from this software without specific prior written permission.
++**
++**
++** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++#include <QtGui/QGuiApplication>
++#include <QtQml/QQmlApplicationEngine>
++
++int main(int argc, char* argv[])
++{
++ setenv("QT_QPA_PLATFORM", "wayland", 1);
++
++ QGuiApplication app(argc, argv);
++ QQmlApplicationEngine engine(QUrl("qrc:/main.qml"));
++ return app.exec();
++}
+diff --git a/tests/manual/qmlclient/main.qml b/tests/manual/qmlclient/main.qml
+new file mode 100644
+index 0000000..a1fe241
+--- /dev/null
++++ b/tests/manual/qmlclient/main.qml
+@@ -0,0 +1,105 @@
++/****************************************************************************
++**
++** Copyright (C) 2016 Pier Luigi Fiorini <pierluigi.fiorini@gmail.com>
++** Contact: http://www.qt-project.org/legal
++**
++** This file is part of the examples of the Qt Toolkit.
++**
++** $QT_BEGIN_LICENSE:BSD$
++** You may use this file under the terms of the BSD license as follows:
++**
++** "Redistribution and use in source and binary forms, with or without
++** modification, are permitted provided that the following conditions are
++** met:
++** * Redistributions of source code must retain the above copyright
++** notice, this list of conditions and the following disclaimer.
++** * Redistributions in binary form must reproduce the above copyright
++** notice, this list of conditions and the following disclaimer in
++** the documentation and/or other materials provided with the
++** distribution.
++** * Neither the name of The Qt Company Ltd nor the names of its
++** contributors may be used to endorse or promote products derived
++** from this software without specific prior written permission.
++**
++**
++** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
++** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
++** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
++** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
++** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
++** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
++** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
++** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
++** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
++**
++** $QT_END_LICENSE$
++**
++****************************************************************************/
++
++import QtQuick 2.2
++import QtQuick.Window 2.2
++
++Window {
++ id: window
++ width: 400
++ height: 400
++ color: "blue"
++ visible: true
++
++ Column {
++ spacing: 8
++
++ Row {
++ spacing: 8
++
++ Repeater {
++ model: ListModel {
++ ListElement { label: "Windowed"; value: Window.Windowed }
++ ListElement { label: "Maximized"; value: Window.Maximized }
++ ListElement { label: "FullScreen"; value: Window.FullScreen }
++ }
++
++ Rectangle {
++ width: 96
++ height: 40
++ color: "gainsboro"
++
++ MouseArea {
++ anchors.fill: parent
++ onClicked: window.visibility = model.value
++
++ Text {
++ anchors.centerIn: parent
++ text: model.label
++ }
++ }
++ }
++ }
++ }
++
++ Text {
++ color: "white"
++ text: {
++ switch (window.visibility) {
++ case Window.Windowed:
++ return "windowed";
++ case Window.Maximized:
++ return "maximized";
++ case Window.FullScreen:
++ return "fullscreen";
++ case Window.Minimized:
++ return "minimized";
++ case Window.AutomaticVisibility:
++ return "automatic";
++ case Window.Hidden:
++ return "hidden";
++ default:
++ break;
++ }
++ return "unknown";
++ }
++ }
++ }
++}
+diff --git a/tests/manual/qmlclient/qml.qrc b/tests/manual/qmlclient/qml.qrc
+new file mode 100644
+index 0000000..6b2d0a7
+--- /dev/null
++++ b/tests/manual/qmlclient/qml.qrc
+@@ -0,0 +1,5 @@
++<!DOCTYPE RCC><RCC version="1.0">
++<qresource>
++ <file>main.qml</file>
++</qresource>
++</RCC>
+diff --git a/tests/manual/qmlclient/qmlclient.pro b/tests/manual/qmlclient/qmlclient.pro
+new file mode 100644
+index 0000000..dcf66db
+--- /dev/null
++++ b/tests/manual/qmlclient/qmlclient.pro
+@@ -0,0 +1,12 @@
++TEMPLATE = app
++
++QT += \
++ gui gui-private core-private \
++ quick \
++ waylandclient \
++
++SOURCES += \
++ main.cpp
++
++RESOURCES += \
++ qml.qrc
diff --git a/PKGBUILD b/PKGBUILD
index 145bcfc69bcc..73c636427fa9 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -109,7 +109,7 @@ $_float && _additional_configure_flags="$_additional_configure_flags -qreal floa
# PKGBUILD vars
-pkgrel=3
+pkgrel=4
pkgname="qt-sdk"
if [[ -n ${_piver} ]]; then
@@ -241,6 +241,7 @@ if $_patching; then
cd ${_waylanddir}
patch -p1 < ${startdir}/0001-Fix-build-of-brcm-egl-client.patch
+ patch -p1 < ${startdir}/5.8.0-beta1-5b807802866c8df00cb3340d4f9bcc343be5973a.patch
# Work around our embarresing propensity to stomp on your own tailored build configuration
sed -i "s/O[23]/Os/" ${_basedir}/mkspecs/common/gcc-base.conf || exit 1