This commit is contained in:
Jan Grulich 2020-09-10 17:09:52 +02:00
parent 527d59d725
commit 52af82532c
11 changed files with 7 additions and 656 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@
/qtwayland-everywhere-src-5.12.5.tar.xz /qtwayland-everywhere-src-5.12.5.tar.xz
/qtwayland-everywhere-src-5.13.2.tar.xz /qtwayland-everywhere-src-5.13.2.tar.xz
/qtwayland-everywhere-src-5.14.2.tar.xz /qtwayland-everywhere-src-5.14.2.tar.xz
/qtwayland-everywhere-src-5.15.1.tar.xz

View File

@ -2,35 +2,20 @@
Summary: Qt5 - Wayland platform support and QtCompositor module Summary: Qt5 - Wayland platform support and QtCompositor module
Name: qt5-%{qt_module} Name: qt5-%{qt_module}
Version: 5.14.2 Version: 5.15.1
Release: 6%{?dist} Release: 1%{?dist}
License: LGPLv3 License: LGPLv3
Url: http://www.qt.io Url: http://www.qt.io
%global majmin %(echo %{version} | cut -d. -f1-2) %global majmin %(echo %{version} | cut -d. -f1-2)
Source0: https://download.qt.io/official_releases/qt/%{majmin}/%{version}/submodules/%{qt_module}-everywhere-src-%{version}.tar.xz Source0: https://download.qt.io/official_releases/qt/%{majmin}/%{version}/submodules/%{qt_module}-everywhere-src-%{version}.tar.xz
# Bold fonts in qt applications appear much too heavy
# https://bugzilla.redhat.com/show_bug.cgi?id=1823984
Patch0: qtwayland-dont-force-gamma-correction-off.patch
# Transferring large amounts of data via clipboard may lead to
# stack overflow and segmentation fault because of recursion in
# QtWaylandClient::QWaylandMimeData::readData().
Patch1: qtwayland-remove-recursion-in-data-offer-retrieval.patch
# Upstreamable patches # Upstreamable patches
# https://fedoraproject.org/wiki/Changes/Qt_Wayland_By_Default_On_Gnome # https://fedoraproject.org/wiki/Changes/Qt_Wayland_By_Default_On_Gnome
# https://bugzilla.redhat.com/show_bug.cgi?id=1732129 # https://bugzilla.redhat.com/show_bug.cgi?id=1732129
Patch50: qtwayland-use-gnome-platform-theme-on-gnome-based-desktops.patch Patch50: qtwayland-use-gnome-platform-theme-on-gnome-based-desktops.patch
# Upstream patches
Patch100: qtwayland-fix-leaking-of-callback-timers.patch
Patch101: qtwayland-client-make-frameback-callback-timeout-configurable.patch
Patch102: qtwayland-client-fix-scroll-direction-with-touchpads.patch
Patch103: qtwayland-client-initialize-mscale-on-creation-instead-of-on-show.patch
Patch104: qtwayland-client-send-subsurface-expose-event-when-toplevel-is-configured.patch
Patch105: qtwayland-client-dont-send-fakt-surface-created-destroyed-events.patch
# filter qml provides # filter qml provides
%global __provides_exclude_from ^%{_qt5_archdatadir}/qml/.*\\.so$ %global __provides_exclude_from ^%{_qt5_archdatadir}/qml/.*\\.so$
@ -137,6 +122,9 @@ popd
%changelog %changelog
* Thu Sep 10 2020 Jan Grulich <jgrulich@redhat.com> - 5.15.1-1
- 5.15.1
* Sat Aug 01 2020 Fedora Release Engineering <releng@fedoraproject.org> - 5.14.2-6 * Sat Aug 01 2020 Fedora Release Engineering <releng@fedoraproject.org> - 5.14.2-6
- Second attempt - Rebuilt for - Second attempt - Rebuilt for
https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild

View File

