summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorSérgio Martins <sergio.martins@kdab.com>2015-01-06 18:13:27 +0000
committerSérgio Martins <sergio.martins@kdab.com>2015-01-09 16:54:54 +0100
commit6e217f067800541ccb9596cf03d52093b2909385 (patch)
treeb36e476776bb3088e6cbdea91524a1ef583166a7 /src/widgets
parentb077ed746ae91321ff9aa72ebd17a463bec98413 (diff)
QColorDialog: Don't loose focus while color picking
On Windows mouse grabbing doesn't work across processes, which means we're interacting with other windows when picking colors. Workaround that by having a transparent 1x1 window below the cursor at all times so we catch the mouse click. Clicking before the window is below the cursor won't happen because our timer interval is 30ms, so it's quite fast. It's hacky but it's what we can do for a feature which was very broken on Windows. Task-number: QTBUG-43663 Change-Id: I295378e033ddc6d9c2230335f0953a727c21e1dd Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp24
-rw-r--r--src/widgets/dialogs/qcolordialog_p.h6
2 files changed, 23 insertions, 7 deletions
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index 882bb999fb..b133c49b5e 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -1579,12 +1579,17 @@ void QColorDialogPrivate::_q_pickScreenColor()
q->grabMouse();
#endif
-#ifdef Q_OS_WIN
+#ifdef Q_OS_WIN32 // excludes WinCE and WinRT
// On Windows mouse tracking doesn't work over other processes's windows
updateTimer->start(30);
+
+ // HACK: Because mouse grabbing doesn't work across processes, we have to have a dummy,
+ // invisible window to catch the mouse click, otherwise we will click whatever we clicked
+ // and loose focus.
+ dummyTransparentWindow.show();
#endif
q->grabKeyboard();
- /* With setMouseTracking(true) the desired color can be more precisedly picked up,
+ /* With setMouseTracking(true) the desired color can be more precisely picked up,
* and continuously pushing the mouse button is not necessary.
*/
q->setMouseTracking(true);
@@ -1606,8 +1611,9 @@ void QColorDialogPrivate::releaseColorPicking()
cp->setCrossVisible(true);
q->removeEventFilter(colorPickingEventFilter);
q->releaseMouse();
-#ifdef Q_OS_WIN
+#ifdef Q_OS_WIN32
updateTimer->stop();
+ dummyTransparentWindow.setVisible(false);
#endif
q->releaseKeyboard();
q->setMouseTracking(false);
@@ -1635,6 +1641,10 @@ void QColorDialogPrivate::init(const QColor &initial)
#ifdef Q_WS_MAC
delegate = 0;
#endif
+#ifdef Q_OS_WIN32
+ dummyTransparentWindow.resize(1, 1);
+ dummyTransparentWindow.setFlags(Qt::Tool | Qt::FramelessWindowHint);
+#endif
q->setCurrentColor(initial);
}
@@ -1791,7 +1801,7 @@ void QColorDialogPrivate::initWidgets()
cancel = buttons->addButton(QDialogButtonBox::Cancel);
QObject::connect(cancel, SIGNAL(clicked()), q, SLOT(reject()));
-#ifdef Q_OS_WIN
+#ifdef Q_OS_WIN32
updateTimer = new QTimer(q);
QObject::connect(updateTimer, SIGNAL(timeout()), q, SLOT(_q_updateColorPicking()));
#endif
@@ -2219,8 +2229,12 @@ void QColorDialogPrivate::_q_updateColorPicking()
return;
lastGlobalPos = newGlobalPos;
- if (!q->rect().contains(q->mapFromGlobal(newGlobalPos))) // Inside the dialog mouse tracking works, handleColorPickingMouseMove will be called
+ if (!q->rect().contains(q->mapFromGlobal(newGlobalPos))) { // Inside the dialog mouse tracking works, handleColorPickingMouseMove will be called
updateColorPicking(newGlobalPos);
+#ifdef Q_OS_WIN32
+ dummyTransparentWindow.setPosition(newGlobalPos);
+#endif
+ }
#endif // ! QT_NO_CURSOR
}
diff --git a/src/widgets/dialogs/qcolordialog_p.h b/src/widgets/dialogs/qcolordialog_p.h
index 2b501522f5..9182b510f1 100644
--- a/src/widgets/dialogs/qcolordialog_p.h
+++ b/src/widgets/dialogs/qcolordialog_p.h
@@ -49,6 +49,7 @@
#include "private/qdialog_p.h"
#include "qcolordialog.h"
#include "qsharedpointer.h"
+#include "qwindow.h"
#ifndef QT_NO_COLORDIALOG
@@ -77,7 +78,7 @@ public:
};
QColorDialogPrivate() : options(new QColorDialogOptions)
-#ifdef Q_OS_WIN
+#ifdef Q_OS_WIN32
, updateTimer(0)
#endif
{}
@@ -143,8 +144,9 @@ public:
QPointer<QObject> receiverToDisconnectOnClose;
QByteArray memberToDisconnectOnClose;
-#ifdef Q_OS_WIN
+#ifdef Q_OS_WIN32
QTimer *updateTimer;
+ QWindow dummyTransparentWindow;
#endif
#ifdef Q_WS_MAC