Fix highdpi conversion of QTabletEvent coordinates on xcb

when high-dpi scaling is enabled, there was an offset
from the cursor position to the event position, because
QWindow::mapFromGlobal() works in device-independent
pixels, but we are using actual screen pixels here.

Task-number: QTBUG-77826
Backport from upstream:
    Change-Id: Ic8743b9e5c4041065f530ed1d9d6c49337b0207a
    Commit: 9d51fb579bb4655f6740096f17f1ced50258c28f
This commit is contained in:
Wei Wei 2023-05-24 10:58:09 +08:00 committed by 韩品龙
parent 2ac5249eb0
commit 815d6c2192
3 changed files with 12 additions and 4 deletions

View File

@ -266,6 +266,13 @@ QPoint QPlatformWindow::mapToGlobal(const QPoint &pos) const
return result; return result;
} }
QPointF QPlatformWindow::mapFromGlobalF(const QPointF &pos) const
{
const QPoint posPt = pos.toPoint();
const QPointF delta = pos - posPt;
return mapFromGlobal(posPt) + delta;
}
/*! /*!
Translates the global screen coordinate \a pos to window Translates the global screen coordinate \a pos to window
coordinates using native methods. This is required for embedded windows, coordinates using native methods. This is required for embedded windows,

View File

@ -114,6 +114,7 @@ public:
virtual bool isForeignWindow() const { return false; }; virtual bool isForeignWindow() const { return false; };
virtual QPoint mapToGlobal(const QPoint &pos) const; virtual QPoint mapToGlobal(const QPoint &pos) const;
virtual QPoint mapFromGlobal(const QPoint &pos) const; virtual QPoint mapFromGlobal(const QPoint &pos) const;
QPointF mapFromGlobalF(const QPointF &pos) const;
virtual void propagateSizeHints(); virtual void propagateSizeHints();

View File

@ -1270,16 +1270,16 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
if (Q_LIKELY(useValuators)) { if (Q_LIKELY(useValuators)) {
const qreal value = scaleOneValuator(normalizedValue, physicalScreenArea.x(), physicalScreenArea.width()); const qreal value = scaleOneValuator(normalizedValue, physicalScreenArea.x(), physicalScreenArea.width());
global.setX(value); global.setX(value);
// mapFromGlobal is ok for nested/embedded windows, but works only with whole-number QPoint; //! \note Fix QTBUG-77826
// so map it first, then add back the sub-pixel position local.setX(xcbWindow->mapFromGlobalF(global).x());
local.setX(window->mapFromGlobal(QPoint(int(value), 0)).x() + (value - int(value)));
} }
break; break;
case QXcbAtom::AbsY: case QXcbAtom::AbsY:
if (Q_LIKELY(useValuators)) { if (Q_LIKELY(useValuators)) {
qreal value = scaleOneValuator(normalizedValue, physicalScreenArea.y(), physicalScreenArea.height()); qreal value = scaleOneValuator(normalizedValue, physicalScreenArea.y(), physicalScreenArea.height());
global.setY(value); global.setY(value);
local.setY(window->mapFromGlobal(QPoint(0, int(value))).y() + (value - int(value))); //! \note Fix QTBUG-77826
local.setY(xcbWindow->mapFromGlobalF(global).y());
} }
break; break;
case QXcbAtom::AbsPressure: case QXcbAtom::AbsPressure: