From 49ea0fc16a499514ebc0c254a983e86bcda88dd6 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Fri, 28 Sep 2018 13:05:53 +0200 Subject: Compositor: Fix crash after surface destruction Fixes a crash due to dangling pointer dereference in QWaylandQuickItem::inputMethodQuery. Fixes: QTBUG-71745 Change-Id: Id379779f23221e7de17423f75c3d78d7e794b7b9 Reviewed-by: Paul Olav Tvete (cherry picked from commit d52e86e6f9bfde48b473dbe9d08e325d45388254) Reviewed-by: Andreas Cord-Landwehr --- src/compositor/compositor_api/qwaylandquickitem_p.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compositor/compositor_api/qwaylandquickitem_p.h b/src/compositor/compositor_api/qwaylandquickitem_p.h index f926d55e8..28b8732d3 100644 --- a/src/compositor/compositor_api/qwaylandquickitem_p.h +++ b/src/compositor/compositor_api/qwaylandquickitem_p.h @@ -154,7 +154,7 @@ public: static QMutex *mutex; QScopedPointer view; - QWaylandSurface *oldSurface = nullptr; + QPointer oldSurface; mutable QWaylandSurfaceTextureProvider *provider = nullptr; bool paintEnabled = true; bool touchEventsEnabled = true; -- cgit v1.2.3 From fa57079a227b92218c5b23dafdcb7f547acb635d Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Wed, 7 Nov 2018 14:19:04 +0100 Subject: Don't crash if view is deleted from surfaceDestroyed signal Fix regression introduced in 297bcd005c4205f69e1bf9e9dc565ab757cf0bac Fixes: QTBUG-71643 Change-Id: I769518a9ca13fcd13ea277c7fa8ac1885ca123ba Reviewed-by: Johan Helsing (cherry picked from commit f890798053c7fa692bff7f8a3e96583dfcaba0cb) Reviewed-by: Paul Olav Tvete --- src/compositor/compositor_api/qwaylandview.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compositor/compositor_api/qwaylandview.cpp b/src/compositor/compositor_api/qwaylandview.cpp index 127593770..1a6bf1a64 100644 --- a/src/compositor/compositor_api/qwaylandview.cpp +++ b/src/compositor/compositor_api/qwaylandview.cpp @@ -56,8 +56,10 @@ void QWaylandViewPrivate::markSurfaceAsDestroyed(QWaylandSurface *surface) Q_ASSERT(surface == this->surface); setSurface(nullptr); + QPointer deleteGuard(q); emit q->surfaceDestroyed(); - clearFrontBuffer(); + if (!deleteGuard.isNull()) + clearFrontBuffer(); } /*! -- cgit v1.2.3 From 9ce3088d226fddc18bcac170fa5cc5be3c29e371 Mon Sep 17 00:00:00 2001 From: Antti Kokko Date: Fri, 16 Nov 2018 09:22:24 +0200 Subject: Add changes file for Qt 5.11.3 + 53dff95bfbe9070c4cd17045f3d5147f29710c5f Compositor: Fix OpenGL textures deleted prematurely + c3b6c4d442c8187e43601c548bc58ce3e4fe21f3 Compositor: Don't send illegal leave events + 297bcd005c4205f69e1bf9e9dc565ab757cf0bac Don't destroy buffer before surfaceDestroyed signal + dccec9b282ae15fa65fd61698dd1cb47325e5c8e Bump version Change-Id: I548d049f958038a358982cc9470654cead9f05df Reviewed-by: Paul Olav Tvete --- dist/changes-5.11.3 | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 dist/changes-5.11.3 diff --git a/dist/changes-5.11.3 b/dist/changes-5.11.3 new file mode 100644 index 000000000..c3f1060b9 --- /dev/null +++ b/dist/changes-5.11.3 @@ -0,0 +1,30 @@ +Qt 5.11.3 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.11.0 through 5.11.2. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +http://doc.qt.io/qt-5/index.html + +The Qt version 5.11 series is binary compatible with the 5.10.x series. +Applications compiled for 5.10 will continue to run with 5.11. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + +https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Compositor * +**************************************************************************** + + - [QTBUG-70163] Fixed a bug where destroying a WaylandQuickItem would + delete the OpenGL texture for all other WaylandQuickItems using that + surface. + - Fixed a bug that caused some clients to abort in libwayland when a + surface left an output. + - [QTBUG-69384] QWaylandView::surfaceDestroyed is now emitted before the + surface is destroyed, fixing close animations. -- cgit v1.2.3 From a8fed20181729cae70de43079c4a34ad1780cfd7 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Mon, 19 Nov 2018 16:32:12 +0100 Subject: use new feature name xkbcommon_evdev -> xkbcommon The xkbcommon configure logic was refactored in qtbase/c3a963da1f9e7b1d37e63eedded61da4fbdaaf9a. For more details see the relevant commit. Change-Id: Ic1aa26846ab8266c589f6e92dc8b81aba36df58a Reviewed-by: Johan Helsing --- README | 4 ++-- src/client/client.pro | 4 ++-- src/client/qwaylandinputdevice.cpp | 22 +++++++++++----------- src/client/qwaylandinputdevice_p.h | 10 +++++----- .../compositor_api/qwaylandcompositor.cpp | 2 +- src/compositor/compositor_api/qwaylandkeyboard.cpp | 22 +++++++++++----------- src/compositor/compositor_api/qwaylandkeyboard_p.h | 8 ++++---- src/compositor/wayland_wrapper/wayland_wrapper.pri | 4 ++-- .../shellintegration/ivi-shell/ivi-shell.pro | 4 ++-- src/plugins/shellintegration/wl-shell/wl-shell.pro | 4 ++-- .../shellintegration/xdg-shell-v5/xdg-shell-v5.pro | 4 ++-- .../shellintegration/xdg-shell-v6/xdg-shell-v6.pro | 4 ++-- .../shellintegration/xdg-shell/xdg-shell.pro | 4 ++-- src/shared/qwaylandxkb.cpp | 10 +++++----- src/shared/qwaylandxkb_p.h | 2 +- tests/auto/compositor/compositor/compositor.pro | 4 ++-- .../auto/compositor/compositor/tst_compositor.cpp | 6 +++--- 17 files changed, 59 insertions(+), 59 deletions(-) diff --git a/README b/README index 4fd99495b..bc6569ef7 100644 --- a/README +++ b/README @@ -9,8 +9,8 @@ QtWaylandCompositor API: Enables the creation of Wayland compositors using Qt and QtQuick. To build the QtWayland module you need the external dependencies: -xkbcommon 0.2.0 - http://xkbcommon.org/ -wayland 1.6.0 - http://wayland.freedesktop.org/ +xkbcommon - http://xkbcommon.org/ +wayland - http://wayland.freedesktop.org/ QtWaylandCompositor supports loading client buffer integrations that don't use the wayland-egl interfaces. These client buffer integrations are picked up by diff --git a/src/client/client.pro b/src/client/client.pro index 45bbb976b..30f32dd7e 100644 --- a/src/client/client.pro +++ b/src/client/client.pro @@ -15,8 +15,8 @@ use_gold_linker: CONFIG += no_linker_version_script CONFIG -= precompile_header CONFIG += link_pkgconfig wayland-scanner -qtConfig(xkbcommon-evdev): \ - QMAKE_USE_PRIVATE += xkbcommon_evdev +qtConfig(xkbcommon): \ + QMAKE_USE_PRIVATE += xkbcommon QMAKE_USE += wayland-client diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index 9d675ae21..ba55e6e17 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -70,7 +70,7 @@ #include -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) #include #endif @@ -84,7 +84,7 @@ QWaylandInputDevice::Keyboard::Keyboard(QWaylandInputDevice *p) connect(&mRepeatTimer, SIGNAL(timeout()), this, SLOT(repeatKey())); } -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) bool QWaylandInputDevice::Keyboard::createDefaultKeyMap() { if (mXkbContext && mXkbMap && mXkbState) { @@ -156,7 +156,7 @@ void QWaylandInputDevice::Keyboard::releaseComposeState() QWaylandInputDevice::Keyboard::~Keyboard() { -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) releaseComposeState(); releaseKeyMap(); #endif @@ -344,7 +344,7 @@ Qt::KeyboardModifiers QWaylandInputDevice::Keyboard::modifiers() const { Qt::KeyboardModifiers ret = Qt::NoModifier; -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) if (!mXkbState) return ret; @@ -625,7 +625,7 @@ void QWaylandInputDevice::Pointer::pointer_axis(uint32_t time, uint32_t axis, in void QWaylandInputDevice::Keyboard::keyboard_keymap(uint32_t format, int32_t fd, uint32_t size) { -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { close(fd); return; @@ -728,7 +728,7 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, if (isDown) mParent->mQDisplay->setLastInputDevice(mParent, serial, window); -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) if (!createDefaultKeyMap()) { return; } @@ -771,7 +771,7 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, #endif if (state == WL_KEYBOARD_KEY_STATE_PRESSED -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) && xkb_keymap_key_repeats(mXkbMap, code) #endif ) { @@ -779,7 +779,7 @@ void QWaylandInputDevice::Keyboard::keyboard_key(uint32_t serial, uint32_t time, mRepeatCode = code; mRepeatTime = time; mRepeatText = text; -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) mRepeatSym = sym; #endif mRepeatTimer.setInterval(400); @@ -793,7 +793,7 @@ void QWaylandInputDevice::Keyboard::repeatKey() { mRepeatTimer.setInterval(25); sendKey(mFocus->window(), mRepeatTime, QEvent::KeyRelease, mRepeatKey, modifiers(), mRepeatCode, -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) mRepeatSym, mNativeModifiers, #else 0, 0, @@ -801,7 +801,7 @@ void QWaylandInputDevice::Keyboard::repeatKey() mRepeatText, true); sendKey(mFocus->window(), mRepeatTime, QEvent::KeyPress, mRepeatKey, modifiers(), mRepeatCode, -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) mRepeatSym, mNativeModifiers, #else 0, 0, @@ -816,7 +816,7 @@ void QWaylandInputDevice::Keyboard::keyboard_modifiers(uint32_t serial, uint32_t group) { Q_UNUSED(serial); -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) if (mXkbState) xkb_state_update_mask(mXkbState, mods_depressed, mods_latched, mods_locked, diff --git a/src/client/qwaylandinputdevice_p.h b/src/client/qwaylandinputdevice_p.h index 4b12cc089..7aa86539b 100644 --- a/src/client/qwaylandinputdevice_p.h +++ b/src/client/qwaylandinputdevice_p.h @@ -65,7 +65,7 @@ #include -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) #include #include #endif @@ -77,7 +77,7 @@ struct wl_cursor_image; #endif -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) struct xkb_compose_state; struct xkb_compose_table; #endif @@ -209,7 +209,7 @@ public: QWaylandInputDevice *mParent = nullptr; QPointer mFocus; -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) xkb_context *mXkbContext = nullptr; xkb_keymap *mXkbMap = nullptr; xkb_state *mXkbState = nullptr; @@ -222,7 +222,7 @@ public: uint32_t mRepeatCode; uint32_t mRepeatTime; QString mRepeatText; -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) xkb_keysym_t mRepeatSym; #endif QTimer mRepeatTimer; @@ -233,7 +233,7 @@ private slots: void repeatKey(); private: -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) bool createDefaultKeyMap(); void releaseKeyMap(); void createComposeState(); diff --git a/src/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index c782304ed..173b50ce0 100644 --- a/src/compositor/compositor_api/qwaylandcompositor.cpp +++ b/src/compositor/compositor_api/qwaylandcompositor.cpp @@ -128,7 +128,7 @@ public: uint32_t code = ke->nativeScanCode; bool isDown = ke->keyType == QEvent::KeyPress; -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) QString text; Qt::KeyboardModifiers modifiers = QWaylandXkb::modifiers(keyb->xkbState()); diff --git a/src/compositor/compositor_api/qwaylandkeyboard.cpp b/src/compositor/compositor_api/qwaylandkeyboard.cpp index e067eeafe..68d855a66 100644 --- a/src/compositor/compositor_api/qwaylandkeyboard.cpp +++ b/src/compositor/compositor_api/qwaylandkeyboard.cpp @@ -51,7 +51,7 @@ #include #include -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) #include #include #include @@ -66,7 +66,7 @@ QWaylandKeyboardPrivate::QWaylandKeyboardPrivate(QWaylandSeat *seat) QWaylandKeyboardPrivate::~QWaylandKeyboardPrivate() { -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) if (xkb_context) { if (keymap_area) munmap(keymap_area, keymap_size); @@ -136,7 +136,7 @@ void QWaylandKeyboardPrivate::keyboard_bind_resource(wl_keyboard::Resource *reso if (resource->version() >= WL_KEYBOARD_REPEAT_INFO_SINCE_VERSION) send_repeat_info(resource->handle, repeatRate, repeatDelay); -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) if (xkb_context) { send_keymap(resource->handle, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymap_fd, keymap_size); @@ -164,7 +164,7 @@ void QWaylandKeyboardPrivate::keyboard_release(wl_keyboard::Resource *resource) void QWaylandKeyboardPrivate::keyEvent(uint code, uint32_t state) { -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) uint key = toWaylandXkbV1Key(code); #else uint key = code; @@ -180,7 +180,7 @@ void QWaylandKeyboardPrivate::sendKeyEvent(uint code, uint32_t state) { uint32_t time = compositor()->currentTimeMsecs(); uint32_t serial = compositor()->nextSerial(); -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) uint key = toWaylandXkbV1Key(code); #else uint key = code; @@ -197,7 +197,7 @@ void QWaylandKeyboardPrivate::modifiers(uint32_t serial, uint32_t mods_depressed } } -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) void QWaylandKeyboardPrivate::maybeUpdateXkbScanCodeTable() { if (!scanCodesByQtKey.isEmpty() || !xkbState()) @@ -225,7 +225,7 @@ void QWaylandKeyboardPrivate::maybeUpdateXkbScanCodeTable() void QWaylandKeyboardPrivate::updateModifierState(uint code, uint32_t state) { -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) if (!xkb_context) return; @@ -265,7 +265,7 @@ void QWaylandKeyboardPrivate::maybeUpdateKeymap() return; pendingKeymap = false; -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) if (!xkb_context) return; @@ -285,7 +285,7 @@ void QWaylandKeyboardPrivate::maybeUpdateKeymap() #endif } -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) static int createAnonymousFile(size_t size) { QString path = QStandardPaths::writableLocation(QStandardPaths::RuntimeLocation); @@ -429,7 +429,7 @@ QWaylandKeyboard::QWaylandKeyboard(QWaylandSeat *seat, QObject *parent) connect(keymap, &QWaylandKeymap::optionsChanged, this, &QWaylandKeyboard::updateKeymap); connect(keymap, &QWaylandKeymap::rulesChanged, this, &QWaylandKeyboard::updateKeymap); connect(keymap, &QWaylandKeymap::modelChanged, this, &QWaylandKeyboard::updateKeymap); -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) d->initXKB(); #endif } @@ -592,7 +592,7 @@ void QWaylandKeyboard::addClient(QWaylandClient *client, uint32_t id, uint32_t v uint QWaylandKeyboard::keyToScanCode(int qtKey) const { uint scanCode = 0; -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) Q_D(const QWaylandKeyboard); const_cast(d)->maybeUpdateXkbScanCodeTable(); scanCode = d->scanCodesByQtKey.value({d->group, qtKey}, 0); diff --git a/src/compositor/compositor_api/qwaylandkeyboard_p.h b/src/compositor/compositor_api/qwaylandkeyboard_p.h index cd1f27956..87e89e85e 100644 --- a/src/compositor/compositor_api/qwaylandkeyboard_p.h +++ b/src/compositor/compositor_api/qwaylandkeyboard_p.h @@ -62,7 +62,7 @@ #include -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) #include #endif @@ -86,7 +86,7 @@ public: void modifiers(uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group); -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) struct xkb_state *xkbState() const { return xkb_state; } uint32_t xkbModsMask() const { return modsDepressed | modsLatched | modsLocked; } void maybeUpdateXkbScanCodeTable(); @@ -106,7 +106,7 @@ protected: void keyboard_release(Resource *resource) override; private: -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) void initXKB(); void createXKBKeymap(); void createXKBState(xkb_keymap *keymap); @@ -128,7 +128,7 @@ private: uint32_t group = 0; bool pendingKeymap = false; -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) size_t keymap_size; int keymap_fd = -1; char *keymap_area = nullptr; diff --git a/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri index e19ea253a..3041d7696 100644 --- a/src/compositor/wayland_wrapper/wayland_wrapper.pri +++ b/src/compositor/wayland_wrapper/wayland_wrapper.pri @@ -30,5 +30,5 @@ qtConfig(wayland-datadevice) { INCLUDEPATH += wayland_wrapper -qtConfig(xkbcommon-evdev): \ - QMAKE_USE += xkbcommon_evdev +qtConfig(xkbcommon): \ + QMAKE_USE += xkbcommon diff --git a/src/plugins/shellintegration/ivi-shell/ivi-shell.pro b/src/plugins/shellintegration/ivi-shell/ivi-shell.pro index ba716c10d..67e659ab0 100644 --- a/src/plugins/shellintegration/ivi-shell/ivi-shell.pro +++ b/src/plugins/shellintegration/ivi-shell/ivi-shell.pro @@ -3,8 +3,8 @@ CONFIG += wayland-scanner QMAKE_USE += wayland-client -qtConfig(xkbcommon-evdev): \ - QMAKE_USE += xkbcommon_evdev +qtConfig(xkbcommon): \ + QMAKE_USE += xkbcommon WAYLANDCLIENTSOURCES += \ ../../../3rdparty/protocol/ivi-application.xml \ diff --git a/src/plugins/shellintegration/wl-shell/wl-shell.pro b/src/plugins/shellintegration/wl-shell/wl-shell.pro index fbff63c71..bb2c1829a 100644 --- a/src/plugins/shellintegration/wl-shell/wl-shell.pro +++ b/src/plugins/shellintegration/wl-shell/wl-shell.pro @@ -2,8 +2,8 @@ QT += gui-private waylandclient-private CONFIG += wayland-scanner QMAKE_USE += wayland-client -qtConfig(xkbcommon-evdev): \ - QMAKE_USE_PRIVATE += xkbcommon_evdev +qtConfig(xkbcommon): \ + QMAKE_USE_PRIVATE += xkbcommon WAYLANDCLIENTSOURCES += \ ../../../3rdparty/protocol/wayland.xml diff --git a/src/plugins/shellintegration/xdg-shell-v5/xdg-shell-v5.pro b/src/plugins/shellintegration/xdg-shell-v5/xdg-shell-v5.pro index bf9edba78..4f6dde9bc 100644 --- a/src/plugins/shellintegration/xdg-shell-v5/xdg-shell-v5.pro +++ b/src/plugins/shellintegration/xdg-shell-v5/xdg-shell-v5.pro @@ -3,8 +3,8 @@ CONFIG += wayland-scanner QMAKE_USE += wayland-client -qtConfig(xkbcommon-evdev): \ - QMAKE_USE += xkbcommon_evdev +qtConfig(xkbcommon): \ + QMAKE_USE += xkbcommon HEADERS += \ qwaylandxdgpopupv5_p.h \ diff --git a/src/plugins/shellintegration/xdg-shell-v6/xdg-shell-v6.pro b/src/plugins/shellintegration/xdg-shell-v6/xdg-shell-v6.pro index 5d5046f60..3c1aaee81 100644 --- a/src/plugins/shellintegration/xdg-shell-v6/xdg-shell-v6.pro +++ b/src/plugins/shellintegration/xdg-shell-v6/xdg-shell-v6.pro @@ -2,8 +2,8 @@ QT += gui-private waylandclient-private CONFIG += wayland-scanner QMAKE_USE += wayland-client -qtConfig(xkbcommon-evdev): \ - QMAKE_USE_PRIVATE += xkbcommon_evdev +qtConfig(xkbcommon): \ + QMAKE_USE_PRIVATE += xkbcommon WAYLANDCLIENTSOURCES += \ ../../../3rdparty/protocol/xdg-shell-unstable-v6.xml diff --git a/src/plugins/shellintegration/xdg-shell/xdg-shell.pro b/src/plugins/shellintegration/xdg-shell/xdg-shell.pro index 2b1191af0..261715845 100644 --- a/src/plugins/shellintegration/xdg-shell/xdg-shell.pro +++ b/src/plugins/shellintegration/xdg-shell/xdg-shell.pro @@ -2,8 +2,8 @@ QT += gui-private waylandclient-private CONFIG += wayland-scanner QMAKE_USE += wayland-client -qtConfig(xkbcommon-evdev): \ - QMAKE_USE_PRIVATE += xkbcommon_evdev +qtConfig(xkbcommon): \ + QMAKE_USE_PRIVATE += xkbcommon WAYLANDCLIENTSOURCES += \ ../../../3rdparty/protocol/xdg-decoration-unstable-v1.xml \ diff --git a/src/shared/qwaylandxkb.cpp b/src/shared/qwaylandxkb.cpp index a0e388a1c..3cfc4b074 100644 --- a/src/shared/qwaylandxkb.cpp +++ b/src/shared/qwaylandxkb.cpp @@ -43,13 +43,13 @@ #include #include -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) #include #endif QT_BEGIN_NAMESPACE -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) static const uint32_t KeyTbl[] = { XKB_KEY_Escape, Qt::Key_Escape, XKB_KEY_Tab, Qt::Key_Tab, @@ -297,7 +297,7 @@ static xkb_keysym_t toKeysymFromTable(uint32_t key) std::pair QWaylandXkb::keysymToQtKey(xkb_keysym_t keysym, Qt::KeyboardModifiers &modifiers) { -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) QString text; uint utf32 = xkb_keysym_to_utf32(keysym); if (utf32) @@ -339,7 +339,7 @@ std::pair QWaylandXkb::keysymToQtKey(xkb_keysym_t keysym, Qt::Keyb Qt::KeyboardModifiers QWaylandXkb::modifiers(struct xkb_state *state) { -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) Qt::KeyboardModifiers modifiers = Qt::NoModifier; xkb_state_component cstate = static_cast(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED | XKB_STATE_LOCKED); @@ -367,7 +367,7 @@ QEvent::Type QWaylandXkb::toQtEventType(uint32_t state) QVector QWaylandXkb::toKeysym(QKeyEvent *event) { -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) QVector keysyms; if (event->key() >= Qt::Key_F1 && event->key() <= Qt::Key_F35) { keysyms.append(XKB_KEY_F1 + (event->key() - Qt::Key_F1)); diff --git a/src/shared/qwaylandxkb_p.h b/src/shared/qwaylandxkb_p.h index 6fa1ea45b..4820d94be 100644 --- a/src/shared/qwaylandxkb_p.h +++ b/src/shared/qwaylandxkb_p.h @@ -45,7 +45,7 @@ #include #include -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) #include #else typedef quint32 xkb_keysym_t; diff --git a/tests/auto/compositor/compositor/compositor.pro b/tests/auto/compositor/compositor/compositor.pro index d69db4ca5..0ce2c6be0 100644 --- a/tests/auto/compositor/compositor/compositor.pro +++ b/tests/auto/compositor/compositor/compositor.pro @@ -7,8 +7,8 @@ QT += core-private gui-private waylandcompositor waylandcompositor-private QMAKE_USE += wayland-client wayland-server -qtConfig(xkbcommon-evdev): \ - QMAKE_USE += xkbcommon_evdev +qtConfig(xkbcommon): \ + QMAKE_USE += xkbcommon WAYLANDCLIENTSOURCES += \ ../../../../src/3rdparty/protocol/xdg-shell-unstable-v5.xml \ diff --git a/tests/auto/compositor/compositor/tst_compositor.cpp b/tests/auto/compositor/compositor/tst_compositor.cpp index 2c0e46b23..281be28bc 100644 --- a/tests/auto/compositor/compositor/tst_compositor.cpp +++ b/tests/auto/compositor/compositor/tst_compositor.cpp @@ -58,7 +58,7 @@ class tst_WaylandCompositor : public QObject private slots: void init(); void seatCapabilities(); -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) void simpleKeyboard(); void keyboardKeymaps(); void keyboardLayoutSwitching(); @@ -169,7 +169,7 @@ void tst_WaylandCompositor::multipleClients() QTRY_COMPARE(compositor.surfaces.size(), 0); } -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) void tst_WaylandCompositor::simpleKeyboard() { @@ -282,7 +282,7 @@ void tst_WaylandCompositor::keyboardLayoutSwitching() QTRY_COMPARE(mockKeyboard->m_lastKeyCode, 44u); } -#endif // QT_CONFIG(xkbcommon_evdev) +#endif // QT_CONFIG(xkbcommon) void tst_WaylandCompositor::keyboardGrab() { -- cgit v1.2.3 From d25b3b7f1059d5561bce3efe7ea903ea76d4e888 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Nowacki?= Date: Thu, 6 Dec 2018 10:29:58 +0100 Subject: Fix invalid QWaylandOutputMode comparison operator Fixes: QTBUG-72288 Change-Id: I61fde92ea4275febbb4ec8c067280a4ca570d7c1 Reviewed-by: Johan Helsing --- .../compositor_api/qwaylandoutputmode.cpp | 4 ++-- .../auto/compositor/compositor/tst_compositor.cpp | 23 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/src/compositor/compositor_api/qwaylandoutputmode.cpp b/src/compositor/compositor_api/qwaylandoutputmode.cpp index 545871175..79a581609 100644 --- a/src/compositor/compositor_api/qwaylandoutputmode.cpp +++ b/src/compositor/compositor_api/qwaylandoutputmode.cpp @@ -89,7 +89,7 @@ QWaylandOutputMode &QWaylandOutputMode::operator=(const QWaylandOutputMode &othe */ bool QWaylandOutputMode::operator==(const QWaylandOutputMode &other) const { - return size() == other.size() && refreshRate() == refreshRate(); + return size() == other.size() && refreshRate() == other.refreshRate(); } /*! @@ -98,7 +98,7 @@ bool QWaylandOutputMode::operator==(const QWaylandOutputMode &other) const */ bool QWaylandOutputMode::operator!=(const QWaylandOutputMode &other) const { - return size() != other.size() || refreshRate() != refreshRate(); + return size() != other.size() || refreshRate() != other.refreshRate(); } /*! diff --git a/tests/auto/compositor/compositor/tst_compositor.cpp b/tests/auto/compositor/compositor/tst_compositor.cpp index 281be28bc..7fe8dfc28 100644 --- a/tests/auto/compositor/compositor/tst_compositor.cpp +++ b/tests/auto/compositor/compositor/tst_compositor.cpp @@ -72,6 +72,7 @@ private slots: void multipleClients(); void geometry(); void modes(); + void comparingModes(); void sizeFollowsWindow(); void mapSurface(); void mapSurfaceHiDpi(); @@ -373,6 +374,28 @@ void tst_WaylandCompositor::modes() QTRY_COMPARE(client.geometry, QRect(QPoint(0, 0), QSize(1920, 1080))); } +void tst_WaylandCompositor::comparingModes() +{ + QWaylandOutputMode mode1(QSize(800, 600), 120000); + QWaylandOutputMode mode2(QSize(1024, 768), 100000); + QWaylandOutputMode mode3(QSize(1024, 768), 120000); + QWaylandOutputMode mode4(QSize(800, 600), 100000); + + QCOMPARE(mode1, mode1); + QCOMPARE(mode2, mode2); + QCOMPARE(mode3, mode3); + QCOMPARE(mode4, mode4); + + for (auto mode: {mode2, mode3, mode4}) + QVERIFY(mode1 != mode); + for (auto mode: {mode1, mode3, mode4}) + QVERIFY(mode2 != mode); + for (auto mode: {mode1, mode2, mode4}) + QVERIFY(mode3 != mode); + for (auto mode: {mode1, mode2, mode2}) + QVERIFY(mode4 != mode); +} + void tst_WaylandCompositor::sizeFollowsWindow() { TestCompositor compositor; -- cgit v1.2.3 From 7f7502865f980a7d72dc04ffc5f25eecf0d414a8 Mon Sep 17 00:00:00 2001 From: Gatis Paeglis Date: Sat, 8 Dec 2018 23:32:03 +0100 Subject: tests: minor fixup in tst_WaylandCompositor::comparingModes() This patch amends d25b3b7f1059d5561bce3efe7ea903ea76d4e888 Change-Id: I413818f6cd4a77062287265f3bcb5db6170fc4d2 Reviewed-by: Johan Helsing --- tests/auto/compositor/compositor/tst_compositor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/auto/compositor/compositor/tst_compositor.cpp b/tests/auto/compositor/compositor/tst_compositor.cpp index 7fe8dfc28..97e650d97 100644 --- a/tests/auto/compositor/compositor/tst_compositor.cpp +++ b/tests/auto/compositor/compositor/tst_compositor.cpp @@ -392,7 +392,7 @@ void tst_WaylandCompositor::comparingModes() QVERIFY(mode2 != mode); for (auto mode: {mode1, mode2, mode4}) QVERIFY(mode3 != mode); - for (auto mode: {mode1, mode2, mode2}) + for (auto mode: {mode1, mode2, mode3}) QVERIFY(mode4 != mode); } -- cgit v1.2.3 From 88041986f448c14871fac76ee01280736af3f382 Mon Sep 17 00:00:00 2001 From: Kimmo Ollila Date: Tue, 16 Oct 2018 12:34:36 +0300 Subject: Fix scaling if wrong attached window size is returned Some drivers may return wrong size from wl_egl_window_get_attached_size and can therefore ignore wl_egl_window_resize calls. This patch introduces a new env variable QT_WAYLAND_DISABLE_RESIZECHECK to skip the size check and to force resizing of egl window on create and resize events. Task-number: QTBUG-70079 Change-Id: I9be97480088c63ae0a6dc3d1d1e026b0683a627e Reviewed-by: Paul Olav Tvete Reviewed-by: Johan Helsing --- src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp index f10a7469a..24dadff4d 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp @@ -126,8 +126,12 @@ void QWaylandEglWindow::updateSurface(bool create) } else { if (m_waylandEglWindow) { int current_width, current_height; - wl_egl_window_get_attached_size(m_waylandEglWindow,¤t_width,¤t_height); - if (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height()) { + static bool disableResizeCheck = qgetenv("QT_WAYLAND_DISABLE_RESIZECHECK").toInt(); + + if (!disableResizeCheck) { + wl_egl_window_get_attached_size(m_waylandEglWindow, ¤t_width, ¤t_height); + } + if (disableResizeCheck || (current_width != sizeWithMargins.width() || current_height != sizeWithMargins.height())) { wl_egl_window_resize(m_waylandEglWindow, sizeWithMargins.width(), sizeWithMargins.height(), mOffset.x(), mOffset.y()); mOffset = QPoint(); -- cgit v1.2.3 From 99526a2227e8a0bccffb504b10f72aeee47e290d Mon Sep 17 00:00:00 2001 From: Paul Olav Tvete Date: Thu, 13 Dec 2018 12:56:07 +0100 Subject: Specify X11 dependency explicitly Fixing build issue now that XComposite no longer pulls in X11. Change-Id: I4c5e77188cf167716aa64f2575d70ac2ca37608b Reviewed-by: Johan Helsing --- src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri b/src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri index f255f5c57..b18aa2d50 100644 --- a/src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri +++ b/src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri @@ -1,6 +1,6 @@ INCLUDEPATH += $$PWD -QMAKE_USE += xcomposite +QMAKE_USE += xcomposite x11 CONFIG += wayland-scanner WAYLANDCLIENTSOURCES += $$PWD/../../../extensions/xcomposite.xml -- cgit v1.2.3 From 1dc85b95ab0adc1e805d059e2c35c671ef790011 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Thu, 1 Nov 2018 10:07:14 +0100 Subject: Client: Full implementation for frame callbacks The Wayland plugin now takes full control over delivering update request and implement frame callbacks for both egl and shm. Fixes two bugs: [ChangeLog][Client] The non-blocking version of eglSwapBuffers is now used. This fixed a bug where minimized windows would block the event loop. Also, when we relied on the QPA version of requestUpdate, we would sometimes deliver one update request while we were waiting for a frame callback. When we implement the fallback timer ourselves we can make sure we only deliver the fallback if there are no pending frame callbacks. Fixes: QTBUG-69077 Change-Id: I2d3a6896c32e63d8520b57448a3601a817816a91 Reviewed-by: Paul Olav Tvete --- src/client/qwaylandwindow.cpp | 107 +++++++++++++++++---- src/client/qwaylandwindow_p.h | 9 +- .../client/wayland-egl/qwaylandglcontext.cpp | 22 ++--- 3 files changed, 103 insertions(+), 35 deletions(-) diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 4ac2ca51e..f596438b6 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -358,6 +358,8 @@ void QWaylandWindow::sendExposeEvent(const QRect &rect) { if (!(mShellSurface && mShellSurface->handleExpose(rect))) QWindowSystemInterface::handleExposeEvent(window(), rect); + else + qCDebug(lcQpaWayland) << "sendExposeEvent: intercepted by shell extension, not sending"; mLastExposeGeometry = rect; } @@ -542,18 +544,11 @@ void QWaylandWindow::handleScreenRemoved(QScreen *qScreen) void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y) { Q_ASSERT(!buffer->committed()); - if (mFrameCallback) { - wl_callback_destroy(mFrameCallback); - mFrameCallback = nullptr; - } - if (buffer) { - mFrameCallback = frame(); - wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this); - mWaitingForFrameSync = true; + handleUpdate(); buffer->setBusy(); - attach(buffer->buffer(), x, y); + QtWayland::wl_surface::attach(buffer->buffer(), x, y); } else { QtWayland::wl_surface::attach(nullptr, 0, 0); } @@ -618,11 +613,9 @@ void QWaylandWindow::frameCallback(void *data, struct wl_callback *callback, uin Q_UNUSED(callback); QWaylandWindow *self = static_cast(data); - self->mWaitingForFrameSync = false; - if (self->mUpdateRequested) { - self->mUpdateRequested = false; + self->mWaitingForFrameCallback = false; + if (self->mUpdateRequested) self->deliverUpdateRequest(); - } } QMutex QWaylandWindow::mFrameSyncMutex; @@ -630,10 +623,10 @@ QMutex QWaylandWindow::mFrameSyncMutex; void QWaylandWindow::waitForFrameSync() { QMutexLocker locker(&mFrameSyncMutex); - if (!mWaitingForFrameSync) + if (!mWaitingForFrameCallback) return; mDisplay->flushRequests(); - while (mWaitingForFrameSync) + while (mWaitingForFrameCallback) mDisplay->blockingReadEvents(); } @@ -1034,12 +1027,88 @@ QVariant QWaylandWindow::property(const QString &name, const QVariant &defaultVa return m_properties.value(name, defaultValue); } +void QWaylandWindow::timerEvent(QTimerEvent *event) +{ + if (event->timerId() == mFallbackUpdateTimerId) { + killTimer(mFallbackUpdateTimerId); + mFallbackUpdateTimerId = -1; + + if (!isExposed()) { + qCDebug(lcWaylandBackingstore) << "Fallback update timer: Window not exposed," + << "not delivering update request."; + return; + } + + if (mWaitingForUpdate && mUpdateRequested && !mWaitingForFrameCallback) { + qCWarning(lcWaylandBackingstore) << "Delivering update request through fallback timer," + << "may not be in sync with display"; + deliverUpdateRequest(); + } + } +} + void QWaylandWindow::requestUpdate() { - if (!mWaitingForFrameSync) - QPlatformWindow::requestUpdate(); - else - mUpdateRequested = true; + if (mUpdateRequested) + return; + + mUpdateRequested = true; + + // If we have a frame callback all is good and will be taken care of there + if (mWaitingForFrameCallback) + return; + + // If we've already called deliverUpdateRequest(), but haven't seen any attach+commit/swap yet + if (mWaitingForUpdate) { + // Ideally, we should just have returned here, but we're not guaranteed that the client + // will actually update, so start this timer to deliver another request update after a while + // *IF* the client doesn't update. + int fallbackTimeout = 100; + mFallbackUpdateTimerId = startTimer(fallbackTimeout); + return; + } + + // Some applications (such as Qt Quick) depend on updates being delivered asynchronously, + // so use invokeMethod to delay the delivery a bit. + QMetaObject::invokeMethod(this, [this] { + // Things might have changed in the meantime + if (mUpdateRequested && !mWaitingForUpdate && !mWaitingForFrameCallback) + deliverUpdateRequest(); + }, Qt::QueuedConnection); +} + +// Should be called whenever we commit a buffer (directly through wl_surface.commit or indirectly +// with eglSwapBuffers) to know when it's time to commit the next one. +// Can be called from the render thread (without locking anything) so make sure to not make races in this method. +void QWaylandWindow::handleUpdate() +{ + // TODO: Should sync subsurfaces avoid requesting frame callbacks? + + if (mFrameCallback) { + wl_callback_destroy(mFrameCallback); + mFrameCallback = nullptr; + } + + if (mFallbackUpdateTimerId != -1) { + // Ideally, we would stop the fallback timer here, but since we're on another thread, + // it's not allowed. Instead we set mFallbackUpdateTimer to -1 here, so we'll just + // ignore it if it times out before it's cleaned up by the invokeMethod call. + int id = mFallbackUpdateTimerId; + mFallbackUpdateTimerId = -1; + QMetaObject::invokeMethod(this, [=] { killTimer(id); }, Qt::QueuedConnection); + } + + mFrameCallback = frame(); + wl_callback_add_listener(mFrameCallback, &QWaylandWindow::callbackListener, this); + mWaitingForFrameCallback = true; + mWaitingForUpdate = false; +} + +void QWaylandWindow::deliverUpdateRequest() +{ + mUpdateRequested = false; + mWaitingForUpdate = true; + QPlatformWindow::deliverUpdateRequest(); } void QWaylandWindow::addAttachOffset(const QPoint point) diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 56ebd3cc6..e5838d231 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -191,7 +191,10 @@ public: bool startSystemMove(const QPoint &pos) override; + void timerEvent(QTimerEvent *event) override; void requestUpdate() override; + void handleUpdate(); + void deliverUpdateRequest() override; public slots: void applyConfigure(); @@ -211,10 +214,14 @@ protected: Qt::MouseButtons mMousePressedInContentArea = Qt::NoButton; WId mWindowId; - bool mWaitingForFrameSync = false; + bool mWaitingForFrameCallback = false; struct ::wl_callback *mFrameCallback = nullptr; QWaitCondition mFrameSyncWait; + // True when we have called deliverRequestUpdate, but the client has not yet attached a new buffer + bool mWaitingForUpdate = false; + int mFallbackUpdateTimerId = -1; + QMutex mResizeLock; bool mWaitingToApplyConfigure = false; bool mCanResize = true; diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp index e58403ad0..0cbbe5389 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp @@ -315,7 +315,9 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, QWaylandDisplay *dis mSupportNonBlockingSwap = false; } if (!mSupportNonBlockingSwap) { - qWarning() << "Non-blocking swap buffers not supported. Subsurface rendering can be affected."; + qWarning(lcQpaWayland) << "Non-blocking swap buffers not supported." + << "Subsurface rendering can be affected." + << "It may also cause the event loop to freeze in some situations"; } updateGLFormat(); @@ -550,20 +552,10 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) m_blitter->blit(window); } - - QWaylandSubSurface *sub = window->subSurfaceWindow(); - if (sub) { - QMutexLocker l(sub->syncMutex()); - - int si = (sub->isSync() && mSupportNonBlockingSwap) ? 0 : m_format.swapInterval(); - - eglSwapInterval(m_eglDisplay, si); - eglSwapBuffers(m_eglDisplay, eglSurface); - } else { - eglSwapInterval(m_eglDisplay, m_format.swapInterval()); - eglSwapBuffers(m_eglDisplay, eglSurface); - } - + window->handleUpdate(); + int swapInterval = mSupportNonBlockingSwap ? 0 : m_format.swapInterval(); + eglSwapInterval(m_eglDisplay, swapInterval); + eglSwapBuffers(m_eglDisplay, eglSurface); window->setCanResize(true); } -- cgit v1.2.3 From f2dc41b5babf0a7b51a1735f290540d7be695042 Mon Sep 17 00:00:00 2001 From: Johan Klokkhammer Helsing Date: Thu, 20 Dec 2018 11:52:12 +0100 Subject: Compositor: Fix crash in QWaylandSurface::waylandClient Adds a test for customSurface which crashed without the fix. Fixes: QTBUG-72688 Change-Id: I30c50e474379c61b90b2dd294eae9a7c88c105a2 Reviewed-by: Pier Luigi Fiorini --- src/compositor/compositor_api/qwaylandsurface.cpp | 13 +++++++++++ src/compositor/compositor_api/qwaylandsurface.h | 2 +- .../auto/compositor/compositor/tst_compositor.cpp | 27 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index 13ae28220..050ab5641 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -430,6 +430,19 @@ QWaylandClient *QWaylandSurface::client() const return d->client; } +/*! + * \property QWaylandSurface::waylandClient + * + * This property holds the \c wl_client using this QWaylandSurface. + */ +::wl_client *QWaylandSurface::waylandClient() const +{ + if (auto *c = client()) + return c->client(); + + return nullptr; +} + /*! * \qmlproperty bool QtWaylandCompositor::WaylandSurface::hasContent * diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index c208c16d4..a138b2af5 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -103,7 +103,7 @@ public: bool isInitialized() const; QWaylandClient *client() const; - struct wl_client *waylandClient() const { return client()->client(); } + ::wl_client *waylandClient() const; bool setRole(QWaylandSurfaceRole *role, wl_resource *errorResource, uint32_t errorCode); QWaylandSurfaceRole *role() const; diff --git a/tests/auto/compositor/compositor/tst_compositor.cpp b/tests/auto/compositor/compositor/tst_compositor.cpp index 97e650d97..e12aa564e 100644 --- a/tests/auto/compositor/compositor/tst_compositor.cpp +++ b/tests/auto/compositor/compositor/tst_compositor.cpp @@ -78,6 +78,7 @@ private slots: void mapSurfaceHiDpi(); void frameCallback(); void removeOutput(); + void customSurface(); void advertisesXdgShellSupport(); void createsXdgSurfaces(); @@ -613,6 +614,32 @@ void tst_WaylandCompositor::removeOutput() QTRY_COMPARE(client.m_outputs.size(), 1); } +class CustomSurface : public QWaylandSurface { + Q_OBJECT +public: + explicit CustomSurface() = default; +}; + +void tst_WaylandCompositor::customSurface() +{ + TestCompositor compositor; + QObject::connect(&compositor, &TestCompositor::surfaceRequested, this, [&compositor] (QWaylandClient *client, uint id, int version) { + auto *s = new CustomSurface(); + QCOMPARE(s->waylandClient(), nullptr); + s->initialize(&compositor, client, id, version); + QCOMPARE(s->waylandClient(), client->client()); + }); + QObject::connect(&compositor, &TestCompositor::surfaceCreated, this, [] (QWaylandSurface *surface) { + auto *custom = qobject_cast(surface); + QVERIFY(custom != nullptr); + }); + compositor.create(); + + MockClient client; + wl_surface *surface = client.createSurface(); + QTRY_COMPARE(compositor.surfaces.size(), 1); +} + void tst_WaylandCompositor::seatCapabilities() { TestCompositor compositor; -- cgit v1.2.3