diff options
-rw-r--r-- | .qmake.conf | 2 | ||||
-rw-r--r-- | dist/changes-5.12.10 | 37 | ||||
-rw-r--r-- | dist/changes-5.12.6 | 56 | ||||
-rw-r--r-- | dist/changes-5.12.7 | 25 | ||||
-rw-r--r-- | dist/changes-5.12.8 | 20 | ||||
-rw-r--r-- | dist/changes-5.12.9 | 27 | ||||
-rw-r--r-- | src/client/qwaylanddisplay.cpp | 30 | ||||
-rw-r--r-- | src/client/qwaylanddisplay_p.h | 2 | ||||
-rw-r--r-- | src/client/qwaylandinputcontext.cpp | 6 | ||||
-rw-r--r-- | src/client/qwaylandinputdevice.cpp | 2 | ||||
-rw-r--r-- | src/client/qwaylandscreen.cpp | 50 | ||||
-rw-r--r-- | src/client/qwaylandscreen_p.h | 7 | ||||
-rw-r--r-- | src/client/qwaylandwindow.cpp | 60 | ||||
-rw-r--r-- | src/client/qwaylandwindow_p.h | 5 | ||||
-rw-r--r-- | src/compositor/compositor_api/qwaylandquickitem.cpp | 2 | ||||
-rw-r--r-- | src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp | 12 | ||||
-rw-r--r-- | src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h | 2 |
17 files changed, 297 insertions, 48 deletions
diff --git a/.qmake.conf b/.qmake.conf index 2e1d6b7ff..912747cbb 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -1,3 +1,3 @@ load(qt_build_config) -MODULE_VERSION = 5.12.6 +MODULE_VERSION = 5.12.12 diff --git a/dist/changes-5.12.10 b/dist/changes-5.12.10 new file mode 100644 index 000000000..4fe368929 --- /dev/null +++ b/dist/changes-5.12.10 @@ -0,0 +1,37 @@ +Qt 5.12.10 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.9. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + https://doc.qt.io/qt-5.12/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +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. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + +**************************************************************************** +* Library * +**************************************************************************** + + +Client +------ + + - [QTBUG-84226] Added support for environment variable + QT_WAYLAND_FORCE_NONBLOCKING_SWAP_SUPPORT, which can be used to force the + resolution of detecting if EGL driver supports non-blocking eglSwapBuffers + call. If you encounter application freezing while waiting indefinitely for a + buffer swap, then try setting variable to 0. + diff --git a/dist/changes-5.12.6 b/dist/changes-5.12.6 new file mode 100644 index 000000000..7d67fe14a --- /dev/null +++ b/dist/changes-5.12.6 @@ -0,0 +1,56 @@ +Qt 5.12.6 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.5. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +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 * +**************************************************************************** + + - Fixed various rounding errors related to touch and mouse input. + - Fixed a crash when trying to maximize an XdgTopLevel with no output. + + - Important Behavior Changes: + * Fixed potential memory access violation. + Between version 5.11 and 5.12 binary compatibility for the + wayland compositor module was broken by increasing the size of + various classes. This was unfortunately not visible in public + headers. As a consequence, application C++ code allocating or + subclassing any of the following classes would have potential + memory access violations: QWaylandKeymap, QWaylandQuickOutput, + QWaylandQuickSurface, QWaylandIviSurface, QWaylandWlShellSurface, + QWaylandXdgSurface, QWaylandXdgSurfaceV5, QWaylandXdgPopupV5, + QWaylandXdgSurfaceV6. To mitigate this issue, upgrade Qt to + 5.12.6 and recompile all compositor code. Do not run a compositor + built with 5.11 or earlier against Qt versions 5.12 or later. + +**************************************************************************** +* QPA plugin * +**************************************************************************** + + - Fixed a freeze that happened when starting a drag-and-drop operation + without a valid source surface. + - Fixed a 100 ms freeze that would occur if applications did not draw + after receiving a deliverUpdateRequest(). + - Fixed touch point position rounding errors. + - Fixed a freeze that could happen when showing a window. + - Fixed an issue where touch focus would be set to false before all touch + points where released. + - Fixed touch event touch points sometimes being reordered, which caused + issues with QtQuick's MultiPointTouchArea. + - Fixed a crash that happened with very long window titles using UTF-16 + characters. diff --git a/dist/changes-5.12.7 b/dist/changes-5.12.7 new file mode 100644 index 000000000..fd8d3ba03 --- /dev/null +++ b/dist/changes-5.12.7 @@ -0,0 +1,25 @@ +Qt 5.12.7 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.6. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +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. + +**************************************************************************** +* QPA plugin * +**************************************************************************** + + - Fixed a crash when re-showing a popup after hiding its parent. + - Fixed a compile error. diff --git a/dist/changes-5.12.8 b/dist/changes-5.12.8 new file mode 100644 index 000000000..729d74045 --- /dev/null +++ b/dist/changes-5.12.8 @@ -0,0 +1,20 @@ +Qt 5.12.8 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.7. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +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. + + - This release contains only minor code improvements. diff --git a/dist/changes-5.12.9 b/dist/changes-5.12.9 new file mode 100644 index 000000000..dd4fa247d --- /dev/null +++ b/dist/changes-5.12.9 @@ -0,0 +1,27 @@ +Qt 5.12.9 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.12.0 through 5.12.8. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + +https://doc.qt.io/qt-5/index.html + +The Qt version 5.12 series is binary compatible with the 5.11.x series. +Applications compiled for 5.11 will continue to run with 5.12. + +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. + +**************************************************************************** +* Client * +**************************************************************************** + + - [QTBUG-82914] Added support for QT_WAYLAND_FRAME_CALLBACK_TIMEOUT + environment variable, which can be used to disable or change the + internal frame callback timeout. If you see windows that stop rendering + or minimize on heavy load, then try setting the variable to 0. diff --git a/src/client/qwaylanddisplay.cpp b/src/client/qwaylanddisplay.cpp index 14469fe6d..d13255036 100644 --- a/src/client/qwaylanddisplay.cpp +++ b/src/client/qwaylanddisplay.cpp @@ -146,6 +146,11 @@ QWaylandDisplay::QWaylandDisplay(QWaylandIntegration *waylandIntegration) mWindowManagerIntegration.reset(new QWaylandWindowManagerIntegration(this)); forceRoundTrip(); + + if (!mWaitingScreens.isEmpty()) { + // Give wl_output.done and zxdg_output_v1.done events a chance to arrive + forceRoundTrip(); + } } QWaylandDisplay::~QWaylandDisplay(void) @@ -160,6 +165,7 @@ QWaylandDisplay::~QWaylandDisplay(void) mWaylandIntegration->destroyScreen(screen); } mScreens.clear(); + qDeleteAll(mWaitingScreens); #if QT_CONFIG(wayland_datadevice) delete mDndSelectionHandler.take(); @@ -244,6 +250,14 @@ QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output) const return nullptr; } +void QWaylandDisplay::handleScreenInitialized(QWaylandScreen *screen) +{ + if (!mWaitingScreens.removeOne(screen)) + return; + mScreens.append(screen); + QWindowSystemInterface::handleScreenAdded(screen); +} + void QWaylandDisplay::waitForScreens() { flushRequests(); @@ -270,11 +284,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin struct ::wl_registry *registry = object(); if (interface == QStringLiteral("wl_output")) { - QWaylandScreen *screen = new QWaylandScreen(this, version, id); - mScreens.append(screen); - // We need to get the output events before creating surfaces - forceRoundTrip(); - mWaylandIntegration->screenAdded(screen); + mWaitingScreens << new QWaylandScreen(this, version, id); } else if (interface == QStringLiteral("wl_compositor")) { mCompositorVersion = qMin((int)version, 3); mCompositor.init(registry, id, mCompositorVersion); @@ -307,7 +317,7 @@ void QWaylandDisplay::registry_global(uint32_t id, const QString &interface, uin forceRoundTrip(); } else if (interface == QLatin1String("zxdg_output_manager_v1")) { mXdgOutputManager.reset(new QtWayland::zxdg_output_manager_v1(registry, id, 1)); - for (auto *screen : qAsConst(mScreens)) + for (auto *screen : qAsConst(mWaitingScreens)) screen->initXdgOutput(xdgOutputManager()); forceRoundTrip(); } @@ -324,6 +334,14 @@ void QWaylandDisplay::registry_global_remove(uint32_t id) RegistryGlobal &global = mGlobals[i]; if (global.id == id) { if (global.interface == QStringLiteral("wl_output")) { + for (auto *screen : mWaitingScreens) { + if (screen->outputId() == id) { + mWaitingScreens.removeOne(screen); + delete screen; + break; + } + } + foreach (QWaylandScreen *screen, mScreens) { if (screen->outputId() == id) { mScreens.removeOne(screen); diff --git a/src/client/qwaylanddisplay_p.h b/src/client/qwaylanddisplay_p.h index ae8ec0ab8..93208e646 100644 --- a/src/client/qwaylanddisplay_p.h +++ b/src/client/qwaylanddisplay_p.h @@ -113,6 +113,7 @@ public: QList<QWaylandScreen *> screens() const { return mScreens; } QWaylandScreen *screenForOutput(struct wl_output *output) const; + void handleScreenInitialized(QWaylandScreen *screen); struct wl_surface *createSurface(void *handle); struct ::wl_region *createRegion(const QRegion &qregion); @@ -209,6 +210,7 @@ private: struct wl_display *mDisplay = nullptr; QtWayland::wl_compositor mCompositor; QScopedPointer<QWaylandShm> mShm; + QList<QWaylandScreen *> mWaitingScreens; QList<QWaylandScreen *> mScreens; QList<QWaylandInputDevice *> mInputDevices; QList<Listener> mRegistryListeners; diff --git a/src/client/qwaylandinputcontext.cpp b/src/client/qwaylandinputcontext.cpp index e85faaf8e..8ece14a18 100644 --- a/src/client/qwaylandinputcontext.cpp +++ b/src/client/qwaylandinputcontext.cpp @@ -375,8 +375,10 @@ void QWaylandTextInput::zwp_text_input_v2_input_method_changed(uint32_t serial, Qt::KeyboardModifiers QWaylandTextInput::modifiersToQtModifiers(uint32_t modifiers) { Qt::KeyboardModifiers ret = Qt::NoModifier; - for (int i = 0; modifiers >>= 1; ++i) { - ret |= m_modifiersMap[i]; + for (int i = 0; i < m_modifiersMap.size(); ++i) { + if (modifiers & (1 << i)) { + ret |= m_modifiersMap[i]; + } } return ret; } diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp index 107442daf..18eb8915b 100644 --- a/src/client/qwaylandinputdevice.cpp +++ b/src/client/qwaylandinputdevice.cpp @@ -912,7 +912,7 @@ void QWaylandInputDevice::Touch::touch_cancel() void QWaylandInputDevice::handleTouchPoint(int id, Qt::TouchPointState state, const QPointF &surfacePosition) { auto end = mTouch->mPendingTouchPoints.end(); - auto it = std::find_if(mTouch->mPendingTouchPoints.begin(), end, [id](auto tp){ return tp.id == id; }); + auto it = std::find_if(mTouch->mPendingTouchPoints.begin(), end, [id](const QWindowSystemInterface::TouchPoint &tp){ return tp.id == id; }); if (it == end) { it = mTouch->mPendingTouchPoints.insert(end, QWindowSystemInterface::TouchPoint()); it->id = id; diff --git a/src/client/qwaylandscreen.cpp b/src/client/qwaylandscreen.cpp index 1fe0125e6..55479f6fd 100644 --- a/src/client/qwaylandscreen.cpp +++ b/src/client/qwaylandscreen.cpp @@ -40,6 +40,7 @@ #include "qwaylandscreen_p.h" #include "qwaylanddisplay_p.h" +#include "qwaylandintegration_p.h" #include "qwaylandcursor_p.h" #include "qwaylandwindow_p.h" @@ -60,6 +61,14 @@ QWaylandScreen::QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uin { if (auto *xdgOutputManager = waylandDisplay->xdgOutputManager()) initXdgOutput(xdgOutputManager); + + if (version < WL_OUTPUT_DONE_SINCE_VERSION) { + qCWarning(lcQpaWayland) << "wl_output done event not supported by compositor," + << "QScreen may not work correctly"; + mWaylandDisplay->forceRoundTrip(); // Give the compositor a chance to send geometry etc. + mOutputDone = true; // Fake the done event + maybeInitialize(); + } } QWaylandScreen::~QWaylandScreen() @@ -68,6 +77,24 @@ QWaylandScreen::~QWaylandScreen() zxdg_output_v1::destroy(); } +void QWaylandScreen::maybeInitialize() +{ + Q_ASSERT(!mInitialized); + + if (!mOutputDone) + return; + + if (mWaylandDisplay->xdgOutputManager() && !mXdgOutputDone) + return; + + mInitialized = true; + mWaylandDisplay->handleScreenInitialized(this); + + updateOutputProperties(); + if (zxdg_output_v1::isInitialized()) + updateXdgOutputProperties(); +} + void QWaylandScreen::initXdgOutput(QtWayland::zxdg_output_manager_v1 *xdgOutputManager) { Q_ASSERT(xdgOutputManager); @@ -242,10 +269,15 @@ void QWaylandScreen::output_scale(int32_t factor) void QWaylandScreen::output_done() { - // the done event is sent after all the geometry and the mode events are sent, - // and the last mode event to be sent is the active one, so we can trust the - // values of mGeometry and mRefreshRate here + mOutputDone = true; + if (mInitialized) + updateOutputProperties(); + else + maybeInitialize(); +} +void QWaylandScreen::updateOutputProperties() +{ if (mTransform >= 0) { bool isPortrait = mGeometry.height() > mGeometry.width(); switch (mTransform) { @@ -272,7 +304,9 @@ void QWaylandScreen::output_done() QWindowSystemInterface::handleScreenOrientationChange(screen(), m_orientation); mTransform = -1; } + QWindowSystemInterface::handleScreenRefreshRateChange(screen(), refreshRate()); + if (!zxdg_output_v1::isInitialized()) QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), geometry()); } @@ -290,6 +324,16 @@ void QWaylandScreen::zxdg_output_v1_logical_size(int32_t width, int32_t height) void QWaylandScreen::zxdg_output_v1_done() { + mXdgOutputDone = true; + if (mInitialized) + updateXdgOutputProperties(); + else + maybeInitialize(); +} + +void QWaylandScreen::updateXdgOutputProperties() +{ + Q_ASSERT(zxdg_output_v1::isInitialized()); QWindowSystemInterface::handleScreenGeometryChange(screen(), geometry(), geometry()); } diff --git a/src/client/qwaylandscreen_p.h b/src/client/qwaylandscreen_p.h index 6e4ed94f7..b726cd05e 100644 --- a/src/client/qwaylandscreen_p.h +++ b/src/client/qwaylandscreen_p.h @@ -71,6 +71,8 @@ public: QWaylandScreen(QWaylandDisplay *waylandDisplay, int version, uint32_t id); ~QWaylandScreen() override; + void maybeInitialize(); + void initXdgOutput(QtWayland::zxdg_output_manager_v1 *xdgOutputManager); QWaylandDisplay *display() const; @@ -117,11 +119,13 @@ private: int32_t transform) override; void output_scale(int32_t factor) override; void output_done() override; + void updateOutputProperties(); // XdgOutput void zxdg_output_v1_logical_position(int32_t x, int32_t y) override; void zxdg_output_v1_logical_size(int32_t width, int32_t height) override; void zxdg_output_v1_done() override; + void updateXdgOutputProperties(); int m_outputId; QWaylandDisplay *mWaylandDisplay = nullptr; @@ -137,6 +141,9 @@ private: QSize mPhysicalSize; QString mOutputName; Qt::ScreenOrientation m_orientation = Qt::PrimaryOrientation; + bool mOutputDone = false; + bool mXdgOutputDone = false; + bool mInitialized = false; #if QT_CONFIG(cursor) QScopedPointer<QWaylandCursor> mWaylandCursor; diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp index 9e63fa17a..29bc0581c 100644 --- a/src/client/qwaylandwindow.cpp +++ b/src/client/qwaylandwindow.cpp @@ -85,6 +85,13 @@ QWaylandWindow::QWaylandWindow(QWindow *window) , mFrameQueue(mDisplay->createEventQueue()) , mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP")) { + { + bool ok; + int frameCallbackTimeout = qEnvironmentVariableIntValue("QT_WAYLAND_FRAME_CALLBACK_TIMEOUT", &ok); + if (ok) + mFrameCallbackTimeout = frameCallbackTimeout; + } + static WId id = 1; mWindowId = id++; connect(qApp, &QGuiApplication::screenRemoved, this, &QWaylandWindow::handleScreenRemoved); @@ -263,10 +270,7 @@ void QWaylandWindow::reset(bool sendDestroyEvent) mFrameCallback = nullptr; } - int timerId = mFrameCallbackTimerId.fetchAndStoreOrdered(-1); - if (timerId != -1) { - killTimer(timerId); - } + mFrameCallbackElapsedTimer.invalidate(); mWaitingForFrameCallback = false; mFrameCallbackTimedOut = false; @@ -424,8 +428,7 @@ void QWaylandWindow::setVisible(bool visible) // QWaylandShmBackingStore::beginPaint(). } else { sendExposeEvent(QRect()); - if (window()->type() == Qt::Popup) - closePopups(this); + closePopups(this); reset(); } } @@ -636,15 +639,11 @@ const wl_callback_listener QWaylandWindow::callbackListener = { void QWaylandWindow::handleFrameCallback() { - // Stop the timer and stop waiting immediately - int timerId = mFrameCallbackTimerId.fetchAndStoreOrdered(-1); mWaitingForFrameCallback = false; + mFrameCallbackElapsedTimer.invalidate(); // The rest can wait until we can run it on the correct thread - auto doHandleExpose = [this, timerId]() { - if (timerId != -1) - killTimer(timerId); - + auto doHandleExpose = [this]() { bool wasExposed = isExposed(); mFrameCallbackTimedOut = false; if (!wasExposed && isExposed()) // Did setting mFrameCallbackTimedOut make the window exposed? @@ -679,13 +678,6 @@ bool QWaylandWindow::waitForFrameSync(int timeout) sendExposeEvent(QRect()); } - // Stop current frame timer if any, can't use killTimer directly, because we might be on a diffent thread - // Ordered semantics is needed to avoid stopping the timer twice and not miss it when it's - // started by other writes - int fcbId = mFrameCallbackTimerId.fetchAndStoreOrdered(-1); - if (fcbId != -1) - QMetaObject::invokeMethod(this, [this, fcbId] { killTimer(fcbId); }, Qt::QueuedConnection); - return !mWaitingForFrameCallback; } @@ -1098,8 +1090,16 @@ QVariant QWaylandWindow::property(const QString &name, const QVariant &defaultVa void QWaylandWindow::timerEvent(QTimerEvent *event) { - if (mFrameCallbackTimerId.testAndSetOrdered(event->timerId(), -1)) { - killTimer(event->timerId()); + if (event->timerId() != mFrameCallbackCheckIntervalTimerId) + return; + + bool callbackTimerExpired = mFrameCallbackElapsedTimer.hasExpired(mFrameCallbackTimeout); + if (!mFrameCallbackElapsedTimer.isValid() || callbackTimerExpired ) { + killTimer(mFrameCallbackCheckIntervalTimerId); + mFrameCallbackCheckIntervalTimerId = -1; + } + if (mFrameCallbackElapsedTimer.isValid() && callbackTimerExpired) { + mFrameCallbackElapsedTimer.invalidate(); qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in time, window should now be inexposed"; mFrameCallbackTimedOut = true; mWaitingForUpdate = false; @@ -1153,16 +1153,16 @@ void QWaylandWindow::handleUpdate() mWaitingForFrameCallback = true; mWaitingForUpdate = false; - // Stop current frame timer if any, can't use killTimer directly, see comment above. - int fcbId = mFrameCallbackTimerId.fetchAndStoreOrdered(-1); - if (fcbId != -1) - QMetaObject::invokeMethod(this, [this, fcbId] { killTimer(fcbId); }, Qt::QueuedConnection); - // Start a timer for handling the case when the compositor stops sending frame callbacks. - QMetaObject::invokeMethod(this, [this] { // Again; can't do it directly - if (mWaitingForFrameCallback) - mFrameCallbackTimerId = startTimer(100); - }, Qt::QueuedConnection); + if (mFrameCallbackTimeout > 0) { + QMetaObject::invokeMethod(this, [this] { + if (mWaitingForFrameCallback) { + if (mFrameCallbackCheckIntervalTimerId < 0) + mFrameCallbackCheckIntervalTimerId = startTimer(mFrameCallbackTimeout); + mFrameCallbackElapsedTimer.start(); + } + }, Qt::QueuedConnection); + } } void QWaylandWindow::deliverUpdateRequest() diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h index 0369bd0c2..609171837 100644 --- a/src/client/qwaylandwindow_p.h +++ b/src/client/qwaylandwindow_p.h @@ -58,6 +58,7 @@ #include <QtGui/QIcon> #include <QtCore/QVariant> #include <QtCore/QLoggingCategory> +#include <QtCore/QElapsedTimer> #include <qpa/qplatformwindow.h> @@ -222,7 +223,8 @@ protected: WId mWindowId; bool mWaitingForFrameCallback = false; bool mFrameCallbackTimedOut = false; // Whether the frame callback has timed out - QAtomicInt mFrameCallbackTimerId = -1; // Started on commit, reset on frame callback + int mFrameCallbackCheckIntervalTimerId = -1; + QElapsedTimer mFrameCallbackElapsedTimer; struct ::wl_callback *mFrameCallback = nullptr; struct ::wl_event_queue *mFrameQueue = nullptr; QWaitCondition mFrameSyncWait; @@ -235,6 +237,7 @@ protected: bool mCanResize = true; bool mResizeDirty = false; bool mResizeAfterSwap; + int mFrameCallbackTimeout = 100; QVariantMap m_properties; bool mSentInitialResize = false; diff --git a/src/compositor/compositor_api/qwaylandquickitem.cpp b/src/compositor/compositor_api/qwaylandquickitem.cpp index 5010247f9..865363ecf 100644 --- a/src/compositor/compositor_api/qwaylandquickitem.cpp +++ b/src/compositor/compositor_api/qwaylandquickitem.cpp @@ -723,7 +723,9 @@ void QWaylandQuickItem::handleSubsurfaceAdded(QWaylandSurface *childSurface) childItem->setSurface(childSurface); childItem->setVisible(true); childItem->setParentItem(this); + childItem->setParent(this); connect(childSurface, &QWaylandSurface::subsurfacePositionChanged, childItem, &QWaylandQuickItem::handleSubsurfacePosition); + connect(childSurface, &QWaylandSurface::destroyed, childItem, &QObject::deleteLater); } else { bool success = QMetaObject::invokeMethod(d->subsurfaceHandler, "handleSubsurfaceAdded", Q_ARG(QWaylandSurface *, childSurface)); if (!success) diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp index 6b9776e9c..6f2156169 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp +++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp @@ -313,9 +313,15 @@ QWaylandGLContext::QWaylandGLContext(EGLDisplay eglDisplay, QWaylandDisplay *dis if (!eglGetConfigAttrib(m_eglDisplay, m_config, a, &a) || !eglGetConfigAttrib(m_eglDisplay, m_config, b, &b) || a > 0) { - mSupportNonBlockingSwap = false; + m_supportNonBlockingSwap = false; } - if (!mSupportNonBlockingSwap) { + { + bool ok; + int supportNonBlockingSwap = qEnvironmentVariableIntValue("QT_WAYLAND_FORCE_NONBLOCKING_SWAP_SUPPORT", &ok); + if (ok) + m_supportNonBlockingSwap = supportNonBlockingSwap != 0; + } + if (!m_supportNonBlockingSwap) { 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"; @@ -558,7 +564,7 @@ void QWaylandGLContext::swapBuffers(QPlatformSurface *surface) m_blitter->blit(window); } - int swapInterval = mSupportNonBlockingSwap ? 0 : m_format.swapInterval(); + int swapInterval = m_supportNonBlockingSwap ? 0 : m_format.swapInterval(); eglSwapInterval(m_eglDisplay, swapInterval); if (swapInterval == 0 && m_format.swapInterval() > 0) { // Emulating a blocking swap diff --git a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h index 9e876ac17..e704792ea 100644 --- a/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h +++ b/src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h @@ -92,7 +92,7 @@ private: DecorationsBlitter *m_blitter = nullptr; bool mUseNativeDefaultFbo = false; uint m_api; - bool mSupportNonBlockingSwap = true; + bool m_supportNonBlockingSwap = true; friend class DecorationsBlitter; }; |