From 296eb88e1c87dc4793b12af4ddfcc67fe88b8ad8 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 16 Nov 2015 16:48:42 +0100 Subject: Windows: Refactor cursor handling. Applying scaling to the pixmaps used in pixmap cursors requires applying a scale factor in a code path now in a constructor of QWindowsWindowCursorData (nested into QWindowsWindowCursor). This needs to be split and the code paths for cursors created from a Qt::CursorShape value and pixmap cursors need to be further separated. Replace the QSharedDataPointer-based QWindowsWindowCursor class by a simple, non-copyable class CursorHandle managing the HCURSOR handle and pass it around using a QSharedPointer. Split the cache in QWindowsCursor into one based on Qt::CursorShape and one based on the cache key aggregated from the pixmap cache keys (using QWindowsPixmapCursorCacheKey renamed from QWindowsCursorCacheKey), simplifying the standard case based on Qt::CursorShape. Reuse class CursorHandle in QWindowsOleDropSource::CursorEntryCursorEntry, which used a similar class. Remove QWindowsCursor::createSystemCursor(). Avoid the construction of temporary QCursor objects for the standard cursors constructed from using resource pixmaps by introducing a struct PixmapCursor containing pixmap and hotspot. Task-number: QTBUG-49511 Change-Id: I5393d64bd70f7dab68c0a8c2255c7685ac367b2f Reviewed-by: Joerg Bornemann --- src/plugins/platforms/windows/qwindowscursor.h | 65 +++++++++++++++----------- 1 file changed, 37 insertions(+), 28 deletions(-) (limited to 'src/plugins/platforms/windows/qwindowscursor.h') diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h index f1763ddd7d..ac9e87d1fb 100644 --- a/src/plugins/platforms/windows/qwindowscursor.h +++ b/src/plugins/platforms/windows/qwindowscursor.h @@ -37,51 +37,49 @@ #include "qtwindows_additional.h" #include -#include +#include #include QT_BEGIN_NAMESPACE -class QWindowsWindowCursorData; - -struct QWindowsCursorCacheKey +struct QWindowsPixmapCursorCacheKey { - explicit QWindowsCursorCacheKey(const QCursor &c); - explicit QWindowsCursorCacheKey(Qt::CursorShape s) : shape(s), bitmapCacheKey(0), maskCacheKey(0) {} - QWindowsCursorCacheKey() : shape(Qt::CustomCursor), bitmapCacheKey(0), maskCacheKey(0) {} + explicit QWindowsPixmapCursorCacheKey(const QCursor &c); - Qt::CursorShape shape; qint64 bitmapCacheKey; qint64 maskCacheKey; }; -inline bool operator==(const QWindowsCursorCacheKey &k1, const QWindowsCursorCacheKey &k2) +inline bool operator==(const QWindowsPixmapCursorCacheKey &k1, const QWindowsPixmapCursorCacheKey &k2) { - return k1.shape == k2.shape && k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey; + return k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey; } -inline uint qHash(const QWindowsCursorCacheKey &k, uint seed) Q_DECL_NOTHROW +inline uint qHash(const QWindowsPixmapCursorCacheKey &k, uint seed) Q_DECL_NOTHROW { - return (uint(k.shape) + uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed; + return (uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed; } -class QWindowsWindowCursor +class CursorHandle { + Q_DISABLE_COPY(CursorHandle) public: - QWindowsWindowCursor(); - explicit QWindowsWindowCursor(const QCursor &c); - ~QWindowsWindowCursor(); - QWindowsWindowCursor(const QWindowsWindowCursor &c); - QWindowsWindowCursor &operator=(const QWindowsWindowCursor &c); + explicit CursorHandle(HCURSOR hcursor = Q_NULLPTR) : m_hcursor(hcursor) {} + ~CursorHandle() + { + if (m_hcursor) + DestroyCursor(m_hcursor); + } - bool isNull() const; - QCursor cursor() const; - HCURSOR handle() const; + bool isNull() const { return !m_hcursor; } + HCURSOR handle() const { return m_hcursor; } private: - QSharedDataPointer m_data; + const HCURSOR m_hcursor; }; +typedef QSharedPointer CursorHandlePtr; + class QWindowsCursor : public QPlatformCursor { public: @@ -91,6 +89,13 @@ public: CursorSuppressed // Cursor suppressed by touch interaction (Windows 8). }; + struct PixmapCursor { + explicit PixmapCursor(const QPixmap &pix = QPixmap(), const QPoint &h = QPoint()) : pixmap(pix), hotSpot(h) {} + + QPixmap pixmap; + QPoint hotSpot; + }; + QWindowsCursor(); void changeCursor(QCursor * widgetCursor, QWindow * widget) Q_DECL_OVERRIDE; @@ -98,18 +103,22 @@ public: void setPos(const QPoint &pos) Q_DECL_OVERRIDE; static HCURSOR createPixmapCursor(const QPixmap &pixmap, const QPoint &hotSpot); - static HCURSOR createSystemCursor(const QCursor &c); - static QCursor customCursor(Qt::CursorShape cursorShape); + static HCURSOR createPixmapCursor(const PixmapCursor &pc) { return createPixmapCursor(pc.pixmap, pc.hotSpot); } + static PixmapCursor customCursor(Qt::CursorShape cursorShape); + + static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape); static QPoint mousePosition(); static CursorState cursorState(); - QWindowsWindowCursor standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor); - QWindowsWindowCursor pixmapWindowCursor(const QCursor &c); + CursorHandlePtr standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor); + CursorHandlePtr pixmapWindowCursor(const QCursor &c); private: - typedef QHash CursorCache; + typedef QHash StandardCursorCache; + typedef QHash PixmapCursorCache; - CursorCache m_cursorCache; + StandardCursorCache m_standardCursorCache; + PixmapCursorCache m_pixmapCursorCache; }; QT_END_NAMESPACE -- cgit v1.2.3