@ -1,92 +0,0 @@
From cd21404f99b486ff62225699e1a4bdc0d5b3d5c1 Mon Sep 17 00:00:00 2001
From: David Edmundson <davidedmundson@kde.org>
Date: Sun, 23 Jun 2019 15:09:51 +0200
Subject: [PATCH] Client: Don't send fake SurfaceCreated/Destroyed events
QPlatformSurface relates to the platform window, not the wl_surface.
The events are already emitted by QPlatformWindow on create/destroy.
To preserve compatibility for a previous KDE version it was faked to
emit the events when the wl_surface is created/hidden to keep behavior.
This is no longer necessary, and it has caused multiple errors, the latest
being a crash when switching between sub-menus with the Sway compositor.
[ChangeLog][QPA plugin] QWaylandWindow no longer sends fake SurfaceCreated/Destroyed events.
Use expose events to be notified when a Wayland surface appears.
Task-number: QTBUG-76324
Fixes: QTBUG-81952
Pick-to: 5.15
Change-Id: I2f003bc9da85f032a0053677fd281152099fc9eb
Reviewed-by: Paul Olav Tvete <paul.tvete@qt.io>
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Reviewed-by: David Edmundson <davidedmundson@kde.org>
---
diff --git a/examples/wayland/custom-extension/client-common/customextension.cpp b/examples/wayland/custom-extension/client-common/customextension.cpp
index aa0cb58..8b77c06 100644
--- a/examples/wayland/custom-extension/client-common/customextension.cpp
+++ b/examples/wayland/custom-extension/client-common/customextension.cpp
@@ -81,8 +81,11 @@ QWindow *CustomExtension::windowForSurface(struct ::wl_surface *surface)
bool CustomExtension::eventFilter(QObject *object, QEvent *event)
{
- if (event->type() == QEvent::PlatformSurface
- && static_cast<QPlatformSurfaceEvent*>(event)->surfaceEventType() == QPlatformSurfaceEvent::SurfaceCreated) {
+ if (event->type() == QEvent::Expose) {
+ auto *exposeEvent = static_cast<QExposeEvent *>(event);
+ if (exposeEvent->region().isNull())
+ return false;
+
QWindow *window = qobject_cast<QWindow*>(object);
Q_ASSERT(window);
window->removeEventFilter(this);
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index 9669cbb..d0d834b 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -100,7 +100,7 @@ QWaylandWindow::~QWaylandWindow()
delete mWindowDecoration;
if (mSurface)
- reset(false);
+ reset();
const QWindow *parent = window();
const auto tlw = QGuiApplication::topLevelWindows();
@@ -127,8 +127,6 @@ void QWaylandWindow::initWindow()
if (!mSurface) {
initializeWlSurface();
- QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceCreated);
- QGuiApplication::sendEvent(window(), &e);
}
if (shouldCreateSubSurface()) {
@@ -241,12 +239,8 @@ bool QWaylandWindow::shouldCreateSubSurface() const
return QPlatformWindow::parent() != nullptr;
}
-void QWaylandWindow::reset(bool sendDestroyEvent)
+void QWaylandWindow::reset()
{
- if (mSurface && sendDestroyEvent) {
- QPlatformSurfaceEvent e(QPlatformSurfaceEvent::SurfaceAboutToBeDestroyed);
- QGuiApplication::sendEvent(window(), &e);
- }
delete mShellSurface;
mShellSurface = nullptr;
delete mSubSurfaceWindow;
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index b57f5dd..a65301c 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -261,7 +261,7 @@ private:
void initializeWlSurface();
bool shouldCreateShellSurface() const;
bool shouldCreateSubSurface() const;
- void reset(bool sendDestroyEvent = true);
+ void reset();
void sendExposeEvent(const QRect &rect);
static void closePopups(QWaylandWindow *parent);
QWaylandScreen *calculateScreenFromSurfaceEvents() const;

View File

@ -1,113 +0,0 @@
From 7f065653e2f372ee5b7e2ea4dbed6681ef41be68 Mon Sep 17 00:00:00 2001
From: David Edmundson <davidedmundson@kde.org>
Date: Tue, 07 Apr 2020 17:36:19 +0100
Subject: [PATCH] Client: Fix scroll direction with touchpads
Wayland axis events and QWheelEvents are opposite way rounds. This was
handled for the case of discrete events, but not continuous events.
This leads to touchpads moving the wrong way round compared to other
clients.
Change-Id: Iee4f5c620940a491949d4039cb3ac70649d83a2b
Pick-to: 5.15
---
diff --git a/src/client/qwaylandinputdevice.cpp b/src/client/qwaylandinputdevice.cpp
index e0f0c6c..ed4a0eb 100644
--- a/src/client/qwaylandinputdevice.cpp
+++ b/src/client/qwaylandinputdevice.cpp
@@ -1025,6 +1025,12 @@
*accumulatedError += delta - pixelDelta;
Q_ASSERT(qAbs(accumulatedError->x()) < 1.0);
Q_ASSERT(qAbs(accumulatedError->y()) < 1.0);
+
+ // for continuous scroll events things should be
+ // in the same direction
+ // i.e converted so downwards surface co-ordinates (positive axis_value)
+ // goes to downwards in wheel event (negative value)
+ pixelDelta *= -1;
return pixelDelta;
}
diff --git a/tests/auto/client/seatv5/tst_seatv5.cpp b/tests/auto/client/seatv5/tst_seatv5.cpp
index e333082..9312c2e 100644
--- a/tests/auto/client/seatv5/tst_seatv5.cpp
+++ b/tests/auto/client/seatv5/tst_seatv5.cpp
@@ -63,6 +63,7 @@
void simpleAxis();
void fingerScroll();
void fingerScrollSlow();
+ void continuousScroll();
void wheelDiscreteScroll();
// Touch tests
@@ -252,7 +253,7 @@
QCOMPARE(e.phase, Qt::ScrollUpdate);
QVERIFY(qAbs(e.angleDelta.x()) <= qAbs(e.angleDelta.y())); // Vertical scroll
// QCOMPARE(e.angleDelta, angleDelta); // TODO: what should this be?
- QCOMPARE(e.pixelDelta, QPoint(0, 10));
+ QCOMPARE(e.pixelDelta, QPoint(0, -10));
QCOMPARE(e.source, Qt::MouseEventSynthesizedBySystem); // A finger is not a wheel
}
@@ -269,7 +270,7 @@
auto e = window.m_events.takeFirst();
QCOMPARE(e.phase, Qt::ScrollUpdate);
QVERIFY(qAbs(e.angleDelta.x()) > qAbs(e.angleDelta.y())); // Horizontal scroll
- QCOMPARE(e.pixelDelta, QPoint(10, 0));
+ QCOMPARE(e.pixelDelta, QPoint(-10, 0));
QCOMPARE(e.source, Qt::MouseEventSynthesizedBySystem); // A finger is not a wheel
}
@@ -284,7 +285,7 @@
{
auto e = window.m_events.takeFirst();
QCOMPARE(e.phase, Qt::ScrollUpdate);
- QCOMPARE(e.pixelDelta, QPoint(10, 10));
+ QCOMPARE(e.pixelDelta, QPoint(-10, -10));
QCOMPARE(e.source, Qt::MouseEventSynthesizedBySystem); // A finger is not a wheel
}
@@ -338,7 +339,7 @@
accumulated += e.pixelDelta;
QTRY_VERIFY(!window.m_events.empty());
}
- QCOMPARE(accumulated.y(), 1);
+ QCOMPARE(accumulated.y(), -1);
}
void tst_seatv5::wheelDiscreteScroll()
{
@@ -370,6 +371,32 @@
}
}
+void tst_seatv5::continuousScroll()
+{
+ WheelWindow window;
+ QCOMPOSITOR_TRY_VERIFY(xdgSurface() && xdgSurface()->m_committedConfigureSerial);
+
+ exec([=] {
+ auto *p = pointer();
+ auto *c = client();
+ p->sendEnter(xdgToplevel()->surface(), {32, 32});
+ p->sendFrame(c);
+ p->sendAxisSource(c, Pointer::axis_source_continuous);
+ p->sendAxis(c, Pointer::axis_vertical_scroll, 10);
+ p->sendAxis(c, Pointer::axis_horizontal_scroll, -5);
+ p->sendFrame(c);
+ });
+
+ QTRY_VERIFY(!window.m_events.empty());
+ {
+ auto e = window.m_events.takeFirst();
+ QCOMPARE(e.phase, Qt::NoScrollPhase);
+ QCOMPARE(e.pixelDelta, QPoint(5, -10));
+ QCOMPARE(e.source, Qt::MouseEventSynthesizedBySystem); // touchpads are not wheels
+ }
+ // Sending axis_stop is not mandatory when axis source != finger
+}
+
void tst_seatv5::createsTouch()
{
QCOMPOSITOR_TRY_COMPARE(touch()->resourceMap().size(), 1);

View File

@ -1,46 +0,0 @@
From 760abe1939f6afc146de2c5172b27b347043f327 Mon Sep 17 00:00:00 2001
From: David Edmundson <davidedmundson@kde.org>
Date: Fri, 24 Jul 2020 16:35:09 +0100
Subject: [PATCH] client: Initialize mScale on creation instead of on show
At the time of creating a QPlatformWindow we will have a QScreen
assigned. It may not be the right one until we get a screen_entered
event, pointing instead to the primary screen.
When we get the screen_entered event we get the correct scale and call
handleWindowScreenChanged. However if it's the same screen as before
QWindowPrivate::setTopLevelScreen will no-op because from it's POV the
screen hasn't changed at all.
This leaves the window having the scale change without any notification.
This is notable with QQuickWidget which creates an FBO very early on
before the window is shown. This would then use the devicePixelRatio of
1 as it is currently unset and then not get any change notification.
Change-Id: Ia7e4072e0bd900abc558bf8930fef4e1e7d2c553
Pick-to: 5.15
---
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index cfcc735..f7647a4 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -86,6 +86,8 @@ QWaylandWindow::QWaylandWindow(QWindow *window)
mFrameCallbackTimeout = frameCallbackTimeout;
}
+ mScale = waylandScreen() ? waylandScreen()->scale() : 1; // fallback to 1 if we don't have a real screen
+
static WId id = 1;
mWindowId = id++;
initializeWlSurface();
@@ -184,8 +186,6 @@ void QWaylandWindow::initWindow()
}
}
- mScale = waylandScreen()->scale();
-
// Enable high-dpi rendering. Scale() returns the screen scale factor and will
// typically be integer 1 (normal-dpi) or 2 (high-dpi). Call set_buffer_scale()
// to inform the compositor that high-resolution buffers will be provided.

