From 46fc3d3729df9e81e42f87c46907d6eb81a0c669 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 30 Jul 2018 09:09:03 +0200 Subject: Windows QPA: Fix override cursor being cleared when crossing window borders Override cursors can be modified externally when for example crossing window borders. Add helper function to enforce the cursor again to QWindowsWindow::applyCursor() which is called for enter events. Task-number: QTBUG-69637 Change-Id: Ibea4da9f2aac81377002b626daae64b1102f6c2b Reviewed-by: Andre de la Rocha Reviewed-by: Oliver Wolff --- src/plugins/platforms/windows/qwindowscursor.cpp | 16 +++++++++++++--- src/plugins/platforms/windows/qwindowscursor.h | 4 +++- src/plugins/platforms/windows/qwindowswindow.cpp | 5 ++++- 3 files changed, 20 insertions(+), 5 deletions(-) (limited to 'src/plugins/platforms/windows') diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index e1a5837201..72155a1d1b 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -549,6 +549,7 @@ CursorHandlePtr QWindowsCursor::standardWindowCursor(Qt::CursorShape shape) } HCURSOR QWindowsCursor::m_overriddenCursor = nullptr; +HCURSOR QWindowsCursor::m_overrideCursor = nullptr; /*! \brief Return cached pixmap cursor or create new one. @@ -621,11 +622,20 @@ void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window) } } +// QTBUG-69637: Override cursors can get reset externally when moving across +// window borders. Enforce the cursor again (to be called from enter event). +void QWindowsCursor::enforceOverrideCursor() +{ + if (hasOverrideCursor() && m_overrideCursor != GetCursor()) + SetCursor(m_overrideCursor); +} + void QWindowsCursor::setOverrideCursor(const QCursor &cursor) { const CursorHandlePtr wcursor = cursorHandle(cursor); - if (wcursor->handle()) { - const HCURSOR previousCursor = SetCursor(wcursor->handle()); + if (const auto overrideCursor = wcursor->handle()) { + m_overrideCursor = overrideCursor; + const HCURSOR previousCursor = SetCursor(overrideCursor); if (m_overriddenCursor == nullptr) m_overriddenCursor = previousCursor; } else { @@ -638,7 +648,7 @@ void QWindowsCursor::clearOverrideCursor() { if (m_overriddenCursor) { SetCursor(m_overriddenCursor); - m_overriddenCursor = nullptr; + m_overriddenCursor = m_overrideCursor = nullptr; } } diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index 53f185358b..345f47597e 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -107,7 +107,8 @@ public: void changeCursor(QCursor * widgetCursor, QWindow * widget) override; void setOverrideCursor(const QCursor &cursor) override; void clearOverrideCursor() override; - bool hasOverrideCursor() const { return m_overriddenCursor != nullptr; } + static void enforceOverrideCursor(); + static bool hasOverrideCursor() { return m_overriddenCursor != nullptr; } QPoint pos() const override; void setPos(const QPoint &pos) override; @@ -143,6 +144,7 @@ private: mutable QPixmap m_ignoreDragCursor; static HCURSOR m_overriddenCursor; + static HCURSOR m_overrideCursor; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index 3909c64c53..aa40d422fb 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -2419,8 +2419,11 @@ static inline bool applyNewCursor(const QWindow *w) void QWindowsWindow::applyCursor() { - if (static_cast(screen()->cursor())->hasOverrideCursor()) + if (QWindowsCursor::hasOverrideCursor()) { + if (isTopLevel()) + QWindowsCursor::enforceOverrideCursor(); return; + } #ifndef QT_NO_CURSOR if (m_cursor->isNull()) { // Recurse up to parent with non-null cursor. Set default for toplevel. if (const QWindow *p = window()->parent()) { -- cgit v1.2.3