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 <fab...@ritter-vogt.de>
+
+- 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
 
 

Reply via email to