https://bugs.kde.org/show_bug.cgi?id=527273
Grief <[email protected]> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |[email protected] --- Comment #1 from Grief <[email protected]> --- I hit the same regression on 6.8.0 (NVIDIA RTX 5080, Wayland, scale 2.25, cursor size 83, cursor theme "hand-of-evil") and traced it in the source. Root cause: commit 0e4fd91b "compositor: make cursor repaints smoother" (fix for bug 509669). Before it, the lambda connected to OutputLayer::repaintScheduled in Compositor::setupLayers bailed out when cursorView->needsRepaint() was true and left re-rendering of the cursor image to composite(). Now it renders the cursor layer synchronously, directly from the signal (prepareRendering + renderLayer + presentAsync). The problem is that CursorItem::setImage() updates the item in three separate steps: m_imageItem->setImage(image); // 1 m_imageItem->setPosition(-hotspot); // 2 m_imageItem->setSize(image.size() / image.devicePixelRatio()); // 3 Step 1 calls discardQuads() + scheduleRepaint(), which emits repaintScheduled synchronously, so the layer is rendered right there: new texture, but the item still has the OLD size (and old hotspot). Quads are rebuilt from the old boundingRect. Step 3 (Item::setSize) calls scheduleRepaint(rect()) twice and only then discardQuads(); the second scheduleRepaint again renders synchronously, still with the cached quads from step 1, i.e. the old geometry. After that nothing triggers another render: cursor movement only moves the plane (canSkipMoveRepaint). Result: the new image is stretched to the dimensions of the previous image until the image changes again. For animated shapes every frame is drawn with the previous frame's size. That is why it only shows with themes whose shapes have different image sizes. KDE Classic: left_ptr is 10x16, fleur/size_* are 16x16, so after a drag the arrow is stretched to 16x16 ("very wide"). hand-of-evil: arrow 166x78, pointing hand 166x90 with animation frames 166..176 wide, so the hand is visibly squeezed horizontally while hovering links and the arrow is stretched vertically after leaving them. Breeze is unaffected because all images are 32x32. It is invisible in screenshots/videos because it only affects the hardware cursor plane buffer. Workarounds: KWIN_FORCE_SW_CURSOR=1 (software cursor is rendered in composite(), after all three setters ran), or a theme where all images have identical dimensions (padding all images of my theme to a common canvas fixed it for me). Possible fixes: apply size and position before setImage() in CursorItem::setImage() (then the last synchronous render sees the final geometry), or better, don't render from inside the repaintScheduled handler while the item is mid-update, e.g. defer the render to the event loop / compositing cycle. -- You are receiving this mail because: You are watching all bug changes.
