diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/kernel/qguiapplication.cpp | 31 | ||||
-rw-r--r-- | src/gui/kernel/qplatformcursor.cpp | 41 | ||||
-rw-r--r-- | src/gui/kernel/qplatformcursor.h | 17 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowscursor.cpp | 30 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowscursor.h | 7 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsintegration.cpp | 2 |
6 files changed, 121 insertions, 7 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 7e62ebf161..b76ff65aff 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -3541,6 +3541,22 @@ static inline void applyCursor(const QList<QWindow *> &l, const QCursor &c) } } +static inline void applyOverrideCursor(const QList<QScreen *> &screens, const QCursor &c) +{ + for (QScreen *screen : screens) { + if (QPlatformCursor *cursor = screen->handle()->cursor()) + cursor->setOverrideCursor(c); + } +} + +static inline void clearOverrideCursor(const QList<QScreen *> &screens) +{ + for (QScreen *screen : screens) { + if (QPlatformCursor *cursor = screen->handle()->cursor()) + cursor->clearOverrideCursor(); + } +} + static inline void applyWindowCursor(const QList<QWindow *> &l) { for (int i = 0; i < l.size(); ++i) { @@ -3585,7 +3601,10 @@ void QGuiApplication::setOverrideCursor(const QCursor &cursor) { CHECK_QAPP_INSTANCE() qGuiApp->d_func()->cursor_list.prepend(cursor); - applyCursor(QGuiApplicationPrivate::window_list, cursor); + if (QPlatformCursor::capabilities().testFlag(QPlatformCursor::OverrideCursor)) + applyOverrideCursor(QGuiApplicationPrivate::screen_list, cursor); + else + applyCursor(QGuiApplicationPrivate::window_list, cursor); } /*! @@ -3607,9 +3626,15 @@ void QGuiApplication::restoreOverrideCursor() qGuiApp->d_func()->cursor_list.removeFirst(); if (qGuiApp->d_func()->cursor_list.size() > 0) { QCursor c(qGuiApp->d_func()->cursor_list.value(0)); - applyCursor(QGuiApplicationPrivate::window_list, c); + if (QPlatformCursor::capabilities().testFlag(QPlatformCursor::OverrideCursor)) + applyOverrideCursor(QGuiApplicationPrivate::screen_list, c); + else + applyCursor(QGuiApplicationPrivate::window_list, c); } else { - applyWindowCursor(QGuiApplicationPrivate::window_list); + if (QPlatformCursor::capabilities().testFlag(QPlatformCursor::OverrideCursor)) + clearOverrideCursor(QGuiApplicationPrivate::screen_list); + else + applyWindowCursor(QGuiApplicationPrivate::window_list); } } #endif// QT_NO_CURSOR diff --git a/src/gui/kernel/qplatformcursor.cpp b/src/gui/kernel/qplatformcursor.cpp index af0214e016..9d2d65246e 100644 --- a/src/gui/kernel/qplatformcursor.cpp +++ b/src/gui/kernel/qplatformcursor.cpp @@ -95,6 +95,17 @@ QT_BEGIN_NAMESPACE */ /*! + \enum QPlatformCursor::OverrideCursor + \since 5.10 + + \value OverrideCursor Indicates that the platform implements + QPlatformCursor::setOverrideCursor() and + QPlatformCursor::clearOverrideCursor(). +*/ + +QPlatformCursor::Capabilities QPlatformCursor::m_capabilities = 0; + +/*! \fn QPlatformCursor::QPlatformCursor() Constructs a QPlatformCursor. @@ -659,4 +670,34 @@ void QPlatformCursorImage::set(const uchar *data, const uchar *mask, \brief Return the cursor's hotspot */ +#ifndef QT_NO_CURSOR +/*! + Reimplement this function in subclass to set an override cursor + on the associated screen and return true to indicate success. + + This function can be implemented on platforms where the cursor is a + property of the application or the screen rather than a property + of the window. On these platforms, the OverrideCursor capability + should be set. + + \sa QGuiApplication::setOverrideCursor(), Capabilities + + \since 5.10 +*/ +void QPlatformCursor::setOverrideCursor(const QCursor &) +{ +} + +/*! + Reimplement this function in subclass to clear the override cursor. + + \sa QGuiApplication::clearOverrideCursor(), Capabilities + + \since 5.10 +*/ +void QPlatformCursor::clearOverrideCursor() +{ +} +#endif // QT_NO_CURSOR + QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformcursor.h b/src/gui/kernel/qplatformcursor.h index dddd9e5831..40e8a562f8 100644 --- a/src/gui/kernel/qplatformcursor.h +++ b/src/gui/kernel/qplatformcursor.h @@ -78,21 +78,36 @@ private: class Q_GUI_EXPORT QPlatformCursor : public QObject { public: + enum Capability { + OverrideCursor = 0x1 + }; + Q_DECLARE_FLAGS(Capabilities, Capability) + QPlatformCursor(); // input methods virtual void pointerEvent(const QMouseEvent & event) { Q_UNUSED(event); } #ifndef QT_NO_CURSOR virtual void changeCursor(QCursor * windowCursor, QWindow * window) = 0; -#endif + virtual void setOverrideCursor(const QCursor &); + virtual void clearOverrideCursor(); +#endif // QT_NO_CURSOR virtual QPoint pos() const; virtual void setPos(const QPoint &pos); + static Capabilities capabilities() { return m_capabilities; } + static void setCapabilities(Capabilities c) { m_capabilities = c; } + static void setCapability(Capability c) { m_capabilities.setFlag(c); } + private: friend void qt_qpa_set_cursor(QWidget * w, bool force); friend class QApplicationPrivate; + + static Capabilities m_capabilities; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QPlatformCursor::Capabilities) + QT_END_NAMESPACE #endif // QPLATFORMCURSOR_H 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<Qt::CursorShape, CursorHandlePtr> StandardCursorCache; typedef QHash<QWindowsPixmapCursorCacheKey, CursorHandlePtr> 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 <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qhighdpiscaling_p.h> #include <QtGui/qpa/qplatforminputcontextfactory_p.h> +#include <QtGui/qpa/qplatformcursor.h> #include <QtEventDispatcherSupport/private/qwindowsguieventdispatcher_p.h> @@ -242,6 +243,7 @@ QWindowsIntegrationPrivate::QWindowsIntegrationPrivate(const QStringList ¶mL } m_context.initTouch(m_options); + QPlatformCursor::setCapability(QPlatformCursor::OverrideCursor); } QWindowsIntegrationPrivate::~QWindowsIntegrationPrivate() |