Windows QPA: Fix drag cursor and hotspot for pixmaps with DPR.
Introduce separate scale factors for hot spot and pixmap and set the devicePixelRatio of the scaled pixmap to 1 matching that of the target pixmap which will be converted to a Windows cursor. Change-Id: I0b0f6c6a79589ec954b5a1a09a86b87c91b5147d Task-number: QTBUG-46068 Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com> Reviewed-by: Alexandru Croitor <alexandru.croitor@theqtcompany.com> Reviewed-by: Morten Johan Sørvig <morten.sorvig@theqtcompany.com>
This commit is contained in:
parent
3cd69671db
commit
50489f2e41
@ -282,30 +282,33 @@ void QWindowsOleDropSource::createCursors()
|
||||
const bool hasPixmap = !pixmap.isNull();
|
||||
|
||||
// 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();
|
||||
const QPlatformScreen *platformScreen = QWindowsContext::instance()->screenManager().screenAtDp(QWindowsCursor::mousePosition());
|
||||
if (!platformScreen) {
|
||||
if (const QScreen *primaryScreen = QGuiApplication::primaryScreen())
|
||||
platformScreen = primaryScreen->handle();
|
||||
}
|
||||
if (!platformCursor && QGuiApplication::primaryScreen())
|
||||
platformCursor = QGuiApplication::primaryScreen()->handle()->cursor();
|
||||
Q_ASSERT(platformScreen);
|
||||
QPlatformCursor *platformCursor = platformScreen->cursor();
|
||||
|
||||
qreal pixmapScaleFactor = 1;
|
||||
qreal hotSpotScaleFactor = 1;
|
||||
if (m_mode != TouchDrag) { // Touch drag: pixmap is shown in a separate QWindow, which will be scaled.)
|
||||
hotSpotScaleFactor = QHighDpiScaling::factor(platformScreen);
|
||||
pixmapScaleFactor = hotSpotScaleFactor / pixmap.devicePixelRatio();
|
||||
}
|
||||
QPixmap scaledPixmap = qFuzzyCompare(pixmapScaleFactor, 1.0)
|
||||
? pixmap
|
||||
: pixmap.scaled((QSizeF(pixmap.size()) * pixmapScaleFactor).toSize(),
|
||||
Qt::KeepAspectRatio, Qt::SmoothTransformation);
|
||||
scaledPixmap.setDevicePixelRatio(1);
|
||||
|
||||
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()));
|
||||
const QPixmap scaledPixmap = scalePixmap
|
||||
? pixmap.scaled((QSizeF(pixmap.size()) * scaleFactor).toSize(),
|
||||
Qt::KeepAspectRatio, Qt::SmoothTransformation)
|
||||
: pixmap;
|
||||
Qt::DropAction actions[] = { Qt::MoveAction, Qt::CopyAction, Qt::LinkAction, Qt::IgnoreAction };
|
||||
int actionCount = int(sizeof(actions) / sizeof(actions[0]));
|
||||
if (!hasPixmap)
|
||||
--actionCount; // No Qt::IgnoreAction unless pixmap
|
||||
const QPoint hotSpot = scalePixmap
|
||||
? (QPointF(drag->hotSpot()) * scaleFactor).toPoint()
|
||||
: drag->hotSpot();
|
||||
const QPoint hotSpot = qFuzzyCompare(hotSpotScaleFactor, 1.0)
|
||||
? drag->hotSpot()
|
||||
: (QPointF(drag->hotSpot()) * hotSpotScaleFactor).toPoint();
|
||||
for (int cnum = 0; cnum < actionCount; ++cnum) {
|
||||
const Qt::DropAction action = actions[cnum];
|
||||
QPixmap cursorPixmap = drag->dragCursor(action);
|
||||
|
Loading…
Reference in New Issue
Block a user