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 <joerg.bornemann@theqtcompany.com>bb10
parent
8da24d8a5c
commit
296eb88e1c
|
|
@ -67,19 +67,14 @@ Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap);
|
|||
\ingroup qt-lighthouse-win
|
||||
*/
|
||||
|
||||
QWindowsCursorCacheKey::QWindowsCursorCacheKey(const QCursor &c)
|
||||
: shape(c.shape()), bitmapCacheKey(0), maskCacheKey(0)
|
||||
QWindowsPixmapCursorCacheKey::QWindowsPixmapCursorCacheKey(const QCursor &c)
|
||||
: bitmapCacheKey(c.pixmap().cacheKey()), maskCacheKey(0)
|
||||
{
|
||||
if (shape == Qt::BitmapCursor) {
|
||||
const qint64 pixmapCacheKey = c.pixmap().cacheKey();
|
||||
if (pixmapCacheKey) {
|
||||
bitmapCacheKey = pixmapCacheKey;
|
||||
} else {
|
||||
Q_ASSERT(c.bitmap());
|
||||
Q_ASSERT(c.mask());
|
||||
bitmapCacheKey = c.bitmap()->cacheKey();
|
||||
maskCacheKey = c.mask()->cacheKey();
|
||||
}
|
||||
if (!bitmapCacheKey) {
|
||||
Q_ASSERT(c.bitmap());
|
||||
Q_ASSERT(c.mask());
|
||||
bitmapCacheKey = c.bitmap()->cacheKey();
|
||||
maskCacheKey = c.mask()->cacheKey();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -206,6 +201,17 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits,
|
|||
#endif
|
||||
}
|
||||
|
||||
// Create a cursor from image and mask of the format QImage::Format_Mono.
|
||||
static HCURSOR createBitmapCursor(const QCursor &cursor)
|
||||
{
|
||||
Q_ASSERT(cursor.shape() == Qt::BitmapCursor && cursor.bitmap());
|
||||
const QImage bbits = cursor.bitmap()->toImage().convertToFormat(QImage::Format_Mono);
|
||||
const QImage mbits = cursor.mask()->toImage().convertToFormat(QImage::Format_Mono);
|
||||
const bool invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
|
||||
const bool invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
|
||||
return createBitmapCursor(bbits, mbits, cursor.hotSpot(), invb, invm);
|
||||
}
|
||||
|
||||
static inline QSize systemCursorSize() { return QSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)); }
|
||||
static inline QSize standardCursorSize() { return QSize(32, 32); }
|
||||
|
||||
|
|
@ -215,7 +221,7 @@ static inline QSize standardCursorSize() { return QSize(32, 32); }
|
|||
// createBitmapCursor() only work for standard sizes (32,48,64...), which does
|
||||
// not work when scaling the 16x16 openhand cursor bitmaps to 150% (resulting
|
||||
// in a non-standard 24x24 size).
|
||||
static QCursor createPixmapCursorFromData(const QSize &systemCursorSize,
|
||||
static QWindowsCursor::PixmapCursor createPixmapCursorFromData(const QSize &systemCursorSize,
|
||||
// The cursor size the bitmap is targeted for
|
||||
const QSize &bitmapTargetCursorSize,
|
||||
// The actual size of the bitmap data
|
||||
|
|
@ -233,10 +239,10 @@ static QCursor createPixmapCursorFromData(const QSize &systemCursorSize,
|
|||
rawImage = rawImage.transformed(transform, Qt::SmoothTransformation);
|
||||
}
|
||||
const QPoint hotSpot(rawImage.width() / 2, rawImage.height() / 2);
|
||||
return QCursor(rawImage, hotSpot.x(), hotSpot.y());
|
||||
return QWindowsCursor::PixmapCursor(rawImage, hotSpot);
|
||||
}
|
||||
|
||||
QCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
|
||||
QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
|
||||
{
|
||||
// Non-standard Windows cursors are created from bitmaps
|
||||
static const uchar vsplit_bits[] = {
|
||||
|
|
@ -412,14 +418,14 @@ QCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
|
|||
case Qt::ClosedHandCursor:
|
||||
return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 16, closedhand_bits, closedhandm_bits);
|
||||
case Qt::DragCopyCursor:
|
||||
return QCursor(QPixmap(copyDragCursorXpmC), 0, 0);
|
||||
return QWindowsCursor::PixmapCursor(QPixmap(copyDragCursorXpmC), QPoint(0, 0));
|
||||
case Qt::DragMoveCursor:
|
||||
return QCursor(QPixmap(moveDragCursorXpmC), 0, 0);
|
||||
return QWindowsCursor::PixmapCursor(QPixmap(moveDragCursorXpmC), QPoint(0, 0));
|
||||
case Qt::DragLinkCursor:
|
||||
return QCursor(QPixmap(linkDragCursorXpmC), 0, 0);
|
||||
return QWindowsCursor::PixmapCursor(QPixmap(linkDragCursorXpmC), QPoint(0, 0));
|
||||
}
|
||||
|
||||
return QCursor();
|
||||
return QWindowsCursor::PixmapCursor();
|
||||
}
|
||||
#else // Q_OS_WINCE || QT_NO_IMAGEFORMAT_PNG
|
||||
struct QWindowsCustomPngCursor {
|
||||
|
|
@ -430,7 +436,7 @@ struct QWindowsCustomPngCursor {
|
|||
int hotSpotY;
|
||||
};
|
||||
|
||||
QCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
|
||||
QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
|
||||
{
|
||||
static const QWindowsCustomPngCursor pngCursors[] = {
|
||||
{ Qt::SplitVCursor, 32, "splitvcursor_32.png", 11, 11 },
|
||||
|
|
@ -473,11 +479,11 @@ QCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
|
|||
}
|
||||
|
||||
if (!bestFit)
|
||||
return QCursor();
|
||||
return PixmapCursor();
|
||||
|
||||
const QPixmap rawImage(QStringLiteral(":/qt-project.org/windows/cursors/images/") +
|
||||
QString::fromLatin1(bestFit->fileName));
|
||||
return QCursor(rawImage, bestFit->hotSpotX, bestFit->hotSpotY);
|
||||
return PixmapCursor(rawImage, QPoint(bestFit->hotSpotX, bestFit->hotSpotY));
|
||||
}
|
||||
#endif // Q_OS_WINCE || QT_NO_IMAGEFORMAT_PNG
|
||||
|
||||
|
|
@ -486,8 +492,10 @@ struct QWindowsStandardCursorMapping {
|
|||
LPCWSTR resource;
|
||||
};
|
||||
|
||||
HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
|
||||
HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape)
|
||||
{
|
||||
Q_ASSERT(cursorShape != Qt::BitmapCursor);
|
||||
|
||||
static const QWindowsStandardCursorMapping standardCursors[] = {
|
||||
{ Qt::ArrowCursor, IDC_ARROW},
|
||||
{ Qt::UpArrowCursor, IDC_UPARROW },
|
||||
|
|
@ -505,18 +513,7 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
|
|||
{ Qt::PointingHandCursor, IDC_HAND }
|
||||
};
|
||||
|
||||
const Qt::CursorShape cursorShape = c.shape();
|
||||
switch (cursorShape) {
|
||||
case Qt::BitmapCursor: {
|
||||
const QPixmap pixmap = c.pixmap();
|
||||
if (!pixmap.isNull())
|
||||
return QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot());
|
||||
const QImage bbits = c.bitmap()->toImage().convertToFormat(QImage::Format_Mono);
|
||||
const QImage mbits = c.mask()->toImage().convertToFormat(QImage::Format_Mono);
|
||||
const bool invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
|
||||
const bool invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
|
||||
return createBitmapCursor(bbits, mbits, c.hotSpot(), invb, invm);
|
||||
}
|
||||
case Qt::BlankCursor: {
|
||||
QImage blank = QImage(systemCursorSize(), QImage::Format_Mono);
|
||||
blank.fill(0); // ignore color table
|
||||
|
|
@ -529,7 +526,7 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
|
|||
case Qt::DragCopyCursor:
|
||||
case Qt::DragMoveCursor:
|
||||
case Qt::DragLinkCursor:
|
||||
return createSystemCursor(customCursor(cursorShape));
|
||||
return QWindowsCursor::createPixmapCursor(customCursor(cursorShape));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -554,37 +551,41 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
|
|||
\brief Return cached standard cursor resources or create new ones.
|
||||
*/
|
||||
|
||||
QWindowsWindowCursor QWindowsCursor::standardWindowCursor(Qt::CursorShape shape)
|
||||
CursorHandlePtr QWindowsCursor::standardWindowCursor(Qt::CursorShape shape)
|
||||
{
|
||||
const QWindowsCursorCacheKey key(shape);
|
||||
CursorCache::iterator it = m_cursorCache.find(key);
|
||||
if (it == m_cursorCache.end())
|
||||
it = m_cursorCache.insert(key, QWindowsWindowCursor(QCursor(shape)));
|
||||
return it.value();
|
||||
StandardCursorCache::Iterator it = m_standardCursorCache.find(shape);
|
||||
if (it == m_standardCursorCache.end()) {
|
||||
if (const HCURSOR hc = QWindowsCursor::createCursorFromShape(shape))
|
||||
it = m_standardCursorCache.insert(shape, CursorHandlePtr(new CursorHandle(hc)));
|
||||
}
|
||||
return it != m_standardCursorCache.end() ? it.value() : CursorHandlePtr(new CursorHandle);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Return cached pixmap cursor or create new one.
|
||||
*/
|
||||
|
||||
QWindowsWindowCursor QWindowsCursor::pixmapWindowCursor(const QCursor &c)
|
||||
CursorHandlePtr QWindowsCursor::pixmapWindowCursor(const QCursor &c)
|
||||
{
|
||||
const QWindowsCursorCacheKey cacheKey(c);
|
||||
CursorCache::iterator it = m_cursorCache.find(cacheKey);
|
||||
if (it == m_cursorCache.end()) {
|
||||
if (m_cursorCache.size() > 50) {
|
||||
const QWindowsPixmapCursorCacheKey cacheKey(c);
|
||||
PixmapCursorCache::iterator it = m_pixmapCursorCache.find(cacheKey);
|
||||
if (it == m_pixmapCursorCache.end()) {
|
||||
if (m_pixmapCursorCache.size() > 50) {
|
||||
// Prevent the cursor cache from growing indefinitely hitting GDI resource
|
||||
// limits if new pixmap cursors are created repetitively by purging out
|
||||
// all-noncurrent pixmap cursors (QTBUG-43515)
|
||||
const HCURSOR currentCursor = GetCursor();
|
||||
for (it = m_cursorCache.begin(); it != m_cursorCache.end() ; ) {
|
||||
if (it.key().bitmapCacheKey && it.value().handle() != currentCursor)
|
||||
it = m_cursorCache.erase(it);
|
||||
for (it = m_pixmapCursorCache.begin(); it != m_pixmapCursorCache.end() ; ) {
|
||||
if (it.value()->handle() != currentCursor)
|
||||
it = m_pixmapCursorCache.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
}
|
||||
it = m_cursorCache.insert(cacheKey, QWindowsWindowCursor(c));
|
||||
const QPixmap pixmap = c.pixmap();
|
||||
const HCURSOR hc = pixmap.isNull()
|
||||
? createBitmapCursor(c) : QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot());
|
||||
it = m_pixmapCursorCache.insert(cacheKey, CursorHandlePtr(new CursorHandle(hc)));
|
||||
}
|
||||
return it.value();
|
||||
}
|
||||
|
|
@ -606,13 +607,13 @@ void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window)
|
|||
if (!window)
|
||||
return;
|
||||
if (!cursorIn) {
|
||||
QWindowsWindow::baseWindowOf(window)->setCursor(QWindowsWindowCursor());
|
||||
QWindowsWindow::baseWindowOf(window)->setCursor(CursorHandlePtr(new CursorHandle));
|
||||
return;
|
||||
}
|
||||
const QWindowsWindowCursor wcursor =
|
||||
const CursorHandlePtr wcursor =
|
||||
cursorIn->shape() == Qt::BitmapCursor ?
|
||||
pixmapWindowCursor(*cursorIn) : standardWindowCursor(cursorIn->shape());
|
||||
if (wcursor.handle()) {
|
||||
if (wcursor->handle()) {
|
||||
QWindowsWindow::baseWindowOf(window)->setCursor(wcursor);
|
||||
} else {
|
||||
qWarning("%s: Unable to obtain system cursor for %d",
|
||||
|
|
@ -658,78 +659,11 @@ void QWindowsCursor::setPos(const QPoint &pos)
|
|||
\brief Per-Window cursor. Contains a QCursor and manages its associated system
|
||||
cursor handle resource.
|
||||
|
||||
Based on QSharedDataPointer, so that it can be passed around and
|
||||
used as a property of QWindowsBaseWindow.
|
||||
|
||||
\internal
|
||||
\ingroup qt-lighthouse-win
|
||||
\sa QWindowsCursor
|
||||
*/
|
||||
|
||||
class QWindowsWindowCursorData : public QSharedData
|
||||
{
|
||||
public:
|
||||
QWindowsWindowCursorData() : m_cursor(Qt::ArrowCursor), m_handle(0) {}
|
||||
explicit QWindowsWindowCursorData(const QCursor &c);
|
||||
~QWindowsWindowCursorData();
|
||||
|
||||
const QCursor m_cursor;
|
||||
const HCURSOR m_handle;
|
||||
};
|
||||
|
||||
QWindowsWindowCursorData::QWindowsWindowCursorData(const QCursor &c) :
|
||||
m_cursor(c),
|
||||
m_handle(QWindowsCursor::createSystemCursor(c))
|
||||
{
|
||||
}
|
||||
|
||||
QWindowsWindowCursorData::~QWindowsWindowCursorData()
|
||||
{
|
||||
if (m_handle)
|
||||
DestroyCursor(m_handle);
|
||||
}
|
||||
|
||||
QWindowsWindowCursor::QWindowsWindowCursor() :
|
||||
m_data(new QWindowsWindowCursorData)
|
||||
{
|
||||
}
|
||||
|
||||
QWindowsWindowCursor::QWindowsWindowCursor(const QCursor &c) :
|
||||
m_data(new QWindowsWindowCursorData(c))
|
||||
{
|
||||
}
|
||||
|
||||
QWindowsWindowCursor::~QWindowsWindowCursor()
|
||||
{
|
||||
}
|
||||
|
||||
QWindowsWindowCursor::QWindowsWindowCursor(const QWindowsWindowCursor &rhs) :
|
||||
m_data(rhs.m_data)
|
||||
{
|
||||
}
|
||||
|
||||
QWindowsWindowCursor & QWindowsWindowCursor::operator =(const QWindowsWindowCursor &rhs)
|
||||
{
|
||||
if (this != &rhs)
|
||||
m_data.operator =(rhs.m_data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool QWindowsWindowCursor::isNull() const
|
||||
{
|
||||
return m_data->m_handle == 0;
|
||||
}
|
||||
|
||||
QCursor QWindowsWindowCursor::cursor() const
|
||||
{
|
||||
return m_data->m_cursor;
|
||||
}
|
||||
|
||||
HCURSOR QWindowsWindowCursor::handle() const
|
||||
{
|
||||
return m_data->m_handle;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // !QT_NO_CURSOR
|
||||
|
|
|
|||
|
|
@ -37,51 +37,49 @@
|
|||
#include "qtwindows_additional.h"
|
||||
|
||||
#include <qpa/qplatformcursor.h>
|
||||
#include <QtCore/QSharedDataPointer>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtCore/QHash>
|
||||
|
||||
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<QWindowsWindowCursorData> m_data;
|
||||
const HCURSOR m_hcursor;
|
||||
};
|
||||
|
||||
typedef QSharedPointer<CursorHandle> 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<QWindowsCursorCacheKey, QWindowsWindowCursor> CursorCache;
|
||||
typedef QHash<Qt::CursorShape, CursorHandlePtr> StandardCursorCache;
|
||||
typedef QHash<QWindowsPixmapCursorCacheKey, CursorHandlePtr> PixmapCursorCache;
|
||||
|
||||
CursorCache m_cursorCache;
|
||||
StandardCursorCache m_standardCursorCache;
|
||||
PixmapCursorCache m_pixmapCursorCache;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -218,23 +218,14 @@ public:
|
|||
STDMETHOD(GiveFeedback)(DWORD dwEffect);
|
||||
|
||||
private:
|
||||
class DragCursorHandle {
|
||||
Q_DISABLE_COPY(DragCursorHandle)
|
||||
public:
|
||||
DragCursorHandle(HCURSOR c) : cursor(c) {}
|
||||
~DragCursorHandle() { DestroyCursor(cursor); }
|
||||
const HCURSOR cursor;
|
||||
};
|
||||
typedef QSharedPointer<DragCursorHandle> DragCursorHandlePtr;
|
||||
|
||||
struct CursorEntry {
|
||||
CursorEntry() : cacheKey(0) {}
|
||||
CursorEntry(const QPixmap &p, qint64 cK, const DragCursorHandlePtr &c, const QPoint &h) :
|
||||
CursorEntry(const QPixmap &p, qint64 cK, const CursorHandlePtr &c, const QPoint &h) :
|
||||
pixmap(p), cacheKey(cK), cursor(c), hotSpot(h) {}
|
||||
|
||||
QPixmap pixmap;
|
||||
qint64 cacheKey; // Cache key of cursor
|
||||
DragCursorHandlePtr cursor;
|
||||
CursorHandlePtr cursor;
|
||||
QPoint hotSpot;
|
||||
};
|
||||
|
||||
|
|
@ -275,7 +266,7 @@ QWindowsOleDropSource::~QWindowsOleDropSource()
|
|||
QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e)
|
||||
{
|
||||
d << "CursorEntry:" << e.pixmap.size() << '#' << e.cacheKey
|
||||
<< "HCURSOR" << e.cursor->cursor << "hotspot:" << e.hotSpot;
|
||||
<< "HCURSOR" << e.cursor->handle() << "hotspot:" << e.hotSpot;
|
||||
return d;
|
||||
}
|
||||
#endif // !QT_NO_DEBUG_STREAM
|
||||
|
|
@ -345,7 +336,7 @@ void QWindowsOleDropSource::createCursors()
|
|||
}
|
||||
|
||||
if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newPixmap, newHotSpot)) {
|
||||
const CursorEntry entry(newPixmap, cacheKey, DragCursorHandlePtr(new DragCursorHandle(sysCursor)), newHotSpot);
|
||||
const CursorEntry entry(newPixmap, cacheKey, CursorHandlePtr(new CursorHandle(sysCursor)), newHotSpot);
|
||||
if (it == m_cursors.end())
|
||||
m_cursors.insert(action, entry);
|
||||
else
|
||||
|
|
@ -458,7 +449,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
|
|||
const CursorEntry &e = it.value();
|
||||
switch (m_mode) {
|
||||
case MouseDrag:
|
||||
SetCursor(e.cursor->cursor);
|
||||
SetCursor(e.cursor->handle());
|
||||
break;
|
||||
case TouchDrag:
|
||||
if (!m_touchDragWindow)
|
||||
|
|
@ -718,16 +709,16 @@ QPixmap QWindowsDrag::defaultCursor(Qt::DropAction action) const
|
|||
switch (action) {
|
||||
case Qt::CopyAction:
|
||||
if (m_copyDragCursor.isNull())
|
||||
m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor).pixmap();
|
||||
m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor).pixmap;
|
||||
return m_copyDragCursor;
|
||||
case Qt::TargetMoveAction:
|
||||
case Qt::MoveAction:
|
||||
if (m_moveDragCursor.isNull())
|
||||
m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor).pixmap();
|
||||
m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor).pixmap;
|
||||
return m_moveDragCursor;
|
||||
case Qt::LinkAction:
|
||||
if (m_linkDragCursor.isNull())
|
||||
m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor).pixmap();
|
||||
m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor).pixmap;
|
||||
return m_linkDragCursor;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -928,6 +928,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
|
|||
m_hdc(0),
|
||||
m_windowState(Qt::WindowNoState),
|
||||
m_opacity(1.0),
|
||||
m_cursor(new CursorHandle),
|
||||
m_dropTarget(0),
|
||||
m_savedStyle(0),
|
||||
m_format(aWindow->requestedFormat()),
|
||||
|
|
@ -2113,13 +2114,13 @@ bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *re
|
|||
|
||||
#ifndef QT_NO_CURSOR
|
||||
// Return the default cursor (Arrow) from QWindowsCursor's cache.
|
||||
static inline QWindowsWindowCursor defaultCursor(const QWindow *w)
|
||||
static inline CursorHandlePtr defaultCursor(const QWindow *w)
|
||||
{
|
||||
if (QScreen *screen = w->screen())
|
||||
if (const QPlatformScreen *platformScreen = screen->handle())
|
||||
if (QPlatformCursor *cursor = platformScreen->cursor())
|
||||
return static_cast<QWindowsCursor *>(cursor)->standardWindowCursor(Qt::ArrowCursor);
|
||||
return QWindowsWindowCursor(Qt::ArrowCursor);
|
||||
return CursorHandlePtr(new CursorHandle(QWindowsCursor::createCursorFromShape(Qt::ArrowCursor)));
|
||||
}
|
||||
|
||||
// Check whether to apply a new cursor. Either the window in question is
|
||||
|
|
@ -2133,7 +2134,7 @@ static inline bool applyNewCursor(const QWindow *w)
|
|||
for (const QWindow *p = underMouse; p ; p = p->parent()) {
|
||||
if (p == w)
|
||||
return true;
|
||||
if (!QWindowsWindow::baseWindowOf(p)->cursor().isNull())
|
||||
if (!QWindowsWindow::baseWindowOf(p)->cursor()->isNull())
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -2149,25 +2150,25 @@ static inline bool applyNewCursor(const QWindow *w)
|
|||
void QWindowsWindow::applyCursor()
|
||||
{
|
||||
#ifndef QT_NO_CURSOR
|
||||
if (m_cursor.isNull()) { // Recurse up to parent with non-null cursor. Set default for toplevel.
|
||||
if (m_cursor->isNull()) { // Recurse up to parent with non-null cursor. Set default for toplevel.
|
||||
if (const QWindow *p = window()->parent()) {
|
||||
QWindowsWindow::baseWindowOf(p)->applyCursor();
|
||||
} else {
|
||||
SetCursor(defaultCursor(window()).handle());
|
||||
SetCursor(defaultCursor(window())->handle());
|
||||
}
|
||||
} else {
|
||||
SetCursor(m_cursor.handle());
|
||||
SetCursor(m_cursor->handle());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
|
||||
void QWindowsWindow::setCursor(const CursorHandlePtr &c)
|
||||
{
|
||||
#ifndef QT_NO_CURSOR
|
||||
if (c.handle() != m_cursor.handle()) {
|
||||
if (c->handle() != m_cursor->handle()) {
|
||||
const bool apply = applyNewCursor(window());
|
||||
qCDebug(lcQpaWindows) << window() << __FUNCTION__
|
||||
<< c.cursor().shape() << " doApply=" << apply;
|
||||
<< c->handle() << " doApply=" << apply;
|
||||
m_cursor = c;
|
||||
if (apply)
|
||||
applyCursor();
|
||||
|
|
|
|||
|
|
@ -225,9 +225,9 @@ public:
|
|||
#endif // !Q_OS_WINCE
|
||||
|
||||
#ifndef QT_NO_CURSOR
|
||||
QWindowsWindowCursor cursor() const { return m_cursor; }
|
||||
CursorHandlePtr cursor() const { return m_cursor; }
|
||||
#endif
|
||||
void setCursor(const QWindowsWindowCursor &c);
|
||||
void setCursor(const CursorHandlePtr &c);
|
||||
void applyCursor();
|
||||
|
||||
inline bool testFlag(unsigned f) const { return (m_flags & f) != 0; }
|
||||
|
|
@ -278,7 +278,7 @@ private:
|
|||
Qt::WindowState m_windowState;
|
||||
qreal m_opacity;
|
||||
#ifndef QT_NO_CURSOR
|
||||
QWindowsWindowCursor m_cursor;
|
||||
CursorHandlePtr m_cursor;
|
||||
#endif
|
||||
QWindowsOleDropTarget *m_dropTarget;
|
||||
unsigned m_savedStyle;
|
||||
|
|
|
|||
Loading…
Reference in New Issue