From b05d1c2ebfebf0f427a92668c0a7b177d0952012 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 2 Jun 2017 09:49:31 +0200 Subject: QPlatformCursor: Add functions for setting/clearing override cursors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit QPA is modeled on the assumption that the cursor is a property of the window and therefore sets the override cursors on all windows. However, on macOS and Windows, the cursor is set per application (or screen). On these platforms, the per window cursor setting needs to be emulated which is a source of bugs especially for override cursors. Add new virtuals to QPlatformCursor allowing to set override cursors which can be implemented by directly setting the cursor on those platforms. Task-number: QTBUG-40122 Task-number: QTBUG-61133 Change-Id: I31d6a927128d22bb1620a8ace35988c0e126236e Reviewed-by: Morten Johan Sørvig Reviewed-by: Gabriel de Dietrich Reviewed-by: Maurice Kalinowski --- src/plugins/platforms/windows/qwindowscursor.cpp | 30 +++++++++++++++++++--- src/plugins/platforms/windows/qwindowscursor.h | 7 +++++ .../platforms/windows/qwindowsintegration.cpp | 2 ++ 3 files changed, 36 insertions(+), 3 deletions(-) (limited to 'src/plugins/platforms') diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp index 1bebe88df7..b9c320fd8f 100644 --- a/src/plugins/platforms/windows/qwindowscursor.cpp +++ b/src/plugins/platforms/windows/qwindowscursor.cpp @@ -586,6 +586,13 @@ QWindowsCursor::QWindowsCursor(const QPlatformScreen *screen) Q_UNUSED(dummy) } +inline CursorHandlePtr QWindowsCursor::cursorHandle(const QCursor &cursor) +{ + return cursor.shape() == Qt::BitmapCursor + ? pixmapWindowCursor(cursor) + : standardWindowCursor(cursor.shape()); +} + /*! \brief Set a cursor on a window. @@ -603,9 +610,7 @@ void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window) platformWindow->setCursor(CursorHandlePtr(new CursorHandle)); return; } - const CursorHandlePtr wcursor = - cursorIn->shape() == Qt::BitmapCursor ? - pixmapWindowCursor(*cursorIn) : standardWindowCursor(cursorIn->shape()); + const CursorHandlePtr wcursor = cursorHandle(*cursorIn); if (wcursor->handle()) { platformWindow->setCursor(wcursor); } else { @@ -614,6 +619,25 @@ void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window) } } +void QWindowsCursor::setOverrideCursor(const QCursor &cursor) +{ + const CursorHandlePtr wcursor = cursorHandle(cursor); + if (wcursor->handle()) { + m_overriddenCursor = SetCursor(wcursor->handle()); + } else { + qWarning("%s: Unable to obtain system cursor for %d", + __FUNCTION__, cursor.shape()); + } +} + +void QWindowsCursor::clearOverrideCursor() +{ + if (m_overriddenCursor) { + SetCursor(m_overriddenCursor); + m_overriddenCursor = nullptr; + } +} + QPoint QWindowsCursor::mousePosition() { POINT p; diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index df2e22733b..9aa9523ac8 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -105,6 +105,9 @@ public: explicit QWindowsCursor(const QPlatformScreen *screen); void changeCursor(QCursor * widgetCursor, QWindow * widget) override; + void setOverrideCursor(const QCursor &cursor) override; + void clearOverrideCursor() override; + QPoint pos() const override; void setPos(const QPoint &pos) override; @@ -127,6 +130,8 @@ private: typedef QHash StandardCursorCache; typedef QHash PixmapCursorCache; + CursorHandlePtr cursorHandle(const QCursor &c); + const QPlatformScreen *const m_screen; StandardCursorCache m_standardCursorCache; PixmapCursorCache m_pixmapCursorCache; @@ -135,6 +140,8 @@ private: mutable QPixmap m_moveDragCursor; mutable QPixmap m_linkDragCursor; mutable QPixmap m_ignoreDragCursor; + + HCURSOR m_overriddenCursor = nullptr; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsintegration.cpp b/src/plugins/platforms/windows/qwindowsintegration.cpp index 6c8fccf350..eb7ad5ecd8 100644 --- a/src/plugins/platforms/windows/qwindowsintegration.cpp +++ b/src/plugins/platforms/windows/qwindowsintegration.cpp @@ -72,6 +72,7 @@ #include #include #include +#include #include @@ -242,6 +243,7 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mL } m_context.initTouch(m_options); + QPlatformCursor::setCapability(QPlatformCursor::OverrideCursor); } QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate() -- cgit v1.2.3