diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index 529f91e1ec05f6bad374da45b09975719cee2264..6fa5dfa48316bfaa05b7e2682122323ce2d9a0a3 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -50,6 +50,7 @@
 
 #include <qpa/qwindowsysteminterface.h>
 
+#include <private/qguiapplication_p.h>
 #include <private/qshapedpixmapdndwindow_p.h>
 #include <private/qsimpledrag_p.h>
 #include <private/qhighdpiscaling_p.h>
@@ -170,6 +171,17 @@ QMimeData *QXcbDrag::platformDropData()
     return dropData;
 }
 
+bool QXcbDrag::eventFilter(QObject *o, QEvent *e)
+{
+    /* We are setting a mouse grab on the QShapedPixmapWindow in order not to
+     * lose the grab when the virtual desktop changes, but
+     * QBasicDrag::eventFilter() expects the events to be coming from the
+     * window where the drag was started. */
+    if (initiatorWindow && o == shapedPixmapWindow())
+        o = initiatorWindow.data();
+    return QBasicDrag::eventFilter(o, e);
+}
+
 void QXcbDrag::startDrag()
 {
     // #fixme enableEventFilter();
@@ -194,6 +206,7 @@ void QXcbDrag::startDrag()
 
     setUseCompositing(current_virtual_desktop->compositingActive());
     setScreen(current_virtual_desktop->screens().constFirst()->screen());
+    initiatorWindow = QGuiApplicationPrivate::currentMouseWindow;
     QBasicDrag::startDrag();
     if (connection()->mouseGrabber() == Q_NULLPTR)
         shapedPixmapWindow()->setMouseGrabEnabled(true);
@@ -202,6 +215,7 @@ void QXcbDrag::startDrag()
 void QXcbDrag::endDrag()
 {
     QBasicDrag::endDrag();
+    initiatorWindow.clear();
 }
 
 static xcb_translate_coordinates_reply_t *
diff --git a/src/plugins/platforms/xcb/qxcbdrag.h b/src/plugins/platforms/xcb/qxcbdrag.h
index c9d257906faf4d7acae312982b4d42c80d8d6051..738da1268d9ad280091c8e87ddffdbb74a3d4666 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.h
+++ b/src/plugins/platforms/xcb/qxcbdrag.h
@@ -69,6 +69,7 @@ public:
     ~QXcbDrag();
 
     virtual QMimeData *platformDropData() Q_DECL_OVERRIDE;
+    bool eventFilter(QObject *o, QEvent *e) Q_DECL_OVERRIDE;
 
     void startDrag() Q_DECL_OVERRIDE;
     void cancel() Q_DECL_OVERRIDE;
@@ -106,6 +107,7 @@ private:
     Qt::DropAction toDropAction(xcb_atom_t atom) const;
     xcb_atom_t toXdndAction(Qt::DropAction a) const;
 
+    QPointer<QWindow> initiatorWindow;
     QPointer<QWindow> currentWindow;
     QPoint currentPosition;