| Summary: | cursor jumps upon edge activation | ||
|---|---|---|---|
| Product: | [Plasma] kwin | Reporter: | Michael Zanetti <mzanetti> |
| Component: | core | Assignee: | KWin default assignee <kwin-bugs-null> |
| Status: | RESOLVED NOT A BUG | ||
| Severity: | normal | Flags: | mgraesslin:
Wayland-
mgraesslin: X11+ |
| Priority: | NOR | ||
| Version First Reported In: | 5.10.5 | ||
| Target Milestone: | --- | ||
| Platform: | Other | ||
| OS: | Linux | ||
| Latest Commit: | Version Fixed/Implemented In: | ||
| Sentry Crash Report: | |||
|
Description
Michael Zanetti
2017-09-17 21:54:40 UTC
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. |