diff options
Diffstat (limited to 'xorg-server/dix')
-rw-r--r-- | xorg-server/dix/getevents.c | 20 | ||||
-rw-r--r-- | xorg-server/dix/touch.c | 4 |
2 files changed, 20 insertions, 4 deletions
diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c index 4cf06406d..d4badc03d 100644 --- a/xorg-server/dix/getevents.c +++ b/xorg-server/dix/getevents.c @@ -1198,7 +1198,6 @@ transform(struct pixman_f_transform *m, double *x, double *y) pixman_f_transform_point(m, &p); - *x = p.v[0]; *y = p.v[1]; } @@ -1348,6 +1347,7 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, RawDeviceEvent *raw; double screenx = 0.0, screeny = 0.0; /* desktop coordinate system */ double devx = 0.0, devy = 0.0; /* desktop-wide in device coords */ + int sx, sy; /* for POINTER_SCREEN */ ValuatorMask mask; ScreenPtr scr; @@ -1390,8 +1390,11 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, /* valuators are in driver-native format (rel or abs) */ if (flags & POINTER_ABSOLUTE) { - if (flags & POINTER_SCREEN) /* valuators are in screen coords */ + if (flags & POINTER_SCREEN) { /* valuators are in screen coords */ + sx = valuator_mask_get(&mask, 0); + sy = valuator_mask_get(&mask, 1); scale_from_screen(pDev, &mask); + } transformAbsolute(pDev, &mask); clipAbsolute(pDev, &mask); @@ -1409,6 +1412,19 @@ fill_pointer_events(InternalEvent *events, DeviceIntPtr pDev, int type, /* valuators are in device coordinate system in absolute coordinates */ scale_to_desktop(pDev, &mask, &devx, &devy, &screenx, &screeny); + + /* #53037 XWarpPointer's scaling back and forth between screen and + device may leave us with rounding errors. End result is that the + pointer doesn't end up on the pixel it should. + Avoid this by forcing screenx/screeny back to what the input + coordinates were. + */ + if (flags & POINTER_SCREEN) { + scr = miPointerGetScreen(pDev); + screenx = sx + scr->x; + screeny = sy + scr->y; + } + scr = positionSprite(pDev, (flags & POINTER_ABSOLUTE) ? Absolute : Relative, &mask, &devx, &devy, &screenx, &screeny); diff --git a/xorg-server/dix/touch.c b/xorg-server/dix/touch.c index e64a6262c..5f77be575 100644 --- a/xorg-server/dix/touch.c +++ b/xorg-server/dix/touch.c @@ -572,8 +572,8 @@ TouchBuildSprite(DeviceIntPtr sourcedev, TouchPointInfoPtr ti, return FALSE; /* Mark which grabs/event selections we're delivering to: max one grab per - * window plus the bottom-most event selection. */ - ti->listeners = calloc(sprite->spriteTraceGood + 1, sizeof(*ti->listeners)); + * window plus the bottom-most event selection, plus any active grab. */ + ti->listeners = calloc(sprite->spriteTraceGood + 2, sizeof(*ti->listeners)); if (!ti->listeners) { sprite->spriteTraceGood = 0; return FALSE; |