diff options
author | Liang Qi <liang.qi@qt.io> | 2018-12-22 18:53:35 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2018-12-22 18:53:35 +0100 |
commit | 5a6020f6efb4f09a77745614c6d1c0369bc5e365 (patch) | |
tree | ed8dec085d4f2a7ac359e5bbbb432b8449fb82fa | |
parent | ed03ec25de7e44d8e9a6aea359518851f5a8efa9 (diff) | |
parent | f2dc41b5babf0a7b51a1735f290540d7be695042 (diff) | |
download | qtwayland-5a6020f6efb4f09a77745614c6d1c0369bc5e365.tar.gz |
Merge remote-tracking branch 'origin/5.12' into dev
Conflicts:
README
src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri
Change-Id: I7cbbf39916821f0f1749e3ccab3151f68f4aa1ac
26 files changed, 265 insertions, 100 deletions
@@ -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.8.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/dist/changes-5.11.3 b/dist/changes-5.11.3 new file mode 100644 index 00000000..c3f1060b --- /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. diff --git a/src/client/client.pro b/src/client/client.pro index 42e7cae8..38d0ac3e 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 qtHaveModule(linuxaccessibility_support_private): \ QT += linuxaccessibility_support_private diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index e35c83ae..49f1ab24 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -70,7 +70,7 @@ #include <QtGui/QGuiApplication> -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) #include <xkbcommon/xkbcommon-compose.h> #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 @@ -343,7 +343,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; @@ -627,7 +627,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; @@ -730,7 +730,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; } @@ -773,7 +773,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 ) { @@ -781,7 +781,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(mRepeatDelay); @@ -795,7 +795,7 @@ void QWaylandInputDevice::Keyboard::repeatKey() { mRepeatTimer.setInterval(mRepeatRate); sendKey(mFocus->window(), mRepeatTime, QEvent::KeyRelease, mRepeatKey, modifiers(), mRepeatCode, -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) mRepeatSym, mNativeModifiers, #else 0, 0, @@ -803,7 +803,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, @@ -818,7 +818,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 d1ff0da2..f27f329b 100644 --- a/src/client/qwaylandinputdevice_p.h +++ b/src/client/qwaylandinputdevice_p.h @@ -63,7 +63,7 @@ #include <QtWaylandClient/private/qwayland-wayland.h> -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) #include <xkbcommon/xkbcommon.h> #include <xkbcommon/xkbcommon-keysyms.h> #endif @@ -75,7 +75,7 @@ struct wl_cursor_image; #endif -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) struct xkb_compose_state; struct xkb_compose_table; #endif @@ -208,7 +208,7 @@ public: QWaylandInputDevice *mParent = nullptr; QPointer<QWaylandWindow> mFocus; -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) xkb_context *mXkbContext = nullptr; xkb_keymap *mXkbMap = nullptr; xkb_state *mXkbState = nullptr; @@ -223,7 +223,7 @@ public: int mRepeatRate = 25; int mRepeatDelay = 400; QString mRepeatText; -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) xkb_keysym_t mRepeatSym; #endif QTimer mRepeatTimer; @@ -234,7 +234,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/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 029820e2..a5eba5b2 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -356,6 +356,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; } @@ -544,18 +546,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); } @@ -620,11 +615,9 @@ void QWaylandWindow::frameCallback(void *data, struct wl_callback *callback, uin Q_UNUSED(callback); QWaylandWindow *self = static_cast<QWaylandWindow*>(data); - self->mWaitingForFrameSync = false; - if (self->mUpdateRequested) { - self->mUpdateRequested = false; + self->mWaitingForFrameCallback = false; + if (self->mUpdateRequested) self->deliverUpdateRequest(); - } } QMutex QWaylandWindow::mFrameSyncMutex; @@ -632,10 +625,10 @@ QMutex QWaylandWindow::mFrameSyncMutex; void QWaylandWindow::waitForFrameSync() { QMutexLocker locker(&mFrameSyncMutex); - if (!mWaitingForFrameSync) + if (!mWaitingForFrameCallback) return; mDisplay->flushRequests(); - while (mWaitingForFrameSync) + while (mWaitingForFrameCallback) mDisplay->blockingReadEvents(); } @@ -1036,12 +1029,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 56ebd3cc..e5838d23 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/compositor/compositor_api/qwaylandcompositor.cpp b/src/compositor/compositor_api/qwaylandcompositor.cpp index c782304e..173b50ce 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 e067eeaf..68d855a6 100644 --- a/src/compositor/compositor_api/qwaylandkeyboard.cpp +++ b/src/compositor/compositor_api/qwaylandkeyboard.cpp @@ -51,7 +51,7 @@ #include <fcntl.h> #include <unistd.h> -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) #include <sys/mman.h> #include <sys/types.h> #include <qwaylandxkb_p.h> @@ -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<QWaylandKeyboardPrivate *>(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 cd1f2795..87e89e85 100644 --- a/src/compositor/compositor_api/qwaylandkeyboard_p.h +++ b/src/compositor/compositor_api/qwaylandkeyboard_p.h @@ -62,7 +62,7 @@ #include <QtCore/QVector> -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) #include <xkbcommon/xkbcommon.h> #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/compositor_api/qwaylandoutputmode.cpp b/src/compositor/compositor_api/qwaylandoutputmode.cpp index 54587117..79a58160 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/src/compositor/compositor_api/qwaylandsurface.cpp b/src/compositor/compositor_api/qwaylandsurface.cpp index be08b17c..8ad2389b 100644 --- a/src/compositor/compositor_api/qwaylandsurface.cpp +++ b/src/compositor/compositor_api/qwaylandsurface.cpp @@ -441,6 +441,19 @@ QWaylandClient *QWaylandSurface::client() const } /*! + * \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 * * This property holds whether the WaylandSurface has content. diff --git a/src/compositor/compositor_api/qwaylandsurface.h b/src/compositor/compositor_api/qwaylandsurface.h index cd08a3d2..13f09f33 100644 --- a/src/compositor/compositor_api/qwaylandsurface.h +++ b/src/compositor/compositor_api/qwaylandsurface.h @@ -106,7 +106,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/src/compositor/wayland_wrapper/wayland_wrapper.pri b/src/compositor/wayland_wrapper/wayland_wrapper.pri index 3e29fb10..b0c8371f 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/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandeglwindow.cpp index f10a7469..24dadff4 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(); diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp index e58403ad..0cbbe538 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); } diff --git a/src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri b/src/hardwareintegration/client/xcomposite_share/xcomposite_share.pri index a9120c26..d2b129d0 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-client-wayland-protocol-include WAYLANDCLIENTSOURCES += $$PWD/../../../extensions/xcomposite.xml diff --git a/src/plugins/shellintegration/ivi-shell/ivi-shell.pro b/src/plugins/shellintegration/ivi-shell/ivi-shell.pro index ba716c10..67e659ab 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 fbff63c7..bb2c1829 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 bf9edba7..4f6dde9b 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 5d5046f6..3c1aaee8 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 2b1191af..26171584 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 a0e388a1..3cfc4b07 100644 --- a/src/shared/qwaylandxkb.cpp +++ b/src/shared/qwaylandxkb.cpp @@ -43,13 +43,13 @@ #include <QKeyEvent> #include <QString> -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) #include <xkbcommon/xkbcommon-keysyms.h> #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<int, QString> 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<int, QString> 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_component>(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED | XKB_STATE_LOCKED); @@ -367,7 +367,7 @@ QEvent::Type QWaylandXkb::toQtEventType(uint32_t state) QVector<xkb_keysym_t> QWaylandXkb::toKeysym(QKeyEvent *event) { -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) QVector<xkb_keysym_t> 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 6fa1ea45..4820d94b 100644 --- a/src/shared/qwaylandxkb_p.h +++ b/src/shared/qwaylandxkb_p.h @@ -45,7 +45,7 @@ #include <Qt> #include <QEvent> -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) #include <xkbcommon/xkbcommon.h> #else typedef quint32 xkb_keysym_t; diff --git a/tests/auto/compositor/compositor/compositor.pro b/tests/auto/compositor/compositor/compositor.pro index 29443f7a..7cf40557 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 78e01af7..8335690f 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(); @@ -73,11 +73,13 @@ private slots: void multipleClients(); void geometry(); void modes(); + void comparingModes(); void sizeFollowsWindow(); void mapSurface(); void mapSurfaceHiDpi(); void frameCallback(); void removeOutput(); + void customSurface(); void advertisesXdgShellSupport(); void createsXdgSurfaces(); @@ -170,7 +172,7 @@ void tst_WaylandCompositor::multipleClients() QTRY_COMPARE(compositor.surfaces.size(), 0); } -#if QT_CONFIG(xkbcommon_evdev) +#if QT_CONFIG(xkbcommon) void tst_WaylandCompositor::simpleKeyboard() { @@ -283,7 +285,7 @@ void tst_WaylandCompositor::keyboardLayoutSwitching() QTRY_COMPARE(mockKeyboard->m_lastKeyCode, 44u); } -#endif // QT_CONFIG(xkbcommon_evdev) +#endif // QT_CONFIG(xkbcommon) void tst_WaylandCompositor::keyboardGrab() { @@ -374,6 +376,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, mode3}) + QVERIFY(mode4 != mode); +} + void tst_WaylandCompositor::sizeFollowsWindow() { TestCompositor compositor; @@ -599,6 +623,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<CustomSurface *>(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; |