diff options
authorShawn Rutledge <>2019-12-20 15:41:32 +0100
committerShawn Rutledge <>2020-01-06 18:51:42 +0100
commit1535fc9fb9ddbfce1680979c0634b4fdf8d75fca (patch)
parent6005d1ca16026e03e9b4b65fe59a9b23f4cf9e01 (diff)
tablets on xcb: report correct local coordinates to nested windows
Change e4532224145a0a72cde9b40cb7fd39011624d1c1 tried to map global position directly from the desktop to the window that should receive the event. That's fine for single-window applications; but media players like OBS and VLC often use embedded windows to play video. So the mapping needs to traverse the window parent hierarchy somehow. In this patch it's done by calling QWindow::mapFromGlobal(), but that only works with integer coordinates (QPoint). To preserve the fix for QTBUG-48151 (and other jitter bugs), we need sub-pixel accuracy; so we have to add back the fractional part after mapping the int part. Fixes: QTBUG-77826 Change-Id: Ib52ce14138e477182e0ef53b0ff30ce1eff40372 Reviewed-by: Gatis Paeglis <>
1 files changed, 4 insertions, 2 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 4639185416..0a82bbc7a9 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -1252,14 +1252,16 @@ void QXcbConnection::xi2ReportTabletEvent(const void *event, TabletData *tabletD
if (Q_LIKELY(useValuators)) {
const qreal value = scaleOneValuator(normalizedValue, physicalScreenArea.x(), physicalScreenArea.width());
- local.setX(value - window->handle()->geometry().x());
+ // mapFromGlobal is ok for nested/embedded windows, but works only with whole-number QPoint;
+ // so map it first, then add back the sub-pixel position
+ local.setX(window->mapFromGlobal(QPoint(int(value), 0)).x() + (value - int(value)));
case QXcbAtom::AbsY:
if (Q_LIKELY(useValuators)) {
qreal value = scaleOneValuator(normalizedValue, physicalScreenArea.y(), physicalScreenArea.height());
- local.setY(value - window->handle()->geometry().y());
+ local.setY(window->mapFromGlobal(QPoint(0, int(value))).y() + (value - int(value)));
case QXcbAtom::AbsPressure: