summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--dist/changes-5.12.1037
-rw-r--r--dist/changes-5.12.656
-rw-r--r--dist/changes-5.12.725
-rw-r--r--dist/changes-5.12.820
-rw-r--r--dist/changes-5.12.927
-rw-r--r--src/client/qwaylanddisplay.cpp30
-rw-r--r--src/client/qwaylanddisplay_p.h2
-rw-r--r--src/client/qwaylandinputcontext.cpp6
-rw-r--r--src/client/qwaylandinputdevice.cpp2
-rw-r--r--src/client/qwaylandscreen.cpp50
-rw-r--r--src/client/qwaylandscreen_p.h7
-rw-r--r--src/client/qwaylandwindow.cpp60
-rw-r--r--src/client/qwaylandwindow_p.h5
-rw-r--r--src/compositor/compositor_api/qwaylandquickitem.cpp2
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandglcontext.cpp12
-rw-r--r--src/hardwareintegration/client/wayland-egl/qwaylandglcontext.h2
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;
};