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());
|
||||
}
|
||||
|
||||
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
|
||||
\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 pixmapWindowCursor(const QCursor &c);
|
||||
|
||||
QPixmap dragDefaultCursor(Qt::DropAction action) const;
|
||||
|
||||
private:
|
||||
typedef QHash<Qt::CursorShape, CursorHandlePtr> StandardCursorCache;
|
||||
typedef QHash<QWindowsPixmapCursorCacheKey, CursorHandlePtr> PixmapCursorCache;
|
||||
@ -120,6 +122,11 @@ private:
|
||||
const QPlatformScreen *const m_screen;
|
||||
StandardCursorCache m_standardCursorCache;
|
||||
PixmapCursorCache m_pixmapCursorCache;
|
||||
|
||||
mutable QPixmap m_copyDragCursor;
|
||||
mutable QPixmap m_moveDragCursor;
|
||||
mutable QPixmap m_linkDragCursor;
|
||||
mutable QPixmap m_ignoreDragCursor;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -271,13 +271,6 @@ QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e)
|
||||
}
|
||||
#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.
|
||||
*/
|
||||
@ -288,7 +281,17 @@ void QWindowsOleDropSource::createCursors()
|
||||
const QPixmap pixmap = drag->pixmap();
|
||||
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
|
||||
&& m_mode != TouchDrag // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.
|
||||
&& (scaleFactor != 1 && scaleFactor != qRound(pixmap.devicePixelRatio()));
|
||||
@ -306,8 +309,8 @@ void QWindowsOleDropSource::createCursors()
|
||||
for (int cnum = 0; cnum < actionCount; ++cnum) {
|
||||
const Qt::DropAction action = actions[cnum];
|
||||
QPixmap cursorPixmap = drag->dragCursor(action);
|
||||
if (cursorPixmap.isNull())
|
||||
cursorPixmap = m_drag->defaultCursor(action);
|
||||
if (cursorPixmap.isNull() && platformCursor)
|
||||
cursorPixmap = static_cast<QWindowsCursor *>(platformCursor)->dragDefaultCursor(action);
|
||||
const qint64 cacheKey = cursorPixmap.cacheKey();
|
||||
const ActionCursorMapIt it = m_cursors.find(action);
|
||||
if (it != m_cursors.end() && it.value().cacheKey == cacheKey)
|
||||
@ -704,94 +707,6 @@ IDropTargetHelper* QWindowsDrag::dropHelper() {
|
||||
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)
|
||||
{
|
||||
// TODO: Accessibility handling?
|
||||
|
@ -42,6 +42,9 @@
|
||||
struct IDropTargetHelper;
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QPlatformScreen;
|
||||
|
||||
class QWindowsDropMimeData : public QWindowsInternalMimeData {
|
||||
public:
|
||||
QWindowsDropMimeData() {}
|
||||
@ -95,18 +98,11 @@ public:
|
||||
|
||||
IDropTargetHelper* dropHelper();
|
||||
|
||||
QPixmap defaultCursor(Qt::DropAction action) const;
|
||||
|
||||
private:
|
||||
QWindowsDropMimeData m_dropData;
|
||||
IDataObject *m_dropDataObject;
|
||||
|
||||
IDropTargetHelper* m_cachedDropTargetHelper;
|
||||
|
||||
mutable QPixmap m_copyDragCursor;
|
||||
mutable QPixmap m_moveDragCursor;
|
||||
mutable QPixmap m_linkDragCursor;
|
||||
mutable QPixmap m_ignoreDragCursor;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
Loading…
x
Reference in New Issue
Block a user