Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package libqt5-qtwayland for
openSUSE:Factory checked in at 2022-01-25 17:35:42
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libqt5-qtwayland (Old)
and /work/SRC/openSUSE:Factory/.libqt5-qtwayland.new.1938 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libqt5-qtwayland"
Tue Jan 25 17:35:42 2022 rev:42 rq:948155 version:5.15.2+kde44
Changes:
--------
--- /work/SRC/openSUSE:Factory/libqt5-qtwayland/libqt5-qtwayland.changes
2021-12-21 18:40:21.877859461 +0100
+++
/work/SRC/openSUSE:Factory/.libqt5-qtwayland.new.1938/libqt5-qtwayland.changes
2022-01-25 17:36:26.750179080 +0100
@@ -1,0 +2,14 @@
+Thu Jan 20 16:33:58 UTC 2022 - Fabian Vogt <[email protected]>
+
+- Update to version 5.15.2+kde44:
+ * Move the wayland socket polling to a separate event thread
+ * Connect flushRequest after forceRoundTrip
+ * Handle registry_global out of constructor
+ * Client: Avoid processing of events when showing windows
+ * Client: Delay deletion of QDrag object until after we're done with it
+ * Client: Implement DataDeviceV3
+ * Set preedit cursor when cursor equals to 0
+- Drop patches, now upstream:
+ * 0001-Client-Avoid-processing-of-events-when-showing-windo.patch
+
+-------------------------------------------------------------------
Old:
----
0001-Client-Avoid-processing-of-events-when-showing-windo.patch
qtwayland-everywhere-src-5.15.2+kde37.obscpio
New:
----
qtwayland-everywhere-src-5.15.2+kde44.obscpio
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ libqt5-qtwayland.spec ++++++
--- /var/tmp/diff_new_pack.eFcU65/_old 2022-01-25 17:36:27.566173460 +0100
+++ /var/tmp/diff_new_pack.eFcU65/_new 2022-01-25 17:36:27.570173433 +0100
@@ -26,7 +26,7 @@
%define so_version 5.15.2
%define tar_version qtwayland-everywhere-src-%{version}
Name: libqt5-qtwayland
-Version: 5.15.2+kde37
+Version: 5.15.2+kde44
Release: 0
Summary: Qt 5 Wayland Addon
# The wayland compositor files are GPL-3.0-or-later
@@ -37,8 +37,6 @@
Source1: baselibs.conf
# PATCH-FIX-OPENSUSE
Patch1: 0001-Revert-Bump-version.patch
-# PATCH-FIX-UPSTREAM
-Patch2: 0001-Client-Avoid-processing-of-events-when-showing-windo.patch
BuildRequires: fdupes
BuildRequires: libqt5-qtbase-private-headers-devel >= %{real_version}
BuildRequires: libqt5-qtdeclarative-private-headers-devel >= %{real_version}
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.eFcU65/_old 2022-01-25 17:36:27.622173074 +0100
+++ /var/tmp/diff_new_pack.eFcU65/_new 2022-01-25 17:36:27.626173047 +0100
@@ -1,6 +1,6 @@
<servicedata>
<service name="tar_scm">
<param
name="url">https://invent.kde.org/qt/qt/qtwayland.git</param>
- <param
name="changesrevision">eb422ab5e07498a7a8d086f6a942ee35ab3c9776</param></service></servicedata>
+ <param
name="changesrevision">4644d51f4b52e83fc1b4d02b380d80d9d57e76fa</param></service></servicedata>
(No newline at EOF)
++++++ qtwayland-everywhere-src-5.15.2+kde37.obscpio ->
qtwayland-everywhere-src-5.15.2+kde44.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddatadevice.cpp
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddatadevice.cpp
--- old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddatadevice.cpp
2021-12-09 17:38:43.000000000 +0100
+++ new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddatadevice.cpp
2022-01-19 17:16:28.000000000 +0100
@@ -72,6 +72,8 @@
QWaylandDataDevice::~QWaylandDataDevice()
{
+ if (wl_data_device_get_version(object()) >=
WL_DATA_DEVICE_RELEASE_SINCE_VERSION)
+ release();
}
QWaylandDataOffer *QWaylandDataDevice::selectionOffer() const
@@ -110,7 +112,7 @@
return m_dragOffer.data();
}
-bool QWaylandDataDevice::startDrag(QMimeData *mimeData, QWaylandWindow *icon)
+bool QWaylandDataDevice::startDrag(QMimeData *mimeData, Qt::DropActions
supportedActions, QWaylandWindow *icon)
{
auto *seat = m_display->currentInputDevice();
auto *origin = seat->pointerFocus();
@@ -123,8 +125,28 @@
}
m_dragSource.reset(new
QWaylandDataSource(m_display->dndSelectionHandler(), mimeData));
+
+ if (wl_data_device_get_version(object()) >= 3)
+ m_dragSource->set_actions(dropActionsToWl(supportedActions));
+
connect(m_dragSource.data(), &QWaylandDataSource::cancelled, this,
&QWaylandDataDevice::dragSourceCancelled);
- connect(m_dragSource.data(), &QWaylandDataSource::targetChanged, this,
&QWaylandDataDevice::dragSourceTargetChanged);
+ connect(m_dragSource.data(), &QWaylandDataSource::dndResponseUpdated,
this, [this](bool accepted, Qt::DropAction action) {
+ auto drag = static_cast<QWaylandDrag
*>(QGuiApplicationPrivate::platformIntegration()->drag());
+ // in old versions drop action is not set, so we guess
+ if (wl_data_source_get_version(m_dragSource->object()) < 3) {
+ drag->setResponse(accepted);
+ } else {
+ QPlatformDropQtResponse response(accepted, action);
+ drag->setResponse(response);
+ }
+ });
+ connect(m_dragSource.data(), &QWaylandDataSource::dndDropped, this,
[](bool accepted, Qt::DropAction action) {
+ QPlatformDropQtResponse response(accepted, action);
+ static_cast<QWaylandDrag
*>(QGuiApplicationPrivate::platformIntegration()->drag())->setDropResponse(response);
+ });
+ connect(m_dragSource.data(), &QWaylandDataSource::finished, this, []() {
+ static_cast<QWaylandDrag
*>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag();
+ });
start_drag(m_dragSource->object(), origin->wlSurface(), icon->wlSurface(),
m_display->currentInputDevice()->serial());
return true;
@@ -153,7 +175,7 @@
supportedActions = drag->supportedActions();
} else if (m_dragOffer) {
dragData = m_dragOffer->mimeData();
- supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
+ supportedActions = m_dragOffer->supportedActions();
} else {
return;
}
@@ -163,7 +185,11 @@
QGuiApplication::keyboardModifiers());
if (drag) {
- static_cast<QWaylandDrag
*>(QGuiApplicationPrivate::platformIntegration()->drag())->finishDrag(response);
+ auto drag = static_cast<QWaylandDrag
*>(QGuiApplicationPrivate::platformIntegration()->drag());
+ drag->setDropResponse(response);
+ drag->finishDrag();
+ } else if (m_dragOffer) {
+ m_dragOffer->finish();
}
}
@@ -187,7 +213,7 @@
supportedActions = drag->supportedActions();
} else if (m_dragOffer) {
dragData = m_dragOffer->mimeData();
- supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
+ supportedActions = m_dragOffer->supportedActions();
}
const QPlatformDragQtResponse &response =
QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint,
supportedActions,
@@ -198,11 +224,7 @@
static_cast<QWaylandDrag
*>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response);
}
- if (response.isAccepted()) {
- wl_data_offer_accept(m_dragOffer->object(), m_enterSerial,
m_dragOffer->firstFormat().toUtf8().constData());
- } else {
- wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, nullptr);
- }
+ sendResponse(supportedActions, response);
}
void QWaylandDataDevice::data_device_leave()
@@ -236,10 +258,10 @@
supportedActions = drag->supportedActions();
} else {
dragData = m_dragOffer->mimeData();
- supportedActions = Qt::CopyAction | Qt::MoveAction | Qt::LinkAction;
+ supportedActions = m_dragOffer->supportedActions();
}
- QPlatformDragQtResponse response =
QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint,
supportedActions,
+ const QPlatformDragQtResponse response =
QWindowSystemInterface::handleDrag(m_dragWindow, dragData, m_dragPoint,
supportedActions,
QGuiApplication::mouseButtons(),
QGuiApplication::keyboardModifiers());
@@ -247,11 +269,7 @@
static_cast<QWaylandDrag
*>(QGuiApplicationPrivate::platformIntegration()->drag())->setResponse(response);
}
- if (response.isAccepted()) {
- wl_data_offer_accept(m_dragOffer->object(), m_enterSerial,
m_dragOffer->firstFormat().toUtf8().constData());
- } else {
- wl_data_offer_accept(m_dragOffer->object(), m_enterSerial, nullptr);
- }
+ sendResponse(supportedActions, response);
}
#endif // QT_CONFIG(draganddrop)
@@ -281,11 +299,6 @@
m_dragSource.reset();
}
-void QWaylandDataDevice::dragSourceTargetChanged(const QString &mimeType)
-{
- static_cast<QWaylandDrag
*>(QGuiApplicationPrivate::platformIntegration()->drag())->updateTarget(mimeType);
-}
-
QPoint QWaylandDataDevice::calculateDragPosition(int x, int y, QWindow *wnd)
const
{
QPoint pnt(wl_fixed_to_int(x), wl_fixed_to_int(y));
@@ -298,6 +311,33 @@
}
return pnt;
}
+
+void QWaylandDataDevice::sendResponse(Qt::DropActions supportedActions, const
QPlatformDragQtResponse &response)
+{
+ if (response.isAccepted()) {
+ if (wl_data_device_get_version(object()) >= 3)
+ m_dragOffer->set_actions(dropActionsToWl(supportedActions),
dropActionsToWl(response.acceptedAction()));
+
+ m_dragOffer->accept(m_enterSerial, m_dragOffer->firstFormat());
+ } else {
+ m_dragOffer->accept(m_enterSerial, QString());
+ }
+}
+
+int QWaylandDataDevice::dropActionsToWl(Qt::DropActions actions)
+{
+
+ int wlActions = WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE;
+ if (actions & Qt::CopyAction)
+ wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY;
+ if (actions & (Qt::MoveAction | Qt::TargetMoveAction))
+ wlActions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE;
+
+ // wayland does not support LinkAction at the time of writing
+ return wlActions;
+}
+
+
#endif // QT_CONFIG(draganddrop)
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddatadevice_p.h
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddatadevice_p.h
--- old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddatadevice_p.h
2021-12-09 17:38:43.000000000 +0100
+++ new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddatadevice_p.h
2022-01-19 17:16:28.000000000 +0100
@@ -64,6 +64,7 @@
QT_BEGIN_NAMESPACE
class QMimeData;
+class QPlatformDragQtResponse;
class QWindow;
namespace QtWaylandClient {
@@ -89,7 +90,7 @@
#if QT_CONFIG(draganddrop)
QWaylandDataOffer *dragOffer() const;
- bool startDrag(QMimeData *mimeData, QWaylandWindow *icon);
+ bool startDrag(QMimeData *mimeData, Qt::DropActions supportedActions,
QWaylandWindow *icon);
void cancelDrag();
#endif
@@ -109,13 +110,16 @@
#if QT_CONFIG(draganddrop)
void dragSourceCancelled();
- void dragSourceTargetChanged(const QString &mimeType);
#endif
private:
#if QT_CONFIG(draganddrop)
QPoint calculateDragPosition(int x, int y, QWindow *wnd) const;
#endif
+ void sendResponse(Qt::DropActions supportedActions, const
QPlatformDragQtResponse &response);
+
+ static int dropActionsToWl(Qt::DropActions dropActions);
+
QWaylandDisplay *m_display = nullptr;
QWaylandInputDevice *m_inputDevice = nullptr;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddatadevicemanager.cpp
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddatadevicemanager.cpp
---
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddatadevicemanager.cpp
2021-12-09 17:38:43.000000000 +0100
+++
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddatadevicemanager.cpp
2022-01-19 17:16:28.000000000 +0100
@@ -50,8 +50,8 @@
namespace QtWaylandClient {
-QWaylandDataDeviceManager::QWaylandDataDeviceManager(QWaylandDisplay *display,
uint32_t id)
- : wl_data_device_manager(display->wl_registry(), id, 1)
+QWaylandDataDeviceManager::QWaylandDataDeviceManager(QWaylandDisplay *display,
int version, uint32_t id)
+ : wl_data_device_manager(display->wl_registry(), id, qMin(version, 3))
, m_display(display)
{
// Create transfer devices for all input devices.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddatadevicemanager_p.h
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddatadevicemanager_p.h
---
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddatadevicemanager_p.h
2021-12-09 17:38:43.000000000 +0100
+++
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddatadevicemanager_p.h
2022-01-19 17:16:28.000000000 +0100
@@ -68,7 +68,7 @@
class Q_WAYLAND_CLIENT_EXPORT QWaylandDataDeviceManager : public
QtWayland::wl_data_device_manager
{
public:
- QWaylandDataDeviceManager(QWaylandDisplay *display, uint32_t id);
+ QWaylandDataDeviceManager(QWaylandDisplay *display, int version, uint32_t
id);
~QWaylandDataDeviceManager() override;
QWaylandDataDevice *getDataDevice(QWaylandInputDevice *inputDevice);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddataoffer.cpp
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddataoffer.cpp
--- old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddataoffer.cpp
2021-12-09 17:38:43.000000000 +0100
+++ new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddataoffer.cpp
2022-01-19 17:16:28.000000000 +0100
@@ -82,6 +82,15 @@
return m_mimeData.data();
}
+Qt::DropActions QWaylandDataOffer::supportedActions() const
+{
+ if (wl_data_offer_get_version(const_cast<::wl_data_offer*>(object())) < 3)
{
+ return Qt::MoveAction | Qt::CopyAction;
+ }
+
+ return m_supportedActions;
+}
+
void QWaylandDataOffer::startReceiving(const QString &mimeType, int fd)
{
receive(mimeType, fd);
@@ -93,6 +102,22 @@
m_mimeData->appendFormat(mime_type);
}
+void QWaylandDataOffer::data_offer_action(uint32_t dnd_action)
+{
+ Q_UNUSED(dnd_action);
+ // This is the compositor telling the drag target what action it should
perform
+ // It does not map nicely into Qt final drop semantics, other than
pretending there is only one supported action?
+}
+
+void QWaylandDataOffer::data_offer_source_actions(uint32_t source_actions)
+{
+ m_supportedActions = Qt::DropActions();
+ if (source_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
+ m_supportedActions |= Qt::MoveAction;
+ if (source_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
+ m_supportedActions |= Qt::CopyAction;
+}
+
QWaylandMimeData::QWaylandMimeData(QWaylandAbstractDataOffer *dataOffer)
: m_dataOffer(dataOffer)
{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddataoffer_p.h
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddataoffer_p.h
--- old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddataoffer_p.h
2021-12-09 17:38:43.000000000 +0100
+++ new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddataoffer_p.h
2022-01-19 17:16:28.000000000 +0100
@@ -82,6 +82,7 @@
explicit QWaylandDataOffer(QWaylandDisplay *display, struct
::wl_data_offer *offer);
~QWaylandDataOffer() override;
QMimeData *mimeData() override;
+ Qt::DropActions supportedActions() const;
QString firstFormat() const;
@@ -89,10 +90,13 @@
protected:
void data_offer_offer(const QString &mime_type) override;
+ void data_offer_source_actions(uint32_t source_actions) override;
+ void data_offer_action(uint32_t dnd_action) override;
private:
QWaylandDisplay *m_display = nullptr;
QScopedPointer<QWaylandMimeData> m_mimeData;
+ Qt::DropActions m_supportedActions;
};
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddatasource.cpp
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddatasource.cpp
--- old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddatasource.cpp
2021-12-09 17:38:43.000000000 +0100
+++ new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddatasource.cpp
2022-01-19 17:16:28.000000000 +0100
@@ -101,7 +101,32 @@
void QWaylandDataSource::data_source_target(const QString &mime_type)
{
- Q_EMIT targetChanged(mime_type);
+ m_accepted = !mime_type.isEmpty();
+ Q_EMIT dndResponseUpdated(m_accepted, m_dropAction);
+}
+
+void QWaylandDataSource::data_source_action(uint32_t action)
+{
+ Qt::DropAction qtAction = Qt::IgnoreAction;
+
+ if (action == WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE)
+ qtAction = Qt::MoveAction;
+ else if (action == WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY)
+ qtAction = Qt::CopyAction;
+
+ m_dropAction = qtAction;
+ Q_EMIT dndResponseUpdated(m_accepted, m_dropAction);
+}
+
+void QWaylandDataSource::data_source_dnd_finished()
+{
+ Q_EMIT finished();
+}
+
+void QWaylandDataSource::data_source_dnd_drop_performed()
+{
+
+ Q_EMIT dndDropped(m_accepted, m_dropAction);
}
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddatasource_p.h
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddatasource_p.h
--- old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddatasource_p.h
2021-12-09 17:38:43.000000000 +0100
+++ new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddatasource_p.h
2022-01-19 17:16:28.000000000 +0100
@@ -77,17 +77,25 @@
QMimeData *mimeData() const;
Q_SIGNALS:
- void targetChanged(const QString &mime_type);
void cancelled();
+ void finished();
+
+ void dndResponseUpdated(bool accepted, Qt::DropAction action);
+ void dndDropped(bool accepted, Qt::DropAction action);
protected:
void data_source_cancelled() override;
void data_source_send(const QString &mime_type, int32_t fd) override;
void data_source_target(const QString &mime_type) override;
+ void data_source_dnd_drop_performed() override;
+ void data_source_dnd_finished() override;
+ void data_source_action(uint32_t action) override;
private:
QWaylandDisplay *m_display = nullptr;
QMimeData *m_mime_data = nullptr;
+ bool m_accepted = false;
+ Qt::DropAction m_dropAction = Qt::IgnoreAction;
};
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddisplay.cpp
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddisplay.cpp
--- old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddisplay.cpp
2021-12-09 17:38:43.000000000 +0100
+++ new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddisplay.cpp
2022-01-19 17:16:28.000000000 +0100
@@ -85,10 +85,203 @@
#include <errno.h>
+#include <tuple> // for std::tie
+
+static void checkWaylandError(struct wl_display *display)
+{
+ int ecode = wl_display_get_error(display);
+ if ((ecode == EPIPE || ecode == ECONNRESET)) {
+ // special case this to provide a nicer error
+ qWarning("The Wayland connection broke. Did the Wayland compositor
die?");
+ } else {
+ qWarning("The Wayland connection experienced a fatal error: %s",
strerror(ecode));
+ }
+ _exit(1);
+}
+
QT_BEGIN_NAMESPACE
namespace QtWaylandClient {
+class EventThread : public QThread
+{
+ Q_OBJECT
+public:
+ enum OperatingMode {
+ EmitToDispatch, // Emit the signal, allow dispatching in a differnt
thread.
+ SelfDispatch, // Dispatch the events inside this thread.
+ };
+
+ EventThread(struct wl_display * wl, struct wl_event_queue * ev_queue,
+ OperatingMode mode)
+ : m_fd(wl_display_get_fd(wl))
+ , m_pipefd{ -1, -1 }
+ , m_wldisplay(wl)
+ , m_wlevqueue(ev_queue)
+ , m_mode(mode)
+ , m_reading(true)
+ , m_quitting(false)
+ {
+ setObjectName(QStringLiteral("WaylandEventThread"));
+ }
+
+ void readAndDispatchEvents()
+ {
+ /*
+ * Dispatch pending events and flush the requests at least once. If
the event thread
+ * is not reading, try to call _prepare_read() to allow the event
thread to poll().
+ * If that fails, re-try dispatch & flush again until _prepare_read()
is successful.
+ *
+ * This allow any call to readAndDispatchEvents() to start event
thread's polling,
+ * not only the one issued from event thread's waitForReading(), which
means functions
+ * called from dispatch_pending() can safely spin an event loop.
+ */
+ for (;;) {
+ if (dispatchQueuePending() < 0) {
+ checkWaylandError(m_wldisplay);
+ return;
+ }
+
+ wl_display_flush(m_wldisplay);
+
+ // We have to check if event thread is reading every time we
dispatch
+ // something, as that may recursively call this function.
+ if (m_reading.loadAcquire())
+ break;
+
+ if (prepareReadQueue() == 0) {
+ QMutexLocker l(&m_mutex);
+ m_reading.storeRelease(true);
+ m_cond.wakeOne();
+ break;
+ }
+ }
+ }
+
+ void stop()
+ {
+ // We have to both write to the pipe and set the flag, as the thread
may be
+ // either in the poll() or waiting for _prepare_read().
+ if (m_pipefd[1] != -1 && write(m_pipefd[1], "\0", 1) == -1)
+ qWarning("Failed to write to the pipe: %s.", strerror(errno));
+
+ {
+ QMutexLocker l(&m_mutex);
+ m_quitting = true;
+ m_cond.wakeOne();
+ }
+
+ wait();
+ }
+
+Q_SIGNALS:
+ void needReadAndDispatch();
+
+protected:
+ void run() override
+ {
+ // we use this pipe to make the loop exit otherwise if we simply used
a flag on the loop condition, if stop() gets
+ // called while poll() is blocking the thread will never quit since
there are no wayland messages coming anymore.
+ struct Pipe
+ {
+ Pipe(int *fds)
+ : fds(fds)
+ {
+ if (qt_safe_pipe(fds) != 0)
+ qWarning("Pipe creation failed. Quitting may hang.");
+ }
+ ~Pipe()
+ {
+ if (fds[0] != -1) {
+ close(fds[0]);
+ close(fds[1]);
+ }
+ }
+
+ int *fds;
+ } pipe(m_pipefd);
+
+ // Make the main thread call wl_prepare_read(), dispatch the pending
messages and flush the
+ // outbound ones. Wait until it's done before proceeding, unless we're
told to quit.
+ while (waitForReading()) {
+ pollfd fds[2] = { { m_fd, POLLIN, 0 }, { m_pipefd[0], POLLIN, 0 }
};
+ poll(fds, 2, -1);
+
+ if (fds[1].revents & POLLIN) {
+ // we don't really care to read the byte that was written here
since we're closing down
+ wl_display_cancel_read(m_wldisplay);
+ break;
+ }
+
+ if (fds[0].revents & POLLIN)
+ wl_display_read_events(m_wldisplay);
+ // The polll was succesfull and the event thread did the
wl_display_read_events(). On the next iteration of the loop
+ // the event sent to the main thread will cause it to dispatch
the messages just read, unless the loop exits in which
+ // case we don't care anymore about them.
+ else
+ wl_display_cancel_read(m_wldisplay);
+ }
+ }
+
+private:
+ bool waitForReading()
+ {
+ Q_ASSERT(QThread::currentThread() == this);
+
+ m_reading.storeRelease(false);
+
+ if (m_mode == SelfDispatch) {
+ readAndDispatchEvents();
+ } else {
+ Q_EMIT needReadAndDispatch();
+
+ QMutexLocker lock(&m_mutex);
+ // m_reading might be set from our emit or some other invocation of
+ // readAndDispatchEvents().
+ while (!m_reading.loadRelaxed() && !m_quitting)
+ m_cond.wait(&m_mutex);
+ }
+
+ return !m_quitting;
+ }
+
+ int dispatchQueuePending()
+ {
+ if (m_wlevqueue)
+ return wl_display_dispatch_queue_pending(m_wldisplay, m_wlevqueue);
+ else
+ return wl_display_dispatch_pending(m_wldisplay);
+ }
+
+ int prepareReadQueue()
+ {
+ if (m_wlevqueue)
+ return wl_display_prepare_read_queue(m_wldisplay, m_wlevqueue);
+ else
+ return wl_display_prepare_read(m_wldisplay);
+ }
+
+ int m_fd;
+ int m_pipefd[2];
+ wl_display *m_wldisplay;
+ wl_event_queue *m_wlevqueue;
+ OperatingMode m_mode;
+
+ /* Concurrency note when operating in EmitToDispatch mode:
+ * m_reading is set to false inside event thread's waitForReading(), and is
+ * set to true inside main thread's readAndDispatchEvents().
+ * The lock is not taken when setting m_reading to false, as the main
thread
+ * is not actively waiting for it to turn false. However, the lock is taken
+ * inside readAndDispatchEvents() before setting m_reading to true,
+ * as the event thread is actively waiting for it under the wait condition.
+ */
+
+ QAtomicInteger<bool> m_reading;
+ bool m_quitting;
+ QMutex m_mutex;
+ QWaitCondition m_cond;
+};
+
Q_LOGGING_CATEGORY(lcQpaWayland, "qt.qpa.wayland"); // for general
(uncategorized) Wayland platform logging
struct wl_surface *QWaylandDisplay::createSurface(void *handle)
@@ -158,17 +351,16 @@
if (!mXkbContext)
qCWarning(lcQpaWayland, "failed to create xkb context");
#endif
-
- forceRoundTrip();
-
- if (!mWaitingScreens.isEmpty()) {
- // Give wl_output.done and zxdg_output_v1.done events a chance to
arrive
- forceRoundTrip();
- }
}
QWaylandDisplay::~QWaylandDisplay(void)
{
+ if (m_eventThread)
+ m_eventThread->stop();
+
+ if (m_frameEventQueueThread)
+ m_frameEventQueueThread->stop();
+
if (mSyncCallback)
wl_callback_destroy(mSyncCallback);
@@ -189,6 +381,18 @@
wl_display_disconnect(mDisplay);
}
+// Steps which is called just after constructor. This separates
registry_global() out of the constructor
+// so that factory functions in integration can be overridden.
+void QWaylandDisplay::initialize()
+{
+ forceRoundTrip();
+
+ if (!mWaitingScreens.isEmpty()) {
+ // Give wl_output.done and zxdg_output_v1.done events a chance to
arrive
+ forceRoundTrip();
+ }
+}
+
void QWaylandDisplay::ensureScreen()
{
if (!mScreens.empty() || mPlaceholderScreen)
@@ -203,98 +407,37 @@
void QWaylandDisplay::checkError() const
{
- int ecode = wl_display_get_error(mDisplay);
- if ((ecode == EPIPE || ecode == ECONNRESET)) {
- // special case this to provide a nicer error
- qWarning("The Wayland connection broke. Did the Wayland compositor
die?");
- } else {
- qWarning("The Wayland connection experienced a fatal error: %s",
strerror(ecode));
- }
- _exit(1);
+ checkWaylandError(mDisplay);
}
+// Called in main thread, either from queued signal or directly.
void QWaylandDisplay::flushRequests()
{
- if (wl_display_prepare_read(mDisplay) == 0) {
- wl_display_read_events(mDisplay);
- }
-
- if (wl_display_dispatch_pending(mDisplay) < 0)
- checkError();
-
- {
- QReadLocker locker(&m_frameQueueLock);
- for (const FrameQueue &q : mExternalQueues) {
- QMutexLocker locker(q.mutex);
- while (wl_display_prepare_read_queue(mDisplay, q.queue) != 0)
- wl_display_dispatch_queue_pending(mDisplay, q.queue);
- wl_display_read_events(mDisplay);
- wl_display_dispatch_queue_pending(mDisplay, q.queue);
- }
- }
+ m_eventThread->readAndDispatchEvents();
+}
- wl_display_flush(mDisplay);
+// We have to wait until we have an eventDispatcher before creating the
eventThread,
+// otherwise forceRoundTrip() may block inside _events_read() because
eventThread is
+// polling.
+void QWaylandDisplay::initEventThread()
+{
+ m_eventThread.reset(
+ new EventThread(mDisplay, /* default queue */ nullptr,
EventThread::EmitToDispatch));
+ connect(m_eventThread.get(), &EventThread::needReadAndDispatch, this,
+ &QWaylandDisplay::flushRequests, Qt::QueuedConnection);
+ m_eventThread->start();
+
+ // wl_display_disconnect() free this.
+ m_frameEventQueue = wl_display_create_queue(mDisplay);
+ m_frameEventQueueThread.reset(
+ new EventThread(mDisplay, m_frameEventQueue,
EventThread::SelfDispatch));
+ m_frameEventQueueThread->start();
}
void QWaylandDisplay::blockingReadEvents()
{
if (wl_display_dispatch(mDisplay) < 0)
- checkError();
-}
-
-void QWaylandDisplay::destroyFrameQueue(const QWaylandDisplay::FrameQueue &q)
-{
- QWriteLocker locker(&m_frameQueueLock);
- auto it = std::find_if(mExternalQueues.begin(),
- mExternalQueues.end(),
- [&q] (const QWaylandDisplay::FrameQueue &other){
return other.queue == q.queue; });
- Q_ASSERT(it != mExternalQueues.end());
- mExternalQueues.erase(it);
- if (q.queue != nullptr)
- wl_event_queue_destroy(q.queue);
- delete q.mutex;
-}
-
-QWaylandDisplay::FrameQueue QWaylandDisplay::createFrameQueue()
-{
- QWriteLocker locker(&m_frameQueueLock);
- FrameQueue q{createEventQueue()};
- mExternalQueues.append(q);
- return q;
-}
-
-wl_event_queue *QWaylandDisplay::createEventQueue()
-{
- return wl_display_create_queue(mDisplay);
-}
-
-void QWaylandDisplay::dispatchQueueWhile(wl_event_queue *queue,
std::function<bool ()> condition, int timeout)
-{
- if (!condition())
- return;
-
- QElapsedTimer timer;
- timer.start();
- struct pollfd pFd = qt_make_pollfd(wl_display_get_fd(mDisplay), POLLIN);
- while (timeout == -1 || timer.elapsed() < timeout) {
- while (wl_display_prepare_read_queue(mDisplay, queue) != 0)
- wl_display_dispatch_queue_pending(mDisplay, queue);
-
- wl_display_flush(mDisplay);
-
- const int remaining = qMax(timeout - timer.elapsed(), 0ll);
- const int pollTimeout = timeout == -1 ? -1 : remaining;
- if (qt_poll_msecs(&pFd, 1, pollTimeout) > 0)
- wl_display_read_events(mDisplay);
- else
- wl_display_cancel_read(mDisplay);
-
- if (wl_display_dispatch_queue_pending(mDisplay, queue) < 0)
- checkError();
-
- if (!condition())
- break;
- }
+ checkWaylandError(mDisplay);
}
QWaylandScreen *QWaylandDisplay::screenForOutput(struct wl_output *output)
const
@@ -354,7 +497,7 @@
mInputDevices.append(inputDevice);
#if QT_CONFIG(wayland_datadevice)
} else if (interface == QStringLiteral("wl_data_device_manager")) {
- mDndSelectionHandler.reset(new QWaylandDataDeviceManager(this, id));
+ mDndSelectionHandler.reset(new QWaylandDataDeviceManager(this,
version, id));
#endif
} else if (interface == QStringLiteral("qt_surface_extension")) {
mWindowExtension.reset(new QtWayland::qt_surface_extension(registry,
id, 1));
@@ -669,4 +812,6 @@
} // namespace QtWaylandClient
+#include "qwaylanddisplay.moc"
+
QT_END_NAMESPACE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddisplay_p.h
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddisplay_p.h
--- old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddisplay_p.h
2021-12-09 17:38:43.000000000 +0100
+++ new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddisplay_p.h
2022-01-19 17:16:28.000000000 +0100
@@ -109,6 +109,7 @@
class QWaylandShellIntegration;
class QWaylandCursor;
class QWaylandCursorTheme;
+class EventThread;
typedef void (*RegistryListener)(void *data,
struct wl_registry *registry,
@@ -120,15 +121,11 @@
Q_OBJECT
public:
- struct FrameQueue {
- FrameQueue(wl_event_queue *q = nullptr) : queue(q), mutex(new QMutex)
{}
- wl_event_queue *queue;
- QMutex *mutex;
- };
-
QWaylandDisplay(QWaylandIntegration *waylandIntegration);
~QWaylandDisplay(void) override;
+ void initialize();
+
#if QT_CONFIG(xkbcommon)
struct xkb_context *xkbContext() const { return mXkbContext.get(); }
#endif
@@ -210,12 +207,11 @@
void handleKeyboardFocusChanged(QWaylandInputDevice *inputDevice);
void handleWindowDestroyed(QWaylandWindow *window);
- wl_event_queue *createEventQueue();
- FrameQueue createFrameQueue();
- void destroyFrameQueue(const FrameQueue &q);
- void dispatchQueueWhile(wl_event_queue *queue, std::function<bool()>
condition, int timeout = -1);
+ wl_event_queue *frameEventQueue() { return m_frameEventQueue; };
bool isKeyboardAvailable() const;
+
+ void initEventThread();
public slots:
void blockingReadEvents();
void flushRequests();
@@ -238,6 +234,9 @@
};
struct wl_display *mDisplay = nullptr;
+ QScopedPointer<EventThread> m_eventThread;
+ wl_event_queue *m_frameEventQueue = nullptr;
+ QScopedPointer<EventThread> m_frameEventQueueThread;
QtWayland::wl_compositor mCompositor;
QScopedPointer<QWaylandShm> mShm;
QList<QWaylandScreen *> mWaitingScreens;
@@ -274,11 +273,9 @@
QWaylandInputDevice *mLastInputDevice = nullptr;
QPointer<QWaylandWindow> mLastInputWindow;
QPointer<QWaylandWindow> mLastKeyboardFocus;
- QVector<QWaylandWindow *> mActiveWindows;
- QVector<FrameQueue> mExternalQueues;
+ QList<QWaylandWindow *> mActiveWindows;
struct wl_callback *mSyncCallback = nullptr;
static const wl_callback_listener syncCallbackListener;
- QReadWriteLock m_frameQueueLock;
bool mClientSideInputContextRequested =
!QPlatformInputContextFactory::requested().isNull();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddnd.cpp
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddnd.cpp
--- old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddnd.cpp
2021-12-09 17:38:43.000000000 +0100
+++ new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddnd.cpp
2022-01-19 17:16:28.000000000 +0100
@@ -66,7 +66,7 @@
{
QBasicDrag::startDrag();
QWaylandWindow *icon = static_cast<QWaylandWindow
*>(shapedPixmapWindow()->handle());
- if
(m_display->currentInputDevice()->dataDevice()->startDrag(drag()->mimeData(),
icon)) {
+ if
(m_display->currentInputDevice()->dataDevice()->startDrag(drag()->mimeData(),
drag()->supportedActions(), icon)) {
icon->addAttachOffset(-drag()->hotSpot());
} else {
// Cancelling immediately does not work, since the event loop for
QDrag::exec is started
@@ -80,6 +80,9 @@
QBasicDrag::cancel();
m_display->currentInputDevice()->dataDevice()->cancelDrag();
+
+ if (drag())
+ drag()->deleteLater();
}
void QWaylandDrag::move(const QPoint &globalPos, Qt::MouseButtons b,
Qt::KeyboardModifiers mods)
@@ -103,33 +106,41 @@
m_display->currentInputDevice()->handleEndDrag();
}
-void QWaylandDrag::updateTarget(const QString &mimeType)
+void QWaylandDrag::setResponse(bool accepted)
{
- setCanDrop(!mimeType.isEmpty());
-
- if (canDrop()) {
- updateCursor(defaultAction(drag()->supportedActions(),
m_display->currentInputDevice()->modifiers()));
- } else {
- updateCursor(Qt::IgnoreAction);
- }
+ // This method is used for old DataDevices where the drag action is not
communicated
+ Qt::DropAction action = defaultAction(drag()->supportedActions(),
m_display->currentInputDevice()->modifiers());
+ setResponse(QPlatformDropQtResponse(accepted, action));
}
-void QWaylandDrag::setResponse(const QPlatformDragQtResponse &response)
+void QWaylandDrag::setResponse(const QPlatformDropQtResponse &response)
{
setCanDrop(response.isAccepted());
if (canDrop()) {
- updateCursor(defaultAction(drag()->supportedActions(),
m_display->currentInputDevice()->modifiers()));
+ updateCursor(response.acceptedAction());
} else {
updateCursor(Qt::IgnoreAction);
}
}
-void QWaylandDrag::finishDrag(const QPlatformDropQtResponse &response)
+void QWaylandDrag::setDropResponse(const QPlatformDropQtResponse &response)
{
setExecutedDropAction(response.acceptedAction());
+}
+
+void QWaylandDrag::finishDrag()
+{
QKeyEvent event(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier);
eventFilter(shapedPixmapWindow(), &event);
+
+ if (drag())
+ drag()->deleteLater();
+}
+
+bool QWaylandDrag::ownsDragObject() const
+{
+ return true;
}
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddnd_p.h
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddnd_p.h
--- old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylanddnd_p.h
2021-12-09 17:38:43.000000000 +0100
+++ new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylanddnd_p.h
2022-01-19 17:16:28.000000000 +0100
@@ -71,9 +71,10 @@
QWaylandDrag(QWaylandDisplay *display);
~QWaylandDrag() override;
- void updateTarget(const QString &mimeType);
- void setResponse(const QPlatformDragQtResponse &response);
- void finishDrag(const QPlatformDropQtResponse &response);
+ void setResponse(bool accepted);
+ void setResponse(const QPlatformDropQtResponse &response);
+ void setDropResponse(const QPlatformDropQtResponse &response);
+ void finishDrag();
protected:
void startDrag() override;
@@ -82,6 +83,7 @@
void drop(const QPoint &globalPos, Qt::MouseButtons b,
Qt::KeyboardModifiers mods) override;
void endDrag() override;
+ bool ownsDragObject() const override;
private:
QWaylandDisplay *m_display = nullptr;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylandintegration.cpp
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylandintegration.cpp
---
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylandintegration.cpp
2021-12-09 17:38:43.000000000 +0100
+++
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylandintegration.cpp
2022-01-19 17:16:28.000000000 +0100
@@ -192,14 +192,18 @@
void QWaylandIntegration::initialize()
{
+ mDisplay->initEventThread();
+
+ // Call after eventDispatcher is fully connected, for
QWaylandDisplay::forceRoundTrip()
+ mDisplay->initialize();
+
+ // But the aboutToBlock() and awake() should be connected after
initializePlatform().
+ // Otherwise the connected flushRequests() may consumes up all events
before processEvents starts to wait,
+ // so that processEvents(QEventLoop::WaitForMoreEvents) may be blocked in
the forceRoundTrip().
QAbstractEventDispatcher *dispatcher =
QGuiApplicationPrivate::eventDispatcher;
QObject::connect(dispatcher, SIGNAL(aboutToBlock()), mDisplay.data(),
SLOT(flushRequests()));
QObject::connect(dispatcher, SIGNAL(awake()), mDisplay.data(),
SLOT(flushRequests()));
- int fd = wl_display_get_fd(mDisplay->wl_display());
- QSocketNotifier *sn = new QSocketNotifier(fd, QSocketNotifier::Read,
mDisplay.data());
- QObject::connect(sn, SIGNAL(activated(QSocketDescriptor)),
mDisplay.data(), SLOT(flushRequests()));
-
// Qt does not support running with no screens
mDisplay->ensureScreen();
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylandwindow.cpp
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylandwindow.cpp
--- old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylandwindow.cpp
2021-12-09 17:38:43.000000000 +0100
+++ new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylandwindow.cpp
2022-01-19 17:16:28.000000000 +0100
@@ -76,7 +76,6 @@
QWaylandWindow::QWaylandWindow(QWindow *window, QWaylandDisplay *display)
: QPlatformWindow(window)
, mDisplay(display)
- , mFrameQueue(mDisplay->createFrameQueue())
,
mResizeAfterSwap(qEnvironmentVariableIsSet("QT_WAYLAND_RESIZE_AFTER_SWAP"))
{
{
@@ -95,8 +94,6 @@
QWaylandWindow::~QWaylandWindow()
{
- mDisplay->destroyFrameQueue(mFrameQueue);
-
delete mWindowDecoration;
if (mSurface)
@@ -436,7 +433,6 @@
if (window()->type() == Qt::Popup || window()->type() == Qt::ToolTip)
activePopups << this;
initWindow();
- mDisplay->flushRequests();
setGeometry(windowGeometry());
// Don't flush the events here, or else the newly visible window may
start drawing, but since
@@ -636,6 +632,8 @@
void QWaylandWindow::handleFrameCallback()
{
+ QMutexLocker locker(&mFrameSyncMutex);
+
mWaitingForFrameCallback = false;
mFrameCallbackElapsedTimer.invalidate();
@@ -657,12 +655,16 @@
mWaitingForUpdateDelivery = true;
QMetaObject::invokeMethod(this, doHandleExpose, Qt::QueuedConnection);
}
+
+ mFrameSyncWait.notify_all();
}
bool QWaylandWindow::waitForFrameSync(int timeout)
{
- QMutexLocker locker(mFrameQueue.mutex);
- mDisplay->dispatchQueueWhile(mFrameQueue.queue, [&]() { return
mWaitingForFrameCallback; }, timeout);
+ QMutexLocker locker(&mFrameSyncMutex);
+
+ QDeadlineTimer deadline(timeout);
+ while (mWaitingForFrameCallback && mFrameSyncWait.wait(&mFrameSyncMutex,
deadline)) { }
if (mWaitingForFrameCallback) {
qCDebug(lcWaylandBackingstore) << "Didn't receive frame callback in
time, window should now be inexposed";
@@ -1158,8 +1160,11 @@
Q_ASSERT(hasPendingUpdateRequest()); // should be set by QPA
// If we have a frame callback all is good and will be taken care of there
- if (mWaitingForFrameCallback)
- return;
+ {
+ QMutexLocker locker(&mFrameSyncMutex);
+ if (mWaitingForFrameCallback)
+ return;
+ }
// If we've already called deliverUpdateRequest(), but haven't seen any
attach+commit/swap yet
// This is a somewhat redundant behavior and might indicate a bug in the
calling code, so log
@@ -1172,7 +1177,12 @@
// so use invokeMethod to delay the delivery a bit.
QMetaObject::invokeMethod(this, [this] {
// Things might have changed in the meantime
- if (hasPendingUpdateRequest() && !mWaitingForFrameCallback)
+ {
+ QMutexLocker locker(&mFrameSyncMutex);
+ if (mWaitingForFrameCallback)
+ return;
+ }
+ if (hasPendingUpdateRequest())
deliverUpdateRequest();
}, Qt::QueuedConnection);
}
@@ -1192,9 +1202,10 @@
if (!mSurface)
return;
- QMutexLocker locker(mFrameQueue.mutex);
+ QMutexLocker locker(&mFrameSyncMutex);
+
struct ::wl_surface *wrappedSurface = reinterpret_cast<struct ::wl_surface
*>(wl_proxy_create_wrapper(mSurface->object()));
- wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(wrappedSurface),
mFrameQueue.queue);
+ wl_proxy_set_queue(reinterpret_cast<wl_proxy *>(wrappedSurface),
mDisplay->frameEventQueue());
mFrameCallback = wl_surface_frame(wrappedSurface);
wl_proxy_wrapper_destroy(wrappedSurface);
wl_callback_add_listener(mFrameCallback,
&QWaylandWindow::callbackListener, this);
@@ -1204,6 +1215,8 @@
// Start a timer for handling the case when the compositor stops sending
frame callbacks.
if (mFrameCallbackTimeout > 0) {
QMetaObject::invokeMethod(this, [this] {
+ QMutexLocker locker(&mFrameSyncMutex);
+
if (mWaitingForFrameCallback) {
if (mFrameCallbackCheckIntervalTimerId < 0)
mFrameCallbackCheckIntervalTimerId =
startTimer(mFrameCallbackTimeout);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylandwindow_p.h
new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylandwindow_p.h
--- old/qtwayland-everywhere-src-5.15.2+kde37/src/client/qwaylandwindow_p.h
2021-12-09 17:38:43.000000000 +0100
+++ new/qtwayland-everywhere-src-5.15.2+kde44/src/client/qwaylandwindow_p.h
2022-01-19 17:16:28.000000000 +0100
@@ -232,7 +232,7 @@
int mFrameCallbackCheckIntervalTimerId = -1;
QElapsedTimer mFrameCallbackElapsedTimer;
struct ::wl_callback *mFrameCallback = nullptr;
- QWaylandDisplay::FrameQueue mFrameQueue;
+ QMutex mFrameSyncMutex;
QWaitCondition mFrameSyncWait;
// True when we have called deliverRequestUpdate, but the client has not
yet attached a new buffer
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/src/shared/qwaylandinputmethodeventbuilder.cpp
new/qtwayland-everywhere-src-5.15.2+kde44/src/shared/qwaylandinputmethodeventbuilder.cpp
---
old/qtwayland-everywhere-src-5.15.2+kde37/src/shared/qwaylandinputmethodeventbuilder.cpp
2021-12-09 17:38:43.000000000 +0100
+++
new/qtwayland-everywhere-src-5.15.2+kde44/src/shared/qwaylandinputmethodeventbuilder.cpp
2022-01-19 17:16:28.000000000 +0100
@@ -151,7 +151,7 @@
{
QList<QInputMethodEvent::Attribute> attributes;
- if (m_preeditCursor < 0) {
+ if (m_preeditCursor <= 0) {
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, 0, 0,
QVariant()));
} else if (m_preeditCursor > 0) {
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Cursor,
indexFromWayland(text, m_preeditCursor), 1, QVariant()));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/qtwayland-everywhere-src-5.15.2+kde37/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
new/qtwayland-everywhere-src-5.15.2+kde44/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
---
old/qtwayland-everywhere-src-5.15.2+kde37/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
2021-12-09 17:38:43.000000000 +0100
+++
new/qtwayland-everywhere-src-5.15.2+kde44/tests/auto/client/datadevicev1/tst_datadevicev1.cpp
2022-01-19 17:16:28.000000000 +0100
@@ -35,7 +35,7 @@
using namespace MockCompositor;
-constexpr int dataDeviceVersion = 1;
+constexpr int dataDeviceVersion = 3;
class DataDeviceCompositor : public DefaultCompositor {
public:
++++++ qtwayland-everywhere-src.obsinfo ++++++
--- /var/tmp/diff_new_pack.eFcU65/_old 2022-01-25 17:36:27.950170815 +0100
+++ /var/tmp/diff_new_pack.eFcU65/_new 2022-01-25 17:36:27.954170788 +0100
@@ -1,6 +1,6 @@
name: qtwayland-everywhere-src
-version: 5.15.2+kde37
-mtime: 1639067923
-commit: eb422ab5e07498a7a8d086f6a942ee35ab3c9776
+version: 5.15.2+kde44
+mtime: 1642608988
+commit: 4644d51f4b52e83fc1b4d02b380d80d9d57e76fa