Windows QPA: Fix cursors getting out of sync after restoring override cursors on native windows

Introduce a flag to QWindowsWindow which forces the cursor to be applied
after restoring override cursors.

Fixes: QTBUG-98856
Pick-to: 6.2 5.15
Change-Id: Id62cdc2dd01f45324503a542446b1c11a1fe6f44
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Keith Kyzivat <keith.kyzivat@qt.io>
Reviewed-by: André de la Rocha <andre.rocha@qt.io>
This commit is contained in:
Friedemann Kleint 2021-12-06 10:45:04 +01:00
parent c8609d1e7a
commit 9ad00e4b3f
5 changed files with 24 additions and 5 deletions

View File

@ -181,14 +181,12 @@ QWindowsContext *QWindowsContext::m_instance = nullptr;
\internal
*/
typedef QHash<HWND, QWindowsWindow *> HandleBaseWindowHash;
struct QWindowsContextPrivate {
QWindowsContextPrivate();
unsigned m_systemInfo = 0;
QSet<QString> m_registeredWindowClassNames;
HandleBaseWindowHash m_windows;
QWindowsContext::HandleBaseWindowHash m_windows;
HDC m_displayContext = nullptr;
int m_defaultDPI = 96;
QWindowsKeyMapper m_keyMapper;
@ -460,6 +458,11 @@ QList<int> QWindowsContext::possibleKeys(const QKeyEvent *e) const
return d->m_keyMapper.possibleKeys(e);
}
QWindowsContext::HandleBaseWindowHash &QWindowsContext::windows()
{
return d->m_windows;
}
QSharedPointer<QWindowCreationContext> QWindowsContext::setWindowCreationContext(const QSharedPointer<QWindowCreationContext> &ctx)
{
const QSharedPointer<QWindowCreationContext> old = d->m_creationContext;

View File

@ -86,6 +86,7 @@ class QWindowsContext
{
Q_DISABLE_COPY_MOVE(QWindowsContext)
public:
using HandleBaseWindowHash = QHash<HWND, QWindowsWindow *>;
enum SystemInfoFlags
{
@ -168,6 +169,8 @@ public:
bool useRTLExtensions() const;
QList<int> possibleKeys(const QKeyEvent *e) const;
HandleBaseWindowHash &windows();
static bool isSessionLocked();
QWindowsMimeConverter &mimeConverter() const;

View File

@ -652,6 +652,11 @@ void QWindowsCursor::clearOverrideCursor()
SetCursor(m_overriddenCursor);
m_overriddenCursor = m_overrideCursor = nullptr;
}
auto &windows = QWindowsContext::instance()->windows();
for (auto it = windows.cbegin(), end = windows.cend(); it != end; ++it) {
if (it.value()->screen() == m_screen)
it.value()->setFlag(QWindowsWindow::RestoreOverrideCursor);
}
}
QPoint QWindowsCursor::mousePosition()

View File

@ -2894,7 +2894,14 @@ void QWindowsWindow::applyCursor()
void QWindowsWindow::setCursor(const CursorHandlePtr &c)
{
#ifndef QT_NO_CURSOR
if (c->handle() != m_cursor->handle()) {
bool changed = c->handle() != m_cursor->handle();
// QTBUG-98856: Cursors can get out of sync after restoring override
// cursors on native windows. Force an update.
if (testFlag(RestoreOverrideCursor)) {
clearFlag(RestoreOverrideCursor);
changed = true;
}
if (changed) {
const bool apply = applyNewCursor(window());
qCDebug(lcQpaWindows) << window() << __FUNCTION__
<< c->handle() << " doApply=" << apply;

View File

@ -238,7 +238,8 @@ public:
VulkanSurface = 0x400000,
ResizeMoveActive = 0x800000,
DisableNonClientScaling = 0x1000000,
Direct3DSurface = 0x2000000
Direct3DSurface = 0x2000000,
RestoreOverrideCursor = 0x4000000
};
QWindowsWindow(QWindow *window, const QWindowsWindowData &data);