From 1373fc13a65821105b88202e12cb987d29e988e0 Mon Sep 17 00:00:00 2001
From: Kai Koehne <kai.koehne@nokia.com>
Date: Tue, 8 Jun 2010 16:43:29 +0200
Subject: [PATCH] QmlDesigner: Prevent freezing while doing drag&drop on some
 Windows systems

QWidget::grabMouse() might freeze if there are e.g. misbehaving virus
scanners installed. This is why e.g. qdockwidget.cpp doesn't use
grabMouse(), but QWidgetPrivate::grabMouseWhileInWindow().

As a hot fix we do the very same now in creator, at the cost of
including the private header qwidget_p.h.

Task-number: BAUHAUS-772
Task-number: QTBUG-11301
---
 .../itemlibrary/customdraganddrop.cpp         | 21 +++++++++++++++++--
 .../itemlibrary/customdraganddrop.h           |  1 +
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.cpp b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.cpp
index 7e67256099d..1672e9947fe 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.cpp
@@ -38,6 +38,10 @@
 #include <QDebug>
 #include <QPainter>
 
+#ifdef Q_OS_WIN
+#include <private/qwidget_p.h>
+#endif
+
 namespace QmlDesigner {
 
 namespace QmlDesignerItemLibraryDragAndDrop {
@@ -54,7 +58,20 @@ void CustomDragAndDropIcon::startDrag()
     raise();
     show();
 
+    grabMouseSafely();
+}
+
+void CustomDragAndDropIcon::grabMouseSafely()
+{
+#ifdef Q_OS_WIN
+    // grabMouse calls SetWindowsHookEx() - this function causes a system-wide
+    // freeze if any other app on the system installs a hook and fails to
+    // process events.
+    QWidgetPrivate *p = qt_widget_private(this);
+    p->grabMouseWhileInWindow();
+#else
     grabMouse();
+#endif
 }
 
 void CustomDragAndDropIcon::mouseReleaseEvent(QMouseEvent *event)
@@ -108,7 +125,8 @@ void CustomDragAndDropIcon::mouseMoveEvent(QMouseEvent *event)
               leave();                     // trigger animation if we leave a widget that accepted
                                            // the drag enter event
       }
-      grabMouse(); //enable the mouse grabber again - after the curser is set
+      //enable the mouse grabber again - after the curser is set
+      grabMouseSafely();
     } else {
         if (CustomDragAndDrop::isAccepted()) // create DragMoveEvents if the current widget
                                              // accepted the DragEnter event
@@ -231,7 +249,6 @@ void CustomDragAndDrop::startCustomDrag(const QPixmap icon, const QPixmap previe
     instance()->m_widget->setIcon(icon);
     instance()->m_widget->setPreview(preview);
     instance()->m_widget->startDrag();
-
 }
 
 bool CustomDragAndDrop::customDragActive()
diff --git a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h
index 263af4c1859..4350f635dbb 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h
+++ b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h
@@ -54,6 +54,7 @@ public:
     void enter();
     void leave();
     void startDrag();
+    void grabMouseSafely();
 
 public slots:
     void animateDrag(int frame);
-- 
GitLab