SUMMARY KDE does not send suspended xdg_toplevel state STEPS TO REPRODUCE 1. With WAYLAND_DEBUG=1 env var set, start a wayland app that binds to xdg-shell (wm_base) version 6. 2. Check xdg-toplevel configure events. OBSERVED RESULT No "suspended" state is received. EXPECTED RESULT "suspended" state is received via xdg_toplevel configure event. SOFTWARE/OS VERSIONS KDE Plasma Version: 6.1.4 ADDITIONAL INFORMATION suspended state was added to the protocol as per https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/201
Correction. The following step should be included: 3. Cover the app window with another window.
>3. Cover the app window with another window. That will not send suspended, but we also still ack frame callbacks in this state so clients should behave. Moving to another desktop or minimizing or locking the screen will send the suspended state and not ack frame callbacks. This is working as *we* expect based on what was needed to make apps work correctly enough at the time. Given your email address, I do want to know why you're asking. Is it affecting Chrome negatively?
> Is it affecting Chrome negatively? Yes you're right it still continues sending frame callbacks but it appears it somehow ends up not releasing buffers when the window gets occluded. For example, initially with an animation running in a chrome window, I see 3 buffers (53, 52, 51) being attached and released: ``` [2792322.937] wl_buffer#53.release() [2792613.077] -> wl_surface#31.attach(wl_buffer#51, 0, 0) [2792617.577] wl_buffer#52.release() [2792796.449] -> wl_surface#31.attach(wl_buffer#53, 0, 0) [2792801.144] wl_buffer#51.release() [2793102.328] -> wl_surface#31.attach(wl_buffer#52, 0, 0) [2793107.900] wl_buffer#53.release() [2793311.867] -> wl_surface#31.attach(wl_buffer#51, 0, 0) [2793317.832] wl_buffer#52.release() [2793622.481] -> wl_surface#31.attach(wl_buffer#53, 0, 0) [2793628.009] wl_buffer#51.release() [2793805.902] -> wl_surface#31.attach(wl_buffer#52, 0, 0) ``` But then when the window is fully covered 2 of the buffers remain unreleased, which halts chromium rendering: ``` [2794624.698] wl_buffer#53.release() [2794803.251] -> wl_surface#31.attach(wl_buffer#51, 0, 0) [2794816.491] wl_buffer#52.release() [2795106.495] -> wl_surface#31.attach(wl_buffer#53, 0, 0) [2795111.186] wl_buffer#51.release() [2795317.602] -> wl_surface#31.attach(wl_buffer#52, 0, 0) [2795323.820] wl_buffer#53.release() [2795349.909] -> wl_surface#31.attach(wl_buffer#51, 0, 0) [2795409.049] -> wl_surface#31.attach(wl_buffer#53, 0, 0) [2795409.159] wl_buffer#51.release() ... This is where the animation and the logs stop. Note #53 and #52 are not returned ... ``` While this doesn't affect normal use cases, there is a use case in chrome that is broken when a window is put in background, viz. the tab capture feature where a tab is internally captured within chromium as opposed to capturing an entire window or screen. If the window containing the tab that is being captured is occluded the capture stops. So for instance sharing a slideshow tab containing animations will freeze when the window is covered by another window. Logs and videos attached here: https://cloud.igalia.com/s/CewK5bS6oyB9gjM I did notice that firefox for instance works around this issue by creating new buffers when previous buffers are blocked and continues to render. I could explore something like that on the chromium-side as well. But I am also interested to know if this is something that is unexpected in kwin and if it could be addressed there, e.g. by not doing any throttling at all or using `suspended` and throttling frame callbacks instead.
Making KWin set the suspended state and stop sending frame callbacks on occluded windows is planned, but won't happen soon, and isn't sufficient to fix your problem in all situations. Applications have to handle the compositor keeping two buffers, that's a thing that can happen in many unavoidable situations, like direct scanout.