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>bb10
parent
b077ed746a
commit
6e217f0678
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue