SUMMARY Whenever I log onto a Wayland session, hovering over links results in the mouse cursor switching to the appropriate state, but while it does so, it briefly moves to the side of where the cursor should actually be, before returning to the correct position. This happens on both XWayland and Wayland applications, Qt and GTK. I have tried to change compositor settings, but they don't seem to help. I'm not using fractional scaling. This isn't my video, but it looks exactly like this: https://www.youtube.com/watch?v=wCyTrt3TrAw STEPS TO REPRODUCE 1. Switch to a Wayland session. 2. Use your mouse to hover over a link or anything else that changes the state of the cursor. 3. Upon hovering over it, or moving the cursor away, it changes to the appropriate state, but it does not transition smoothly. It moves to the size for a brief second and returns to the correct position. OBSERVED RESULT Upon switching states, it jumps to the side for a small amount of time, then switches to the correct state in the correct position. EXPECTED RESULT It should switch states without moving to the side or glitching. SOFTWARE/OS VERSIONS Linux/KDE Plasma: openSUSE Tumbleweed 20211228 snapshot. (available in About System) KDE Plasma Version: 5.23.4 KDE Frameworks Version: 5.89.0 Qt Version: 5.15.2 ADDITIONAL INFORMATION The same issue also happens on other distributions, themes (including the default Breeze theme, cursor and otherwise), but only on Wayland, not on xorg. None of the compositor settings solve or help reduce the issue. On RX 580 4gb.
I launched kwin_wayland with --exit-with-session konsole as well as with the WAYLAND_DEBUG=1 environment variable. This is the output (a bit trimmed). I tried to reproduce the issue (and successfully so!) by causing the cursor state to change. [195565,571] wl_callback@31.done(322477) [195565,580] -> wl_buffer@36.destroy() [195565,771] -> wl_buffer@38.release() [195566,248] -> wl_surface@13.frame(new id wl_callback@31) [195566,260] -> wl_surface@13.set_buffer_scale(1) [195566,272] -> wl_surface@13.frame(new id wl_callback@34) [195566,304] -> zwp_linux_dmabuf_v1@25.create_params(new id zwp_linux_buffer_params_v1@35) [195566,315] -> zwp_linux_buffer_params_v1@35.add(fd 39, 0, 0, 4096, 16777215, 4294967295) [195566,331] -> zwp_linux_buffer_params_v1@35.create_immed(new id wl_buffer@33, 1024, 768, 808669784, 0) [195566,345] -> zwp_linux_buffer_params_v1@35.destroy() [195566,348] -> wl_surface@13.attach(wl_buffer@33, 0, 0) [195566,356] -> wl_surface@13.damage_buffer(210, 100, 616, 1) [195566,364] -> wl_surface@13.damage_buffer(209, 101, 618, 113) [195566,372] -> wl_surface@13.damage_buffer(209, 214, 637, 444) [195566,383] -> wl_surface@13.damage_buffer(209, 658, 618, 20) [195566,391] -> wl_surface@13.damage_buffer(210, 678, 616, 1) [195566,408] -> wl_surface@13.commit() [195566,515] -> wl_callback@44.done(322478) [195566,529] -> wl_display@1.delete_id(44) [195566,593] wl_display@1.delete_id(44) [195566,607] wl_buffer@38.release() [195566,611] wl_callback@44.done(322478) [195575,763] wl_display@1.delete_id(36) [195575,778] wl_display@1.delete_id(35) [195575,811] wl_pointer@19.motion(322489, 693,000000, 658,000000) [195577,254] wl_display@1.delete_id(31) [195577,264] wl_display@1.delete_id(34) [195577,279] wl_callback@31.done(322490) [195578,328] wl_buffer@29.release() [195578,334] wl_callback@34.done(322490) [195578,339] -> wl_buffer@29.destroy() [195578,605] -> wl_surface@13.frame(new id wl_callback@34) [195578,615] -> wl_surface@13.set_buffer_scale(1) [195578,624] -> wl_surface@13.frame(new id wl_callback@31) [195578,647] -> zwp_linux_dmabuf_v1@25.create_params(new id zwp_linux_buffer_params_v1@35) [195578,656] -> zwp_linux_buffer_params_v1@35.add(fd 39, 0, 0, 4096, 16777215, 4294967295) [195578,669] -> zwp_linux_buffer_params_v1@35.create_immed(new id wl_buffer@36, 1024, 768, 808669784, 0) [195578,679] -> zwp_linux_buffer_params_v1@35.destroy() [195578,683] -> wl_surface@13.attach(wl_buffer@36, 0, 0) [195578,690] -> wl_surface@13.damage_buffer(210, 100, 616, 1) [195578,698] -> wl_surface@13.damage_buffer(209, 101, 618, 577) [195578,705] -> wl_surface@13.damage_buffer(210, 678, 616, 1) [195578,716] -> wl_surface@13.commit() [195582,664] wl_display@1.delete_id(29) [195582,673] wl_display@1.delete_id(35) [195582,690] wl_pointer@19.motion(322496, 693,000000, 659,000000) [195590,602] wl_display@1.delete_id(34) [195590,612] wl_display@1.delete_id(31) [195590,631] wl_callback@34.done(322504) [195615,851] wl_pointer@19.motion(322529, 692,000000, 659,000000) [195710,824] wl_pointer@19.motion(322624, 692,000000, 660,000000) [195717,713] wl_pointer@19.motion(322631, 691,000000, 660,000000) [195788,945] wl_pointer@19.motion(322702, 690,000000, 660,000000) [195806,836] wl_pointer@19.motion(322720, 690,000000, 661,000000) [195832,803] wl_pointer@19.motion(322746, 689,000000, 661,000000) [195869,849] wl_pointer@19.motion(322783, 689,000000, 662,000000) [195881,871] wl_pointer@19.motion(322795, 688,000000, 662,000000) [195911,724] wl_pointer@19.motion(322825, 687,000000, 662,000000) [195912,634] wl_pointer@19.motion(322826, 687,000000, 663,000000) [195938,100] wl_pointer@19.motion(322851, 686,000000, 663,000000) [195947,736] wl_pointer@19.motion(322861, 686,000000, 664,000000) [195986,798] wl_pointer@19.motion(322900, 685,000000, 664,000000) [196013,993] wl_pointer@19.motion(322927, 685,000000, 665,000000) [196074,856] wl_pointer@19.motion(322988, 684,000000, 665,000000) [196082,714] wl_pointer@19.motion(322996, 684,000000, 666,000000) [196118,766] wl_pointer@19.motion(323032, 683,000000, 666,000000) [196119,666] wl_pointer@19.motion(323033, 683,000000, 667,000000) [196147,847] wl_pointer@19.motion(323061, 683,000000, 668,000000) [196147,917] -> wl_pointer@19.set_cursor(1531, wl_surface@18, 4, 4) [196147,929] -> wl_surface@18.attach(wl_buffer@28, 0, 0) [196147,938] -> wl_surface@18.set_buffer_scale(1) [196147,943] -> wl_surface@18.damage_buffer(0, 0, 32, 32) [196147,951] -> wl_surface@18.commit() [196148,404] wl_buffer@23.release() [196151,808] wl_pointer@19.motion(323065, 682,000000, 668,000000) [196188,891] wl_pointer@19.motion(323102, 682,000000, 669,000000) [196201,795] wl_pointer@19.motion(323115, 681,000000, 669,000000) [196218,771] wl_pointer@19.motion(323132, 681,000000, 670,000000) [196763,852] wl_pointer@19.motion(323677, 680,000000, 670,000000) [196830,800] wl_pointer@19.motion(323744, 679,000000, 670,000000) [196877,824] wl_pointer@19.motion(323791, 678,000000, 670,000000) [196906,786] wl_pointer@19.motion(323820, 678,000000, 669,000000) [196939,848] wl_pointer@19.motion(323853, 678,000000, 668,000000) [196987,820] wl_pointer@19.motion(323901, 678,000000, 667,000000) [196987,896] -> wl_pointer@19.set_cursor(1531, wl_surface@18, 16, 16) [196987,906] -> wl_surface@18.attach(wl_buffer@23, 0, 0) [196987,913] -> wl_surface@18.set_buffer_scale(1) [196987,918] -> wl_surface@18.damage_buffer(0, 0, 32, 32) [196987,926] -> wl_surface@18.commit() [196988,396] wl_buffer@28.release() [197024,801] wl_pointer@19.motion(323938, 677,000000, 667,000000) [197926,829] wl_pointer@19.motion(324840, 677,000000, 668,000000) [197926,913] -> wl_pointer@19.set_cursor(1531, wl_surface@18, 4, 4) [197926,928] -> wl_surface@18.attach(wl_buffer@28, 0, 0) [197926,938] -> wl_surface@18.set_buffer_scale(1) [197926,943] -> wl_surface@18.damage_buffer(0, 0, 32, 32) [197926,954] -> wl_surface@18.commit() [197927,454] wl_buffer@23.release() [197975,865] wl_pointer@19.motion(324889, 677,000000, 669,000000) [198000,770] wl_pointer@19.motion(324914, 676,000000, 669,000000) [198066,872] wl_pointer@19.motion(324980, 676,000000, 670,000000) [199555,927] wl_pointer@19.motion(326469, 675,000000, 670,000000) [199698,790] wl_pointer@19.motion(326612, 674,000000, 670,000000) [199717,841] wl_pointer@19.motion(326631, 674,000000, 669,000000) [199754,812] wl_pointer@19.motion(326668, 673,000000, 669,000000) [199784,765] wl_pointer@19.motion(326698, 672,000000, 669,000000) [199785,725] wl_pointer@19.motion(326699, 672,000000, 668,000000) [199806,933] wl_pointer@19.motion(326720, 671,000000, 668,000000) [199827,842] wl_pointer@19.motion(326741, 671,000000, 667,000000) [199827,951] -> wl_pointer@19.set_cursor(1531, wl_surface@18, 16, 16) [199827,976] -> wl_surface@18.attach(wl_buffer@23, 0, 0) [199827,995] -> wl_surface@18.set_buffer_scale(1) [199828,003] -> wl_surface@18.damage_buffer(0, 0, 32, 32) [199828,022] -> wl_surface@18.commit() [199828,578] wl_buffer@28.release() [199828,712] wl_pointer@19.motion(326742, 670,000000, 667,000000) [199856,834] wl_pointer@19.motion(326770, 669,000000, 667,000000) [199870,218] wl_pointer@19.motion(326783, 669,000000, 666,000000) [199886,839] wl_pointer@19.motion(326800, 668,000000, 666,000000) [199944,903] wl_pointer@19.motion(326858, 667,000000, 666,000000) [199950,777] wl_pointer@19.motion(326864, 667,000000, 665,000000) [200009,841] wl_pointer@19.motion(326923, 666,000000, 665,000000) [200101,789] wl_pointer@19.motion(327015, 665,000000, 665,000000) [200121,814] wl_pointer@19.motion(327035, 665,000000, 664,000000) [200137,836] wl_pointer@19.motion(327051, 664,000000, 664,000000) [200154,786] wl_pointer@19.motion(327068, 664,000000, 663,000000) [200173,868] wl_pointer@19.motion(327087, 663,000000, 663,000000) [200190,038] wl_pointer@19.motion(327103, 663,000000, 662,000000) [200214,788] wl_pointer@19.motion(327128, 662,000000, 662,000000) [200235,772] wl_pointer@19.motion(327149, 662,000000, 661,000000) [200282,862] wl_pointer@19.motion(327196, 661,000000, 661,000000) [200292,801] wl_pointer@19.motion(327206, 661,000000, 660,000000) [200374,881] wl_pointer@19.motion(327288, 661,000000, 659,000000) [200375,758] wl_pointer@19.motion(327289, 660,000000, 659,000000) [200435,871] wl_pointer@19.motion(327349, 660,000000, 658,000000) [200442,802] wl_pointer@19.motion(327356, 659,000000, 658,000000) [200480,815] wl_pointer@19.motion(327394, 659,000000, 657,000000) [200480,882] -> wl_pointer@19.set_cursor(1531, wl_surface@18, 4, 4) [200480,892] -> wl_surface@18.attach(wl_buffer@28, 0, 0) [200480,900] -> wl_surface@18.set_buffer_scale(1) [200480,904] -> wl_surface@18.damage_buffer(0, 0, 32, 32) [200480,912] -> wl_surface@18.commit() [200480,933] -> wl_pointer@20.enter(141, wl_surface@23, 482,000000, 519,000000) [200480,946] -> wl_pointer@20.frame() [200481,028] wl_pointer@20.enter(141, wl_surface@23, 482,000000, 519,000000) [200481,090] -> wl_pointer@20.set_cursor(141, wl_surface@39, 4, 4) [200481,122] -> wl_surface@39.set_buffer_scale(1) [200481,135] -> wl_surface@39.attach(wl_buffer@36, 0, 0) [200481,160] -> wl_surface@39.damage(0, 0, 32, 32) [200481,189] -> wl_surface@39.commit() [200481,205] wl_pointer@20.frame() [200481,254] wl_pointer@20.set_cursor(141, wl_surface@39, 4, 4) [200481,275] -> wl_pointer@19.set_cursor(1531, wl_surface@18, 0, 0) [200481,286] -> wl_surface@18.attach(nil, 0, 0) [200481,294] -> wl_surface@18.set_buffer_scale(1) [200481,299] -> wl_surface@18.damage_buffer(0, 0, -1, -1) [200481,310] -> wl_surface@18.commit() [200481,322] -> wl_pointer@20.set_cursor([200481,330] -> wl_pointer@19.set_cursor(1411531, , wl_surface@18, wl_surface@394, , 4) 16[200481,347] -> wl_surface@18.attach(, wl_buffer@30, 160) , 0) [200481,361] -> wl_surface@18.set_buffer_scale([200481,360] -> wl_surface@39.set_buffer_scale(1) 1[200481,369] -> wl_surface@18.damage_buffer() 0, 0[200481,375] -> wl_surface@39.attach(, 32wl_buffer@43, , 320) , 0[200481,397] -> wl_surface@18.commit() ) [200481,403] -> wl_surface@39.damage(0[200481,411] wl_surface@39.set_buffer_scale(, 10) , [200481,419] wl_surface@39.attach(32wl_buffer@36, , 032, 0) ) [200481,435] wl_surface@39.damage(0[200481,434] -> wl_surface@39.commit(, 0) , 32, 32) [200481,450] wl_surface@39.commit() [200481,462] -> wl_pointer@19.set_cursor(1531, wl_surface@18, 4, 4) [200481,474] -> wl_surface@18.attach(wl_buffer@26, 0, 0) [200481,483] -> wl_surface@18.set_buffer_scale(1) [200481,487] -> wl_surface@18.damage_buffer(0, 0, 32, 32) [200481,496] -> wl_surface@18.commit() [200481,507] wl_buffer@23.release() [200481,519] wl_pointer@20.set_cursor(141, wl_surface@39, 16, 16) [200481,534] -> wl_pointer@19.set_cursor(1531, wl_surface@18, 16, 16) [200481,548] -> wl_surface@18.attach(wl_buffer@23, 0, 0) [200481,558] -> wl_surface@18.set_buffer_scale(1) [200481,564] -> wl_surface@18.damage_buffer(0, 0, 32, 32) [200481,575] -> wl_surface@18.commit() [200481,584] wl_surface@39.set_buffer_scale(1) [200481,590] wl_surface@39.attach(wl_buffer@43, 0, 0) [200481,601] wl_surface@39.damage(0, 0, 32, 32) [200481,613] wl_surface@39.commit() [200481,619] -> wl_buffer@36.release() [200481,630] -> wl_pointer@19.set_cursor(1531, wl_surface@18, 16, 16) [200481,645] -> wl_surface@18.attach(wl_buffer@32, 0, 0) [200481,662] -> wl_surface@18.set_buffer_scale(1) [200481,668] -> wl_surface@18.damage_buffer(0, 0, 32, 32) [200481,677] -> wl_surface@18.commit() [200481,690] wl_buffer@28.release() [200482,391] wl_buffer@30.release() [200482,410] wl_buffer@26.release() [200482,562] wl_buffer@23.release() [200494,829] wl_pointer@19.motion(327408, 658,000000, 657,000000) [200545,842] wl_pointer@19.motion(327459, 658,000000, 656,000000) [200551,753] wl_pointer@19.motion(327465, 657,000000, 656,000000) [200600,771] wl_pointer@19.motion(327514, 657,000000, 655,000000) [200610,727] wl_pointer@19.motion(327524, 656,000000, 655,000000) [200636,778] wl_pointer@19.motion(327550, 656,000000, 654,000000) [200657,873] wl_pointer@19.motion(327571, 655,000000, 654,000000) [200695,797] wl_pointer@19.motion(327609, 655,000000, 653,000000) [200968,763] wl_pointer@19.motion(327882, 655,000000, 654,000000) [200998,839] wl_pointer@19.motion(327912, 655,000000, 655,000000) [201026,802] wl_pointer@19.motion(327940, 654,000000, 655,000000) [201062,903] wl_pointer@19.motion(327976, 654,000000, 656,000000) [201270,802] wl_pointer@19.motion(328184, 654,000000, 657,000000) [201362,799] wl_pointer@19.motion(328276, 654,000000, 658,000000) [201362,848] -> wl_pointer@20.leave(142, wl_surface@23) [201362,855] -> wl_pointer@20.frame() [201362,866] -> wl_pointer@19.set_cursor(1531, wl_surface@18, 0, 0) [201362,874] -> wl_surface@18.attach(nil, 0, 0) [201362,879] -> wl_surface@18.set_buffer_scale(1) [201362,883] -> wl_surface@18.damage_buffer(0, 0, -1, -1) [201362,889] -> wl_surface@18.commit() [201362,922] -> wl_pointer@19.set_cursor(1531, wl_surface@18, 16, 16) [201362,940] -> wl_surface@18.attach(wl_buffer@23, 0, 0) [201362,949] -> wl_surface@18.set_buffer_scale(1) [201362,954] -> wl_surface@18.damage_buffer(0, 0, 32, 32) [201362,964] -> wl_surface@18.commit() [201363,021] wl_pointer@20.leave(142, wl_surface@23) [201363,041] wl_pointer@20.frame() [201363,174] wl_buffer@32.release() [201452,816] wl_pointer@19.motion(328366, 654,000000, 659,000000) [201486,784] wl_pointer@19.motion(328400, 654,000000, 660,000000) [201564,955] wl_pointer@19.motion(328478, 654,000000, 661,000000) [204529,352] wl_pointer@19.leave(1542, wl_surface@13)
I have this exact same problem on Manjaro KDE using Wayland. My graphics card is a Radeon RX 6800. Here's a 480fps slow motion video of my 180Hz monitor showing the issue: https://www.youtube.com/watch?v=75_pFmPOiRQ
*** Bug 451653 has been marked as a duplicate of this bug. ***
Same bug when I start to drag an icon on desktop. I use intel iGPU. SOFTWARE/OS VERSIIONS Operating System: Arch Linux KDE Plasma Version: 5.24.3 KDE Frameworks Version: 5.92.0 Qt Version: 5.15.3 Graphics Platform: Wayland
Affected too, using AMD GPU. Here's a short video showing it.. https://www.youtube.com/watch?v=bfv1wMdCgb4
I don't believe this is exclusive to Wayland. I can notice a broken frame when the cursor changes state in both X11 and Wayland.
(In reply to ob from comment #6) > I don't believe this is exclusive to Wayland. I can notice a broken frame > when the cursor changes state in both X11 and Wayland. Can you verify that? You can use the camera from your phone if it has a slow-motion mode, like I did in my post above.
Created attachment 147968 [details] Cursor glitch in Wayland and X11 It's definitely far less noticeable in X11, maybe a different problem altogether.
Looks like the same problem but much worse on Wayland. It's really bothersome on Wayland, even at normal speed.
As this can be reproduced with Xorg, kwin_wayland and also weston is almost certain that this is a driver bug - it seems to me like it updates the cursor texture and position asynchronously. I opened an issue with amd: https://gitlab.freedesktop.org/drm/amd/-/issues/1968 (In reply to Patrick Silva from comment #4) > Same bug when I start to drag an icon on desktop. I use intel iGPU. > > SOFTWARE/OS VERSIIONS > Operating System: Arch Linux > KDE Plasma Version: 5.24.3 > KDE Frameworks Version: 5.92.0 > Qt Version: 5.15.3 > Graphics Platform: Wayland I think that is a Qt bug, there's a weird similar issue in Dolphin and Gwenview as well - but not in Firefox when dragging an image.
(In reply to Zamundaaa from comment #10) The desktop icon/file/folder thing is definitely exclusive to the Wayland session. In X11, it animates fading in attached the cursor after the icon immediately disappears on the desktop or in the folder.
Git commit f07d6bd40034372b7176f57de080003c8a612d57 by Vlad Zahorodnii, on behalf of Xaver Hugl. Committed on 10/05/2022 at 07:06. Pushed by vladz into branch 'master'. backends/drm: port the cursor to use output layers M +1 -0 src/backends/drm/CMakeLists.txt M +2 -2 src/backends/drm/drm_buffer_gbm.cpp M +2 -1 src/backends/drm/drm_buffer_gbm.h M +5 -5 src/backends/drm/drm_gpu.cpp M +24 -0 src/backends/drm/drm_layer.cpp M +15 -0 src/backends/drm/drm_layer.h M +117 -55 src/backends/drm/drm_output.cpp M +5 -2 src/backends/drm/drm_output.h M +33 -31 src/backends/drm/drm_pipeline.cpp M +8 -8 src/backends/drm/drm_pipeline.h M +7 -8 src/backends/drm/drm_pipeline_legacy.cpp M +47 -0 src/backends/drm/drm_qpainter_layer.cpp M +18 -0 src/backends/drm/drm_qpainter_layer.h M +3 -1 src/backends/drm/drm_render_backend.h M +2 -2 src/backends/drm/dumb_swapchain.cpp M +1 -1 src/backends/drm/dumb_swapchain.h M +7 -1 src/backends/drm/egl_gbm_backend.cpp M +2 -1 src/backends/drm/egl_gbm_backend.h A +65 -0 src/backends/drm/egl_gbm_cursor_layer.cpp [License: GPL(v2.0+)] A +47 -0 src/backends/drm/egl_gbm_cursor_layer.h [License: GPL(v2.0+)] M +15 -15 src/backends/drm/egl_gbm_layer_surface.cpp M +5 -5 src/backends/drm/egl_gbm_layer_surface.h M +6 -0 src/backends/drm/gbm_surface.cpp M +2 -0 src/backends/drm/gbm_surface.h M +6 -1 src/backends/drm/scene_qpainter_drm_backend.cpp M +2 -1 src/backends/drm/scene_qpainter_drm_backend.h https://invent.kde.org/plasma/kwin/commit/f07d6bd40034372b7176f57de080003c8a612d57
To explain why I put this in CC for the commit, while there's probably still some driver bug (with some flicker being visible in Weston), it fixes most of the flicker on kwin_wayland.