So I'm using libinput as touchpad driver on a new MacBook Pro and because the touchpad is so huge with high resolution, the cursor moves really slow and systemsetting's mouse module doesn't support changing the cursor speed for libinput. So I'm using this to double the mouse cursor speed: xinput set-prop 12 142 2.000000, 0.000000, 0.000000, 0.000000, 2.000000, 0.000000, 0.000000, 0.000000, 1.000000 That works fine, except for this bug: when revealing an autohiding panel with the mouse, the cursor jumps for half a screen width/height along the edge (depending whether the panel is on the side or bottom). As example, revealing an autohiding panel on the left screen edge by hitting the center of the left edge, as soon as the panel appears, the cursor jumps to the lower left corner of the screen.
I don't see a reason why KWin should be responsible for that. It does a push back, but only one pixel to the right.
Hi Martin, I'm not 100% sure either if it's really kwin... Maybe it's the panel? But perhaps it's something in that 1 pixel push back that break it? like, if it does setCursorPosition(x, y) trying to correct one of them by 1 (depending on the edge) but there's some issue in the calculation of the new x/y values? I'm just guessing here... For all I know is that it only happens on edges where that have an autohide panel and if libinput's properties are set to translate the cursor matrix.
The relevant code in KWin is: void Edge::pushCursorBack(const QPoint &cursorPos) { if (m_pushBackBlocked) return; int x = cursorPos.x(); int y = cursorPos.y(); const QSize &distance = edges()->cursorPushBackDistance(); if (isLeft()) { x += distance.width(); } if (isRight()) { x -= distance.width(); } if (isTop()) { y += distance.height(); } if (isBottom()) { y -= distance.height(); } Cursor::setPos(x, y); } This has worked for years and I'm quite certain it is not broken ;-) What I could imagine is that cursor warping does not work in general due to the xinput property you set. We just use xcb_warp_pointer on the rootWindow. You could try using a dummy implementation to check whether warping works.
Hey, so, I've edited screenedge.cpp and commented out the pushback of the cursor, and indeed the issue is gone (obviously at the cost that the one pixel pushback doesn't work any more either). I also tried to add debug prints for the cursor position when it hits the edge and those seem to be correct. Which leads me to believe that the issue must be somewhere on the path of of Cursor::setPos(). Not saying it's necessarily in kwin itself, but at least it seems to happen when writing the position, and not when reading it. I tried to follow the path but I got lost. All the connections to Cursor::posChanged don't seem to actually set the cursor (except in the software cursor case which doesn't seem to be case here, at least I couldn't see the m_softwareCursor path in platform.cpp being triggered) and the drm/x11standalone backends don't actually seem to trigger any cursor position updates, but rather only use that information for the edge glow and such. Hope this helps, not sure where to go from here atm. Br, Michael
Cursor::setPos is finally implemented in the X11Cursor::doSetPos (file plugins/platforms/x11/standalone/x11cursor.cpp line60) void X11Cursor::doSetPos() { const QPoint &pos = currentPos(); xcb_warp_pointer(connection(), XCB_WINDOW_NONE, rootWindow(), 0, 0, 0, 0, pos.x(), pos.y()); // call default implementation to emit signal Cursor::doSetPos(); } As written in the last comment my guess is that xcb_warp_pointer just creates an incorrect warp in your case.
Assuming it's a problem in xinput and not in KWin.