You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When a Workshop item is subscribed while the app is running, the Steam client downloads it into steamapps/workshop/content/431960/<id>, but the wallpaper does not appear in the library until a rescan is triggered by hand. Nothing observes the Workshop directory, so the subscription stays invisible until the user finds the Refresh button, uses the tray entry, or restarts.
I would like to suggest a hook for this: steamapps/workshop/appworkshop_431960.acf — the same file the plugin already reads since #84. Filing an issue rather than a PR because the scan trigger lives in the daemon rather than in the Lua plugin, and I would rather agree on the shape before touching it. Happy to move this to the waywallen repository if that is the better place for it.
What I observed
waywallen 0.2.6 (org.waywallen.waywallen.Daemon1.Version), plugin org.waywallen.open-wallpaper-engine 0.2.0, daemon running with --no-ui --no-tray, KDE Plasma / Arch.
With the daemon running, I subscribed to a Workshop item (3625095088, 96 KB) in the Steam client.
About 200 s later the Steam client created content/431960/3625095088 and, 0.2 s after that, rewrote steamapps/workshop/appworkshop_431960.acf. I polled both every 200 ms; the record's WorkshopItemDetails block for the item carries subscribedby, so it is exactly the shape source: read Workshop subscriptions from Steam's own record #84 reads.
One detail worth noting: the .acfinode changed across that write (6865340 → 6866042). Steam replaces the file, it does not write into the existing one.
I then left the daemon alone for roughly 15 minutes. The library still held the same 39 items, and select * from item where path like '%3625095088%' against waywallen-v2.db returned nothing.
One manual rescan — org.waywallen.waywallen.Daemon1.Rescan over D-Bus, which is the same control::rescan entry point as the tray's "Rescan wallpapers" — made it appear at once: 39 → 40 items, display_name = 几何绘图 | GeoDraw v2.0, resource = .../3625095088/assets.json, external_id = 3625095088.
The same happens with a directory placed into content/431960 by hand: invisible for as long as I waited, present immediately after a rescan. So this is about the scan trigger and not about anything item-specific.
Expected: once Steam has finished downloading a subscribed item, it turns up in the library on its own.
Where a rescan is triggered today
Every path into control::refresh_sources I could find is an explicit user or lifecycle action, and there is no filesystem watching anywhere — Cargo.toml pulls in no notify/inotify crate, and src/ contains no direct inotify use either:
daemon startup — src/main.rs:588
the WallpaperScan request, i.e. the wallpaper page's "Refresh" action (ui/qml/page/WallpaperPage.qml:293-299) — src/ws_server.rs:1930-1939
auto-detect registering a library — src/control.rs:1521
plugin install/refresh — src/control.rs:708
tray "Rescan wallpapers" — src/tray/dbusmenu.rs:169-170 and :348
D-Bus Rescan — src/dbus_iface.rs:120-121
Req::SubscriptionSet (src/ws_server.rs:2572) returns as soon as the plugin accepts the mutation and schedules nothing afterwards, which is sensible on its own — at that moment Steam has not downloaded anything yet, so an immediate scan would find nothing. But nothing picks the item up later either. And a subscription made in the Steam client or in a browser never passes through that handler at all.
(Line numbers are against waywallen main, e5626c1.)
One approach that works: treat steamapps/workshop/appworkshop_431960.acf as the "Steam finished something" signal and run a library refresh when it changes.
It fits well because the plugin already depends on that exact file — ACF_REL in wallpaper_engine/workshop.lua:10, read per Steam root by fold_root (workshop.lua:103-105), folded once per scan by workshop.refresh (workshop.lua:134, called from source.lua:64). The "is this a real subscription" question and the "has something changed" question would then come from the same source of truth, and the roots to watch are the ones source.lua:59-60 already derives from ctx.libraries(). In the run above the record was rewritten 0.2 s after the content directory appeared, so by the time it changes, the files are on disk and a scan finds them.
Things that turned out to matter:
The file is replaced, not modified. The inode changed across the subscription, so a watch pinned to the file itself goes deaf after the first event. Watching the containing steamapps/workshop/ directory survives the replacement.
It may not exist yet. A machine that has never downloaded a Workshop item for 431960 has no appworkshop_431960.acf; fold_root already treats a missing file as "no record" (workshop.lua:105). Watching the directory also covers the file being created later.
One record per Steam library. Each registered root has its own copy, which is why workshop.refresh folds over all of them — the watch set should follow the same list and be re-armed when libraries are added or removed.
Collapse bursts into a single scan. A full refresh_sources per raw event would be wasteful, so a short debounce plus skipping while scan_in_progress is already set (src/control.rs:1618) keeps it to one scan per burst.
A polling variant — re-reading the record every couple of seconds instead of watching it — is also viable and adds no dependency; reading one small KeyValues file is far cheaper than a full library scan. That is enough to cover subscriptions made anywhere, including in the Steam client.
If this direction looks right to you, I am glad to prepare the patch; I just did not want to push a daemon-side change without asking first.
Summary
When a Workshop item is subscribed while the app is running, the Steam client downloads it into
steamapps/workshop/content/431960/<id>, but the wallpaper does not appear in the library until a rescan is triggered by hand. Nothing observes the Workshop directory, so the subscription stays invisible until the user finds the Refresh button, uses the tray entry, or restarts.I would like to suggest a hook for this:
steamapps/workshop/appworkshop_431960.acf— the same file the plugin already reads since #84. Filing an issue rather than a PR because the scan trigger lives in the daemon rather than in the Lua plugin, and I would rather agree on the shape before touching it. Happy to move this to the waywallen repository if that is the better place for it.What I observed
waywallen 0.2.6 (
org.waywallen.waywallen.Daemon1.Version), pluginorg.waywallen.open-wallpaper-engine0.2.0, daemon running with--no-ui --no-tray, KDE Plasma / Arch.3625095088, 96 KB) in the Steam client.content/431960/3625095088and, 0.2 s after that, rewrotesteamapps/workshop/appworkshop_431960.acf. I polled both every 200 ms; the record'sWorkshopItemDetailsblock for the item carriessubscribedby, so it is exactly the shape source: read Workshop subscriptions from Steam's own record #84 reads.One detail worth noting: the
.acfinode changed across that write (6865340 → 6866042). Steam replaces the file, it does not write into the existing one.select * from item where path like '%3625095088%'againstwaywallen-v2.dbreturned nothing.org.waywallen.waywallen.Daemon1.Rescanover D-Bus, which is the samecontrol::rescanentry point as the tray's "Rescan wallpapers" — made it appear at once: 39 → 40 items,display_name = 几何绘图 | GeoDraw v2.0,resource = .../3625095088/assets.json,external_id = 3625095088.The same happens with a directory placed into
content/431960by hand: invisible for as long as I waited, present immediately after a rescan. So this is about the scan trigger and not about anything item-specific.Expected: once Steam has finished downloading a subscribed item, it turns up in the library on its own.
Where a rescan is triggered today
Every path into
control::refresh_sourcesI could find is an explicit user or lifecycle action, and there is no filesystem watching anywhere —Cargo.tomlpulls in nonotify/inotify crate, andsrc/contains no directinotifyuse either:src/main.rs:588WallpaperScanrequest, i.e. the wallpaper page's "Refresh" action (ui/qml/page/WallpaperPage.qml:293-299) —src/ws_server.rs:1930-1939src/ws_server.rs:2821,src/ws_server.rs:2846src/control.rs:1521src/control.rs:708src/tray/dbusmenu.rs:169-170and:348Rescan—src/dbus_iface.rs:120-121Req::SubscriptionSet(src/ws_server.rs:2572) returns as soon as the plugin accepts the mutation and schedules nothing afterwards, which is sensible on its own — at that moment Steam has not downloaded anything yet, so an immediate scan would find nothing. But nothing picks the item up later either. And a subscription made in the Steam client or in a browser never passes through that handler at all.(Line numbers are against waywallen
main, e5626c1.)Suggestion: build on the file #84 already reads
One approach that works: treat
steamapps/workshop/appworkshop_431960.acfas the "Steam finished something" signal and run a library refresh when it changes.It fits well because the plugin already depends on that exact file —
ACF_RELinwallpaper_engine/workshop.lua:10, read per Steam root byfold_root(workshop.lua:103-105), folded once per scan byworkshop.refresh(workshop.lua:134, called fromsource.lua:64). The "is this a real subscription" question and the "has something changed" question would then come from the same source of truth, and the roots to watch are the onessource.lua:59-60already derives fromctx.libraries(). In the run above the record was rewritten 0.2 s after the content directory appeared, so by the time it changes, the files are on disk and a scan finds them.Things that turned out to matter:
steamapps/workshop/directory survives the replacement.appworkshop_431960.acf;fold_rootalready treats a missing file as "no record" (workshop.lua:105). Watching the directory also covers the file being created later.workshop.refreshfolds over all of them — the watch set should follow the same list and be re-armed when libraries are added or removed.refresh_sourcesper raw event would be wasteful, so a short debounce plus skipping whilescan_in_progressis already set (src/control.rs:1618) keeps it to one scan per burst.A polling variant — re-reading the record every couple of seconds instead of watching it — is also viable and adds no dependency; reading one small KeyValues file is far cheaper than a full library scan. That is enough to cover subscriptions made anywhere, including in the Steam client.
If this direction looks right to you, I am glad to prepare the patch; I just did not want to push a daemon-side change without asking first.