Repository navigation
Conversation
Switching wallpapers faded the current backend out at once and created the next one underneath. A cold scene start takes seconds (shader compiles), so the desktop showed the bare background colour, with the icons over it, for all of that; scene->scene and video->video swaps did not even fade, since they reassigned `source` on the live item. Each backend now exposes `frameShown`, set on its first frame (InfoShow, a static pane, starts true). backendLoader.load() keeps the backend that is on screen as `_outgoing`, stacked above and still playing, until the new one sets frameShown; then it fades out over 250 ms (an instant cut with "Reduce animations") and is destroyed. A backend that never reached the screen during rapid switching is dropped at once, so what the user sees stays up rather than a blank gap. A 25 s timeout guarantees the old layer never lingers; the backends' own load watchdogs still swap in InfoShow on failure. A different wallpaper now always gets a fresh backend, even of the same type, so it goes through this handoff. A path change on the same workshop id (another page of the same web wallpaper) still swaps in place, as before; folder videos carry no id, so for them any path change is a new wallpaper. The outgoing backend must also stop following background.*, which describes the next wallpaper from the moment the switch starts: WallpaperWorkShopId changes first and read_wallpaper_config resolves synchronously, so the old wallpaper immediately took the new one's display mode, speed and user properties and stretched or cropped until the swap finished. Backends gain freezeOptions(), which pins those to their current values; load() calls it on the outgoing backend, and the new wallpaper's options are read after that (readCurrentOptions, before `source` is set, so USER_PROPS still precede LOAD_SCENE). The workshopid handler defers its read with Qt.callLater for the same reason. tst_main_handoff.qml drives this through the real main.qml: the old scene stays on top until the new one draws and then fades, the outgoing scene keeps its own display mode, a rapid A->B->C switch keeps A on screen, and a same-id path change does not rebuild.
Switching away from a video wallpaper froze every plasmashell window
for ~200 ms (QSG_RENDER_TIMING). Two synchronous waits on the mpv core:
- ~MpvRender runs mpv_render_context_free on the Qt render thread
during the scenegraph sync (GUI thread blocked), and that call waits
for the core to tear its video output down.
- onMpvEvents answered every observed-property event with two
mpv_get_property calls ("idle-active", "pause") on the GUI thread,
which block while the core is busy, i.e. exactly during a teardown.
onMpvEvents now takes both values from the MPV_EVENT_PROPERTY_CHANGE
payload (both are observed as MPV_FORMAT_FLAG) and keeps the last seen
pair, so an event never calls back into the core.
MpvObject::stopAsync() detaches the owner from mpv's wakeup callback
(MpvHandle::detachOwner, the first half of beginShutdown) and issues an
async "stop". Mpv.qml exposes it as prepareDestroy(), and the handoff's
fade-out calls that on the outgoing backend and destroys it 400 ms
later: by then mpv has dropped its video output, and
mpv_render_context_free no longer waits. Backends without
prepareDestroy are destroyed right away, as before.
tst_mpvbackend covers stopAsync: it returns without waiting on the
core, an observed-property change after it no longer reaches the
object (with a control run showing the same change does without it),
and repeated / uninitialised calls are safe.
Stacked on "Keep the old wallpaper on screen until the new one has
drawn" (the fade-out that calls prepareDestroy).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends on #35 (the handoff's fade-out is what calls
prepareDestroy). Until that one is merged, this PR's diff includes its commit.Problem
Switching away from a video wallpaper froze every plasmashell window for ~200 ms (
QSG_RENDER_TIMING, on a build based on an oldermain, 5c3d184; the teardown code below is the same on today'smain). There are two synchronous waits on the mpv core:~MpvRendercallsmpv_render_context_freeon the render thread during the sync (GUI thread blocked). That call waits for the core to tear down its video output.onMpvEventsanswered every observed-property event with twompv_get_propertycalls on the GUI thread. Those block while the core is busy, which is exactly the case during a teardown.Change
onMpvEventstakesidle-active/pausefrom theMPV_EVENT_PROPERTY_CHANGEpayload (both are observed asMPV_FORMAT_FLAG) and keeps the last pair.MpvObject::stopAsync()does two things: it detaches the owner (MpvHandle::detachOwner, the first half ofbeginShutdown) and issues an asyncstop.Mpv.qmlexposes it asprepareDestroy(). The fade-out calls that, then destroys the backend 400 ms later, whenmpv_render_context_freeno longer waits.Tests
tst_mpvbackendchecks that:stopAsyncdoesn't wait on the core;tools/scripts/preflight.shpasses (run inside afedora-toolbox:latestcontainer built fromDEPS_FEDORA,WEK_IN_CI=1). One note: on this laptop the fuzz step times out on the checked-in seedtests/fuzz_corpus/WPShaderCompile/seed/58392d50…(~33 s per compile under ASAN+UBSAN, identical on cleanmain), so I ran preflight with--no-fuzzand then all fuzz targets with the same settings except-timeout=60: no findings.Setup: Plasma 6 (Wayland), KWin, Intel Iris Xe (RPL-P), 2520x1680 @ 120 Hz laptop panel, Manjaro.