OSDN Git Service

QmlDesigner: Prevent freezing while doing drag&drop on some Windows
authorKai Koehne <kai.koehne@nokia.com>
Tue, 8 Jun 2010 14:43:29 +0000 (16:43 +0200)
committerKai Koehne <kai.koehne@nokia.com>
Tue, 8 Jun 2010 14:47:10 +0000 (16:47 +0200)
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

src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.cpp
src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h

index 7e67256..1672e99 100644 (file)
 #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()
index 263af4c..4350f63 100644 (file)
@@ -54,6 +54,7 @@ public:
     void enter();
     void leave();
     void startDrag();
+    void grabMouseSafely();
 
 public slots:
     void animateDrag(int frame);