View File

@ -1,103 +0,0 @@
From efc94a48526baf92b8a78916e03e1fef5993fa95 Mon Sep 17 00:00:00 2001
From: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Date: Mon, 06 Apr 2020 09:52:33 +0200
Subject: [PATCH] Client: Make frame back callback timeout configurable
To avoid rendering when windows are minimized, we try to detect
this case by checking if 100 ms passes after an update before
any frame callback arrives. Wayland expects to drive the rendering
through frame callbacks, while Qt expects to be informed when a
window is no longer visible and will run a tight, vsynced render loop
until it gets the appropriate event. This mismatch causes issues,
and the timeout is an attempt to avoid actively rendering to a hidden
surface by detecting the missing callbacks.
It causes problems on embedded, though, when a device is so
busy that the timeout happens even when the window is visible.
So we introduce a way to configure the timeout. Either increase
its duration if you can guarantee a certain minimum time between
events even with high load, or set it to 0 to disable it completely.
(at the expense of drawing to invisible windows).
Note that this is required for fixing a critical memory leak that
happens when using Wayland on embedded.
This was mistakenly pushed to 5.12 branch, so it will not be
automatically merged upstream. Therefore we have to
cherry-pick it.
[ChangeLog][Client] 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.
Task-number: QTBUG-82914
Reviewed-by: David Edmundson <davidedmundson@kde.org>
(cherry picked from commit 0a0e0eb8dca699858435dec5194b0b8b6ebd3cf8)
Change-Id: I2aeeecb0fab8f7be9b838e477c88eae22b322d75
Reviewed-by: Janne Koskinen <janne.p.koskinen@qt.io>
---
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index 884a979..0545c80 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -79,6 +79,13 @@
, 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++;
initializeWlSurface();
@@ -1096,7 +1103,7 @@
if (event->timerId() != mFrameCallbackCheckIntervalTimerId)
return;
- bool callbackTimerExpired = mFrameCallbackElapsedTimer.hasExpired(100);
+ bool callbackTimerExpired = mFrameCallbackElapsedTimer.hasExpired(mFrameCallbackTimeout);
if (!mFrameCallbackElapsedTimer.isValid() || callbackTimerExpired ) {
killTimer(mFrameCallbackCheckIntervalTimerId);
mFrameCallbackCheckIntervalTimerId = -1;
@@ -1157,13 +1164,15 @@
mWaitingForUpdate = false;
// Start a timer for handling the case when the compositor stops sending frame callbacks.
- QMetaObject::invokeMethod(this, [this] {
- if (mWaitingForFrameCallback) {
- if (mFrameCallbackCheckIntervalTimerId < 0)
- mFrameCallbackCheckIntervalTimerId = startTimer(100);
- mFrameCallbackElapsedTimer.start();
- }
- }, 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 ef03fd1..89d6272 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -240,6 +240,7 @@
bool mCanResize = true;
bool mResizeDirty = false;
bool mResizeAfterSwap;
+ int mFrameCallbackTimeout = 100;
QVariantMap m_properties;
bool mSentInitialResize = false;

View File

@ -1,59 +0,0 @@
From e87bc5eda5191dfec9c8bdfdcd67faf15e79d1d1 Mon Sep 17 00:00:00 2001
From: David Edmundson <davidedmundson@kde.org>
Date: Sun, 26 Jul 2020 17:56:25 +0100
Subject: [PATCH] Client: Send subsurface expose event when toplevel is configured
If a subsurface is set to be visible on the cilent side before the top
level is configured it will do not create an exposeEvent and map a
buffer as we fail the check in isExposed() where we check the parent.
This is correct behavior.
However, when the toplevel receives an applyConfigure from the shell
client we need subsurfaces to update accordingly.
This fixes a race where subsurfaces are not shown with slow compositors.
Change-Id: Icd156e7655d5b25535acc4d2fe77c31e19ebfa32
Pick-to: 5.15
---
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index f7647a4..9669cbb 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -517,10 +517,22 @@ void QWaylandWindow::applyConfigure()
doApplyConfigure();
lock.unlock();
- sendExposeEvent(QRect(QPoint(), geometry().size()));
+ sendRecursiveExposeEvent();
QWindowSystemInterface::flushWindowSystemEvents();
}
+void QWaylandWindow::sendRecursiveExposeEvent()
+{
+ if (!window()->isVisible())
+ return;
+ sendExposeEvent(QRect(QPoint(), geometry().size()));
+
+ for (QWaylandSubSurface *subsurf : qAsConst(mChildren)) {
+ auto subWindow = subsurf->window();
+ subWindow->sendRecursiveExposeEvent();
+ }
+}
+
void QWaylandWindow::attach(QWaylandBuffer *buffer, int x, int y)
{
Q_ASSERT(!buffer->committed());
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index f2055df..b57f5dd 100644
--- a/src/client/qwaylandwindow_p.h
+++ b/src/client/qwaylandwindow_p.h
@@ -268,6 +268,7 @@ private:
void handleMouseEventWithDecoration(QWaylandInputDevice *inputDevice, const QWaylandPointerEvent &e);
void handleScreensChanged();
+ void sendRecursiveExposeEvent();
bool mInResizeFromApplyConfigure = false;
QRect mLastExposeGeometry;

View File

@ -1,32 +0,0 @@
From e72f7db39f58063267036a4e5d066e70a80184b2 Mon Sep 17 00:00:00 2001
From: Allan Sandfeld Jensen <allan.jensen@qt.io>
Date: Tue, 21 Apr 2020 10:11:41 +0200
Subject: [PATCH] Don't force gamma-correction off
The freetype backend can now do selective gamma-correcting, but need
to have a useful gamma-value.
Fixes: QTBUG-83636
Change-Id: I89e99d0a63b75d15d70763ee0c2459caa761beee
Reviewed-by: David Edmundson <davidedmundson@kde.org>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
---
diff --git a/src/client/qwaylandintegration.cpp b/src/client/qwaylandintegration.cpp
index 85c1990..2e0d508 100644
--- a/src/client/qwaylandintegration.cpp
+++ b/src/client/qwaylandintegration.cpp
@@ -233,13 +233,6 @@
if (hint == ShowIsFullScreen && mDisplay->windowManagerIntegration())
return mDisplay->windowManagerIntegration()->showIsFullScreen();
- switch (hint) {
- case QPlatformIntegration::FontSmoothingGamma:
- return qreal(1.0);
- default:
- break;
- }
-
return QPlatformIntegration::styleHint(hint);
}

View File

@ -1,129 +0,0 @@
From fabaaec60a5fe477f7339c0d825d8b236a7e5330 Mon Sep 17 00:00:00 2001
From: Janne Koskinen <janne.p.koskinen@qt.io>
Date: Tue, 24 Mar 2020 14:22:35 +0200
Subject: [PATCH] Fix leaking of callback timers
Use two timers to create timeout trigger for framecallback.
Removes multiple timers approach that is subject to race conditions.
This was mistakenly pushed to 5.12 branch which will not be
automatically merged upstream, so it has to be cherry-picked.
Fixes: QTBUG-82914
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
(cherry picked from commit d18c29931b0bc889fff66bdbde89133544ba0529)
Change-Id: I258c0c08f0ac5803192fc0024e40ba72e72c37a8
Reviewed-by: Janne Koskinen <janne.p.koskinen@qt.io>
---
diff --git a/src/client/qwaylandwindow.cpp b/src/client/qwaylandwindow.cpp
index 9fa2f15..884a979 100644
--- a/src/client/qwaylandwindow.cpp
+++ b/src/client/qwaylandwindow.cpp
@@ -257,10 +257,7 @@
mFrameCallback = nullptr;
}
- int timerId = mFrameCallbackTimerId.fetchAndStoreOrdered(-1);
- if (timerId != -1) {
- killTimer(timerId);
- }
+ mFrameCallbackElapsedTimer.invalidate();
mWaitingForFrameCallback = false;
mFrameCallbackTimedOut = false;
@@ -602,15 +599,11 @@
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?
@@ -645,13 +638,6 @@
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;
}
@@ -1107,8 +1093,16 @@
void QWaylandWindow::timerEvent(QTimerEvent *event)
{
- if (mFrameCallbackTimerId.testAndSetOrdered(event->timerId(), -1)) {
- killTimer(event->timerId());
+ if (event->timerId() != mFrameCallbackCheckIntervalTimerId)
+ return;
+
+ bool callbackTimerExpired = mFrameCallbackElapsedTimer.hasExpired(100);
+ 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;
@@ -1162,15 +1156,13 @@
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);
+ QMetaObject::invokeMethod(this, [this] {
+ if (mWaitingForFrameCallback) {
+ if (mFrameCallbackCheckIntervalTimerId < 0)
+ mFrameCallbackCheckIntervalTimerId = startTimer(100);
+ mFrameCallbackElapsedTimer.start();
+ }
}, Qt::QueuedConnection);
}
diff --git a/src/client/qwaylandwindow_p.h b/src/client/qwaylandwindow_p.h
index 352df89..ef03fd1 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>
@@ -225,7 +226,8 @@
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;

