diff options
author | Sérgio Martins <sergio.martins@kdab.com> | 2014-12-12 12:33:04 +0000 |
---|---|---|
committer | Sérgio Martins <sergio.martins@kdab.com> | 2015-01-06 14:22:21 +0100 |
commit | 38a3158d2fe32dc55c6b6286fac58f782571294a (patch) | |
tree | 950ccb1fc456c6a4d8ba52e3b1310a8f983b3587 /src/widgets | |
parent | b699ac070c01958cdc6599675f8335377ac45d3a (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')
-rw-r--r-- | src/widgets/dialogs/qcolordialog.cpp | 40 | ||||
-rw-r--r-- | src/widgets/dialogs/qcolordialog.h | 1 | ||||
-rw-r--r-- | src/widgets/dialogs/qcolordialog_p.h | 12 |
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, |