Created attachment 172939 [details] Screenshot of an incorrect mouse cursor hovering over a text entry while zoomed in. SUMMARY When zoomed into the screen with kwin's zoom effect under Wayland, the mouse cursor doesn't properly change to reflect what you're hovering over. STEPS TO REPRODUCE 1. Zoom into the screen 2. Open a non-KDE application (like Chromium, Firefox, Rider, etc.) 3. Hover over a text input field. OBSERVED RESULT The mouse cursor doesn't always change to the "I-Beam" cursor. It instead stays as a regular pointing arrow, or whatever cursor it was previously. EXPECTED RESULT Hovering over a text entry box should result in the cursor changing to a text entry (I-Beam) cursor. SOFTWARE/OS VERSIONS Linux/KDE Plasma: Arch Linux / Plasma 6.1.4 KDE Frameworks Version: 6.5.0 Qt Version: 6.7.2 ADDITIONAL INFORMATION This does not seem to affect KDE applications such as Konsole. Moving the cursor outside of any application (onto a panel/the desktop) causes a cursor update, meaning it doesn't affect plasma-shell. Zooming out with the reset zoom keybinding (meta+0) sometimes causes a cursor refresh. Zooming out with the regular zoom out binding (meta+hyphen) does not. I've filed this under effects-generic due to there not being a dedicated accessibility or zoom category, however I consider this a severe a11y issue due to the fact it also makes it very difficult for me to find resize/drag handles on windows/application panels (like resizing the file tree in an IDE). Attached is an image of me editing this bug report, and my cursor hovering over the text entry. The cursor is a pointer cursor despite there being a text entry below it.
I could reproduce the issue a few days ago, but not today. I didn't update any related package or reboot between the successful reproduction earlier and the unsuccessful one today. I have no idea what changed. OS: NixOS unstable KDE Plasma 6.1.3, using Wayland
update: I could reproduce it with Discord (Armcord flatpak) and Jetbrains Toolbox, but not Firefox, Dolphin, Falkon, Thunderbird or qBittorrent. NixOS wrappers may have something to do with Firefox and Thunderbird working as expected.
I've just tested with Firefox, it is unaffected. I can't figure out my way around Bugzilla enough to edit my original post to remove Firefox from the list of example apps to test.
AFter further testing in my Discord community, we have discovered that this seems to consistently affect apps running under Xwayland. You can reproduce the bug in KDE applications by forcing them to run under Xwayland, i.e: QT_QPA_PLATFORM=xcb konsole to run Konsole under Xwayland.
I've been informed that certain Electron apps, like Webcord, don't use Wayland by default and instead use Xwayland. You can force them to use Wayland by editing ~/.config/electron-flags.conf. This works around the cursor bug for me when using Webcord. In electron-flags.conf: --ozone-platform-hint=auto Then restart any open Electron apps.
Can reproduce.
I have seen the same issue in straight X11, typically in gnome/GTK applications. Another side effect of similar nature is that sometimes the mouse cursor will not be drawn on top of the highest z-order window when zoom is active with scale cursor selected. Easiest to reproduce is gnome-sudoku where the windows that popup up to enter numbers using the mouse will hide the scaled cursor when zoomed in. It doesn't happen always, and sometimes killing and kstarting plasmashell will make it work for a while. I have not figured out what triggers it to start failing. Not certain it's the same bug it seemed close enough to report it here rather than open a new one.
First time looking at this bug *as a programmer*, and here's what I've found so far. The zoom effect generally hides the true mouse cursor and takes control over rendering it, so that the cursor can do things like scale based on zoom level. Great. It only does this when the zoom level is other than 1.0 (so, when you're zoomed in). Otherwise it just lets kwin normally render the mouse cursor. When zoom is in charge of rendering the cursor, there's texture caching going on here. This code, although I don't fully understand it yet because my debugger is being really annoying about breakpoints, seems to be what's responsible for refreshing zoom's cursor texture when the cache becomes invalid. Usually it gets called when the cursor shape or theme changes. <code> GLTexture *ZoomEffect::ensureCursorTexture() { if (!m_cursorTexture || m_cursorTextureDirty) { m_cursorTexture.reset(); m_cursorTextureDirty = false; const auto cursor = effects->cursorImage(); if (!cursor.image().isNull()) { m_cursorTexture = GLTexture::upload(cursor.image()); if (!m_cursorTexture) { return nullptr; } m_cursorTexture->setWrapMode(GL_CLAMP_TO_EDGE); } } return m_cursorTexture.get(); } </code> What I've noticed in some limited debugging is that the body of the `if` statement just never executes when testing the Xwayland case. I have a code editor open running under xwayland in a nested Kwin session, and moving the mouse between the code editor and file tree never causes the cursor to change between an I-Beam and arrow. That code also never gets called. If zoomed out, the cursor does change properly between arrow/I-Beam, but the moment I zoom in, this stops working properly. Which makes sense, knowing zoom only takes over cursor rendering when you actually zoom into the screen. So that's where I'm at. This is definitely specific to just the zoom app and Xwayland windows. Normal Wayland ones work fine.
I've investigated further. Kwin has two cursor sources, ShapeCursorSource and SurfaceCursorSource. ShapeCursorSource is backed by the Wayland cursor shape protocol, SurfaceCursorSource is backed by a Wayland surface. When a ShapeCursorSource is active, everything works fine. This explains why I can see the cursor changing while using most Wayland clients on my system; they're using Cursor Shape Protocol. I've been wondering why this bug affects my game engine, despite it having Wayland support through SDL, and this may explain that. It turns out that, after some really painful testing, SurfaceCursorSource seems to only emit its "changed" signal when zoomed out. Likely because the server cursor isn't marked as hidden, though I haven't gotten that far. I haven't figured out what triggers the cursor refresh, only that the Wayland surface never gets committed while you're zoomed in and hovering between UI elements in a window. I no longer believe this is specific to Xwayland, I'll rename the bug.
That explains the bug... We send frame callbacks for the cursor surface in the Compositor, instead of the scene like with all other surfaces. The compositor has a check for Cursors::self()->isCursorHidden(), so hiding the cursor in the effect means it doesn't get frame callbacks anymore, which means the app never updates it.
A possibly relevant merge request was started @ https://invent.kde.org/plasma/kwin/-/merge_requests/7499
A possibly relevant merge request was started @ https://invent.kde.org/plasma/kwin/-/merge_requests/7510