View File

@ -1,64 +0,0 @@
From 80bf946e78b5b5b4276668249eb1fab769259426 Mon Sep 17 00:00:00 2001
From: David Edmundson <davidedmundson@kde.org>
Date: Tue, 23 Jul 2019 08:44:46 +0200
Subject: [PATCH] Client: Remove recursion in data offer retrieval
A loop functions just as well is more readable and uses less stack
memory.
Change-Id: I6f6c6b7b8047c42080fb8b9e0bc3eae96f8872ab
Reviewed-by: David Faure <david.faure@kdab.com>
Reviewed-by: Johan Helsing <johan.helsing@qt.io>
---
src/client/qwaylanddataoffer.cpp | 37 +++++++++++++++++---------------
1 file changed, 20 insertions(+), 17 deletions(-)
diff --git a/src/client/qwaylanddataoffer.cpp b/src/client/qwaylanddataoffer.cpp
index 4c06277f..2297e8a1 100644
--- a/src/client/qwaylanddataoffer.cpp
+++ b/src/client/qwaylanddataoffer.cpp
@@ -170,24 +170,27 @@ int QWaylandMimeData::readData(int fd, QByteArray &data) const
timeout.tv_sec = 1;
timeout.tv_usec = 0;
- int ready = select(FD_SETSIZE, &readset, nullptr, nullptr, &timeout);
- if (ready < 0) {
- qWarning() << "QWaylandDataOffer: select() failed";
- return -1;
- } else if (ready == 0) {
- qWarning("QWaylandDataOffer: timeout reading from pipe");
- return -1;
- } else {
- char buf[4096];
- int n = QT_READ(fd, buf, sizeof buf);
-
- if (n > 0) {
- data.append(buf, n);
- n = readData(fd, data);
- } else if (n < 0) {
- qWarning("QWaylandDataOffer: read() failed");
+ Q_FOREVER {
+ int ready = select(FD_SETSIZE, &readset, nullptr, nullptr, &timeout);
+ if (ready < 0) {
+ qWarning() << "QWaylandDataOffer: select() failed";
+ return -1;
+ } else if (ready == 0) {
+ qWarning("QWaylandDataOffer: timeout reading from pipe");
+ return -1;
+ } else {
+ char buf[4096];
+ int n = QT_READ(fd, buf, sizeof buf);
+
+ if (n < 0) {
+ qWarning("QWaylandDataOffer: read() failed");
+ return -1;
+ } else if (n == 0) {
+ return 0;
+ } else if (n > 0) {
+ data.append(buf, n);
+ }
}
- return n;
}
}

View File

@ -1 +1 @@
SHA512 (qtwayland-everywhere-src-5.14.2.tar.xz) = 0f396cabace17f099c2f2c0be54317006dc00c5f4be08cd79a4fa4fdc94362f63cc6ce9decc7feb63f566dd2ea52d562257e4bb23332557054418fc16dc7e899 SHA512 (qtwayland-everywhere-src-5.15.1.tar.xz) = d6619f35b3ab163372a0d49a2221c487d5936b6d9ebeb92a7fd41521c424d550eea7c5c584e07f15bde1ec5ece1bd5774845eb9956ce793e546197ffdb28d594