Windows: Fix the size of drag cursors in multi-screen setups.
Move QWindowsDrag::defaultCursor() to the per-screen instance of QWindowsCursor so that the cached default drag cursor pixmaps are created with the correct size per screen. Task-number: QTBUG-49511 Change-Id: I02f75ac3b1e5e064325b066ee03e1d5c8a7c7ee8 Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
This commit is contained in:
parent
05c8e51d88
commit
07efdb78f0
@ -692,6 +692,94 @@ void QWindowsCursor::setPos(const QPoint &pos)
|
|||||||
SetCursorPos(pos.x() , pos.y());
|
SetCursorPos(pos.x() , pos.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPixmap QWindowsCursor::dragDefaultCursor(Qt::DropAction action) const
|
||||||
|
{
|
||||||
|
switch (action) {
|
||||||
|
case Qt::CopyAction:
|
||||||
|
if (m_copyDragCursor.isNull())
|
||||||
|
m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor, m_screen).pixmap;
|
||||||
|
return m_copyDragCursor;
|
||||||
|
case Qt::TargetMoveAction:
|
||||||
|
case Qt::MoveAction:
|
||||||
|
if (m_moveDragCursor.isNull())
|
||||||
|
m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor, m_screen).pixmap;
|
||||||
|
return m_moveDragCursor;
|
||||||
|
case Qt::LinkAction:
|
||||||
|
if (m_linkDragCursor.isNull())
|
||||||
|
m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor, m_screen).pixmap;
|
||||||
|
return m_linkDragCursor;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char * const ignoreDragCursorXpmC[] = {
|
||||||
|
"24 30 3 1",
|
||||||
|
". c None",
|
||||||
|
"a c #000000",
|
||||||
|
"X c #FFFFFF",
|
||||||
|
"aa......................",
|
||||||
|
"aXa.....................",
|
||||||
|
"aXXa....................",
|
||||||
|
"aXXXa...................",
|
||||||
|
"aXXXXa..................",
|
||||||
|
"aXXXXXa.................",
|
||||||
|
"aXXXXXXa................",
|
||||||
|
"aXXXXXXXa...............",
|
||||||
|
"aXXXXXXXXa..............",
|
||||||
|
"aXXXXXXXXXa.............",
|
||||||
|
"aXXXXXXaaaa.............",
|
||||||
|
"aXXXaXXa................",
|
||||||
|
"aXXaaXXa................",
|
||||||
|
"aXa..aXXa...............",
|
||||||
|
"aa...aXXa...............",
|
||||||
|
"a.....aXXa..............",
|
||||||
|
"......aXXa.....XXXX.....",
|
||||||
|
".......aXXa..XXaaaaXX...",
|
||||||
|
".......aXXa.XaaaaaaaaX..",
|
||||||
|
"........aa.XaaaXXXXaaaX.",
|
||||||
|
"...........XaaaaX..XaaX.",
|
||||||
|
"..........XaaXaaaX..XaaX",
|
||||||
|
"..........XaaXXaaaX.XaaX",
|
||||||
|
"..........XaaX.XaaaXXaaX",
|
||||||
|
"..........XaaX..XaaaXaaX",
|
||||||
|
"...........XaaX..XaaaaX.",
|
||||||
|
"...........XaaaXXXXaaaX.",
|
||||||
|
"............XaaaaaaaaX..",
|
||||||
|
".............XXaaaaXX...",
|
||||||
|
"...............XXXX....."};
|
||||||
|
|
||||||
|
if (m_ignoreDragCursor.isNull()) {
|
||||||
|
#if !defined (Q_OS_WINCE)
|
||||||
|
HCURSOR cursor = LoadCursor(NULL, IDC_NO);
|
||||||
|
ICONINFO iconInfo = {0, 0, 0, 0, 0};
|
||||||
|
GetIconInfo(cursor, &iconInfo);
|
||||||
|
BITMAP bmColor = {0, 0, 0, 0, 0, 0, 0};
|
||||||
|
|
||||||
|
if (iconInfo.hbmColor
|
||||||
|
&& GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor)
|
||||||
|
&& bmColor.bmWidth == bmColor.bmWidthBytes / 4) {
|
||||||
|
const int colorBitsLength = bmColor.bmHeight * bmColor.bmWidthBytes;
|
||||||
|
uchar *colorBits = new uchar[colorBitsLength];
|
||||||
|
GetBitmapBits(iconInfo.hbmColor, colorBitsLength, colorBits);
|
||||||
|
const QImage colorImage(colorBits, bmColor.bmWidth, bmColor.bmHeight,
|
||||||
|
bmColor.bmWidthBytes, QImage::Format_ARGB32);
|
||||||
|
|
||||||
|
m_ignoreDragCursor = QPixmap::fromImage(colorImage);
|
||||||
|
delete [] colorBits;
|
||||||
|
} else {
|
||||||
|
m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
|
||||||
|
}
|
||||||
|
|
||||||
|
DeleteObject(iconInfo.hbmMask);
|
||||||
|
DeleteObject(iconInfo.hbmColor);
|
||||||
|
DestroyCursor(cursor);
|
||||||
|
#else // !Q_OS_WINCE
|
||||||
|
m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
|
||||||
|
#endif // !Q_OS_WINCE
|
||||||
|
}
|
||||||
|
return m_ignoreDragCursor;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class QWindowsWindowCursor
|
\class QWindowsWindowCursor
|
||||||
\brief Per-Window cursor. Contains a QCursor and manages its associated system
|
\brief Per-Window cursor. Contains a QCursor and manages its associated system
|
||||||
|
@ -113,6 +113,8 @@ public:
|
|||||||
CursorHandlePtr standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
|
CursorHandlePtr standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
|
||||||
CursorHandlePtr pixmapWindowCursor(const QCursor &c);
|
CursorHandlePtr pixmapWindowCursor(const QCursor &c);
|
||||||
|
|
||||||
|
QPixmap dragDefaultCursor(Qt::DropAction action) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef QHash<Qt::CursorShape, CursorHandlePtr> StandardCursorCache;
|
typedef QHash<Qt::CursorShape, CursorHandlePtr> StandardCursorCache;
|
||||||
typedef QHash<QWindowsPixmapCursorCacheKey, CursorHandlePtr> PixmapCursorCache;
|
typedef QHash<QWindowsPixmapCursorCacheKey, CursorHandlePtr> PixmapCursorCache;
|
||||||
@ -120,6 +122,11 @@ private:
|
|||||||
const QPlatformScreen *const m_screen;
|
const QPlatformScreen *const m_screen;
|
||||||
StandardCursorCache m_standardCursorCache;
|
StandardCursorCache m_standardCursorCache;
|
||||||
PixmapCursorCache m_pixmapCursorCache;
|
PixmapCursorCache m_pixmapCursorCache;
|
||||||
|
|
||||||
|
mutable QPixmap m_copyDragCursor;
|
||||||
|
mutable QPixmap m_moveDragCursor;
|
||||||
|
mutable QPixmap m_linkDragCursor;
|
||||||
|
mutable QPixmap m_ignoreDragCursor;
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
@ -271,13 +271,6 @@ QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e)
|
|||||||
}
|
}
|
||||||
#endif // !QT_NO_DEBUG_STREAM
|
#endif // !QT_NO_DEBUG_STREAM
|
||||||
|
|
||||||
static qreal dragScaleFactor()
|
|
||||||
{
|
|
||||||
const QWindowsScreenManager &screenManager = QWindowsContext::instance()->screenManager();
|
|
||||||
const QWindowsScreen *screen = screenManager.screenAtDp(QWindowsCursor::mousePosition());
|
|
||||||
return screen ? QHighDpiScaling::factor(screen) : qreal(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Blend custom pixmap with cursors.
|
\brief Blend custom pixmap with cursors.
|
||||||
*/
|
*/
|
||||||
@ -288,7 +281,17 @@ void QWindowsOleDropSource::createCursors()
|
|||||||
const QPixmap pixmap = drag->pixmap();
|
const QPixmap pixmap = drag->pixmap();
|
||||||
const bool hasPixmap = !pixmap.isNull();
|
const bool hasPixmap = !pixmap.isNull();
|
||||||
|
|
||||||
const qreal scaleFactor = dragScaleFactor();
|
// Find screen for drag. Could be obtained from QDrag::source(), but that might be a QWidget.
|
||||||
|
|
||||||
|
qreal scaleFactor = 1;
|
||||||
|
QPlatformCursor *platformCursor = Q_NULLPTR;
|
||||||
|
if (const QPlatformScreen *platformScreen = QWindowsContext::instance()->screenManager().screenAtDp(QWindowsCursor::mousePosition())) {
|
||||||
|
scaleFactor = QHighDpiScaling::factor(platformScreen);
|
||||||
|
platformCursor = platformScreen->cursor();
|
||||||
|
}
|
||||||
|
if (!platformCursor && QGuiApplication::primaryScreen())
|
||||||
|
platformCursor = QGuiApplication::primaryScreen()->handle()->cursor();
|
||||||
|
|
||||||
const bool scalePixmap = hasPixmap
|
const bool scalePixmap = hasPixmap
|
||||||
&& m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.
|
&& m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.
|
||||||
&& (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio()));
|
&& (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio()));
|
||||||
@ -306,8 +309,8 @@ void QWindowsOleDropSource::createCursors()
|
|||||||
for (int cnum = 0; cnum < actionCount; ++cnum) {
|
for (int cnum = 0; cnum < actionCount; ++cnum) {
|
||||||
const Qt::DropAction action = actions[cnum];
|
const Qt::DropAction action = actions[cnum];
|
||||||
QPixmap cursorPixmap = drag->dragCursor(action);
|
QPixmap cursorPixmap = drag->dragCursor(action);
|
||||||
if (cursorPixmap.isNull())
|
if (cursorPixmap.isNull() && platformCursor)
|
||||||
cursorPixmap = m_drag->defaultCursor(action);
|
cursorPixmap = static_cast<QWindowsCursor *>(platformCursor)->dragDefaultCursor(action);
|
||||||
const qint64 cacheKey = cursorPixmap.cacheKey();
|
const qint64 cacheKey = cursorPixmap.cacheKey();
|
||||||
const ActionCursorMapIt it = m_cursors.find(action);
|
const ActionCursorMapIt it = m_cursors.find(action);
|
||||||
if (it != m_cursors.end() && it.value().cacheKey == cacheKey)
|
if (it != m_cursors.end() && it.value().cacheKey == cacheKey)
|
||||||
@ -704,94 +707,6 @@ IDropTargetHelper* QWindowsDrag::dropHelper() {
|
|||||||
return m_cachedDropTargetHelper;
|
return m_cachedDropTargetHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap QWindowsDrag::defaultCursor(Qt::DropAction action) const
|
|
||||||
{
|
|
||||||
switch (action) {
|
|
||||||
case Qt::CopyAction:
|
|
||||||
if (m_copyDragCursor.isNull())
|
|
||||||
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;
|
|
||||||
return m_moveDragCursor;
|
|
||||||
case Qt::LinkAction:
|
|
||||||
if (m_linkDragCursor.isNull())
|
|
||||||
m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor).pixmap;
|
|
||||||
return m_linkDragCursor;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char * const ignoreDragCursorXpmC[] = {
|
|
||||||
"24 30 3 1",
|
|
||||||
". c None",
|
|
||||||
"a c #000000",
|
|
||||||
"X c #FFFFFF",
|
|
||||||
"aa......................",
|
|
||||||
"aXa.....................",
|
|
||||||
"aXXa....................",
|
|
||||||
"aXXXa...................",
|
|
||||||
"aXXXXa..................",
|
|
||||||
"aXXXXXa.................",
|
|
||||||
"aXXXXXXa................",
|
|
||||||
"aXXXXXXXa...............",
|
|
||||||
"aXXXXXXXXa..............",
|
|
||||||
"aXXXXXXXXXa.............",
|
|
||||||
"aXXXXXXaaaa.............",
|
|
||||||
"aXXXaXXa................",
|
|
||||||
"aXXaaXXa................",
|
|
||||||
"aXa..aXXa...............",
|
|
||||||
"aa...aXXa...............",
|
|
||||||
"a.....aXXa..............",
|
|
||||||
"......aXXa.....XXXX.....",
|
|
||||||
".......aXXa..XXaaaaXX...",
|
|
||||||
".......aXXa.XaaaaaaaaX..",
|
|
||||||
"........aa.XaaaXXXXaaaX.",
|
|
||||||
"...........XaaaaX..XaaX.",
|
|
||||||
"..........XaaXaaaX..XaaX",
|
|
||||||
"..........XaaXXaaaX.XaaX",
|
|
||||||
"..........XaaX.XaaaXXaaX",
|
|
||||||
"..........XaaX..XaaaXaaX",
|
|
||||||
"...........XaaX..XaaaaX.",
|
|
||||||
"...........XaaaXXXXaaaX.",
|
|
||||||
"............XaaaaaaaaX..",
|
|
||||||
".............XXaaaaXX...",
|
|
||||||
"...............XXXX....."};
|
|
||||||
|
|
||||||
if (m_ignoreDragCursor.isNull()) {
|
|
||||||
#if !defined (Q_OS_WINCE)
|
|
||||||
HCURSOR cursor = LoadCursor(NULL, IDC_NO);
|
|
||||||
ICONINFO iconInfo = {0, 0, 0, 0, 0};
|
|
||||||
GetIconInfo(cursor, &iconInfo);
|
|
||||||
BITMAP bmColor = {0, 0, 0, 0, 0, 0, 0};
|
|
||||||
|
|
||||||
if (iconInfo.hbmColor
|
|
||||||
&& GetObject(iconInfo.hbmColor, sizeof(BITMAP), &bmColor)
|
|
||||||
&& bmColor.bmWidth == bmColor.bmWidthBytes / 4) {
|
|
||||||
const int colorBitsLength = bmColor.bmHeight * bmColor.bmWidthBytes;
|
|
||||||
uchar *colorBits = new uchar[colorBitsLength];
|
|
||||||
GetBitmapBits(iconInfo.hbmColor, colorBitsLength, colorBits);
|
|
||||||
const QImage colorImage(colorBits, bmColor.bmWidth, bmColor.bmHeight,
|
|
||||||
bmColor.bmWidthBytes, QImage::Format_ARGB32);
|
|
||||||
|
|
||||||
m_ignoreDragCursor = QPixmap::fromImage(colorImage);
|
|
||||||
delete [] colorBits;
|
|
||||||
} else {
|
|
||||||
m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
|
|
||||||
}
|
|
||||||
|
|
||||||
DeleteObject(iconInfo.hbmMask);
|
|
||||||
DeleteObject(iconInfo.hbmColor);
|
|
||||||
DestroyCursor(cursor);
|
|
||||||
#else // !Q_OS_WINCE
|
|
||||||
m_ignoreDragCursor = QPixmap(ignoreDragCursorXpmC);
|
|
||||||
#endif // !Q_OS_WINCE
|
|
||||||
}
|
|
||||||
return m_ignoreDragCursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
Qt::DropAction QWindowsDrag::drag(QDrag *drag)
|
Qt::DropAction QWindowsDrag::drag(QDrag *drag)
|
||||||
{
|
{
|
||||||
// TODO: Accessibility handling?
|
// TODO: Accessibility handling?
|
||||||
|
@ -42,6 +42,9 @@
|
|||||||
struct IDropTargetHelper;
|
struct IDropTargetHelper;
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class QPlatformScreen;
|
||||||
|
|
||||||
class QWindowsDropMimeData : public QWindowsInternalMimeData {
|
class QWindowsDropMimeData : public QWindowsInternalMimeData {
|
||||||
public:
|
public:
|
||||||
QWindowsDropMimeData() {}
|
QWindowsDropMimeData() {}
|
||||||
@ -95,18 +98,11 @@ public:
|
|||||||
|
|
||||||
IDropTargetHelper* dropHelper();
|
IDropTargetHelper* dropHelper();
|
||||||
|
|
||||||
QPixmap defaultCursor(Qt::DropAction action) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QWindowsDropMimeData m_dropData;
|
QWindowsDropMimeData m_dropData;
|
||||||
IDataObject *m_dropDataObject;
|
IDataObject *m_dropDataObject;
|
||||||
|
|
||||||
IDropTargetHelper* m_cachedDropTargetHelper;
|
IDropTargetHelper* m_cachedDropTargetHelper;
|
||||||
|
|
||||||
mutable QPixmap m_copyDragCursor;
|
|
||||||
mutable QPixmap m_moveDragCursor;
|
|
||||||
mutable QPixmap m_linkDragCursor;
|
|
||||||
mutable QPixmap m_ignoreDragCursor;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user