summaryrefslogtreecommitdiffstats
path: root/src/widgets/dialogs
diff options
context:
space:
mode:
authorSérgio Martins <sergio.martins@kdab.com>2014-12-12 12:33:04 +0000
committerSérgio Martins <sergio.martins@kdab.com>2015-01-06 14:22:21 +0100
commit38a3158d2fe32dc55c6b6286fac58f782571294a (patch)
tree950ccb1fc456c6a4d8ba52e3b1310a8f983b3587 /src/widgets/dialogs
parentb699ac070c01958cdc6599675f8335377ac45d3a (diff)
Windows: Fix QColorDialog's live updates while picking outside color
Microsoft's SetCapture() doesn't work on windows owned by other processes, so instead we use a timer. This is the same approach as used by qttools/src/pixeltool. The mouse move approach however is more elegant and doesn't hammer the CPU with QCursor::pos() calls when idle. For this reason the workaround is Q_OS_WIN only. Task-number: QTBUG-34538 Change-Id: I40a6f7df5bf2a3a29ade8fe4a92f5b5c4ece7efb Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com>
Diffstat (limited to 'src/widgets/dialogs')
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp40
-rw-r--r--src/widgets/dialogs/qcolordialog.h1
-rw-r--r--src/widgets/dialogs/qcolordialog_p.h12
3 files changed, 48 insertions, 5 deletions
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index f04e5b9ea6..882bb999fb 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -57,6 +57,7 @@
#include "qdialogbuttonbox.h"
#include "qscreen.h"
#include "qcursor.h"
+#include "qtimer.h"
#include <algorithm>
@@ -1577,6 +1578,11 @@ void QColorDialogPrivate::_q_pickScreenColor()
#else
q->grabMouse();
#endif
+
+#ifdef Q_OS_WIN
+ // On Windows mouse tracking doesn't work over other processes's windows
+ updateTimer->start(30);
+#endif
q->grabKeyboard();
/* With setMouseTracking(true) the desired color can be more precisedly picked up,
* and continuously pushing the mouse button is not necessary.
@@ -1600,6 +1606,9 @@ void QColorDialogPrivate::releaseColorPicking()
cp->setCrossVisible(true);
q->removeEventFilter(colorPickingEventFilter);
q->releaseMouse();
+#ifdef Q_OS_WIN
+ updateTimer->stop();
+#endif
q->releaseKeyboard();
q->setMouseTracking(false);
lblScreenColorInfo->setText(QLatin1String("\n"));
@@ -1782,6 +1791,10 @@ void QColorDialogPrivate::initWidgets()
cancel = buttons->addButton(QDialogButtonBox::Cancel);
QObject::connect(cancel, SIGNAL(clicked()), q, SLOT(reject()));
+#ifdef Q_OS_WIN
+ updateTimer = new QTimer(q);
+ QObject::connect(updateTimer, SIGNAL(timeout()), q, SLOT(_q_updateColorPicking()));
+#endif
retranslateStrings();
}
@@ -2196,18 +2209,37 @@ void QColorDialog::changeEvent(QEvent *e)
QDialog::changeEvent(e);
}
-bool QColorDialogPrivate::handleColorPickingMouseMove(QMouseEvent *e)
+void QColorDialogPrivate::_q_updateColorPicking()
{
- // If the cross is visible the grabbed color will be black most of the times
- cp->setCrossVisible(!cp->geometry().contains(e->pos()));
+#ifndef QT_NO_CURSOR
+ Q_Q(QColorDialog);
+ static QPoint lastGlobalPos;
+ QPoint newGlobalPos = QCursor::pos();
+ if (lastGlobalPos == newGlobalPos)
+ return;
+ lastGlobalPos = newGlobalPos;
- const QPoint globalPos = e->globalPos();
+ if (!q->rect().contains(q->mapFromGlobal(newGlobalPos))) // Inside the dialog mouse tracking works, handleColorPickingMouseMove will be called
+ updateColorPicking(newGlobalPos);
+#endif // ! QT_NO_CURSOR
+}
+
+void QColorDialogPrivate::updateColorPicking(const QPoint &globalPos)
+{
const QColor color = grabScreenColor(globalPos);
// QTBUG-39792, do not change standard, custom color selectors while moving as
// otherwise it is not possible to pre-select a custom cell for assignment.
setCurrentColor(color, ShowColor);
lblScreenColorInfo->setText(QColorDialog::tr("Cursor at %1, %2, color: %3\nPress ESC to cancel")
.arg(globalPos.x()).arg(globalPos.y()).arg(color.name()));
+}
+
+bool QColorDialogPrivate::handleColorPickingMouseMove(QMouseEvent *e)
+{
+ // If the cross is visible the grabbed color will be black most of the times
+ cp->setCrossVisible(!cp->geometry().contains(e->pos()));
+
+ updateColorPicking(e->globalPos());
return true;
}
diff --git a/src/widgets/dialogs/qcolordialog.h b/src/widgets/dialogs/qcolordialog.h
index d23254a2b2..b06da2ab13 100644
--- a/src/widgets/dialogs/qcolordialog.h
+++ b/src/widgets/dialogs/qcolordialog.h
@@ -116,6 +116,7 @@ private:
Q_PRIVATE_SLOT(d_func(), void _q_newCustom(int, int))
Q_PRIVATE_SLOT(d_func(), void _q_newStandard(int, int))
Q_PRIVATE_SLOT(d_func(), void _q_pickScreenColor())
+ Q_PRIVATE_SLOT(d_func(), void _q_updateColorPicking())
friend class QColorShower;
};
diff --git a/src/widgets/dialogs/qcolordialog_p.h b/src/widgets/dialogs/qcolordialog_p.h
index af3ebe8925..2b501522f5 100644
--- a/src/widgets/dialogs/qcolordialog_p.h
+++ b/src/widgets/dialogs/qcolordialog_p.h
@@ -63,6 +63,7 @@ class QVBoxLayout;
class QPushButton;
class QWellArray;
class QColorPickingEventFilter;
+class QTimer;
class QColorDialogPrivate : public QDialogPrivate
{
@@ -75,7 +76,11 @@ public:
SetColorAll = ShowColor | SelectColor
};
- QColorDialogPrivate() : options(new QColorDialogOptions) {}
+ QColorDialogPrivate() : options(new QColorDialogOptions)
+#ifdef Q_OS_WIN
+ , updateTimer(0)
+#endif
+ {}
QPlatformColorDialogHelper *platformColorDialogHelper() const
{ return static_cast<QPlatformColorDialogHelper *>(platformHelper()); }
@@ -104,6 +109,8 @@ public:
void _q_newCustom(int, int);
void _q_newStandard(int, int);
void _q_pickScreenColor();
+ void _q_updateColorPicking();
+ void updateColorPicking(const QPoint &pos);
void releaseColorPicking();
bool handleColorPickingMouseMove(QMouseEvent *e);
bool handleColorPickingMouseButtonRelease(QMouseEvent *e);
@@ -136,6 +143,9 @@ public:
QPointer<QObject> receiverToDisconnectOnClose;
QByteArray memberToDisconnectOnClose;
+#ifdef Q_OS_WIN
+ QTimer *updateTimer;
+#endif
#ifdef Q_WS_MAC
void openCocoaColorPanel(const QColor &initial,