Files
LiveWall/README.md
T
2026-11-04 20:33:02 +00:00

34 KiB
Raw Blame History

LiveWall 1.8.4 — animated GIF, video & YouTube desktop wallpapers for Windows 11

A complete, self-contained live-wallpaper app written in C# / WPF (.NET 8). It plays videos, animated GIFs, still images, YouTube links and any web page behind your desktop icons — exactly where a wallpaper belongs — with a comprehensive settings window where every behaviour can be configured.

No store, no subscription, no account.


1. What you got

Folder Contents
LiveWall-Setup-1.8.4.exe Installer — dark, app-branded setup; per-user install, upgrade detection, Start-menu shortcut, uninstaller, .NET runtime check.
LiveWall-Setup-1.8.0.exe, LiveWall-Setup-1.7.0.exe, LiveWall-Setup-1.6.3.exe Previous releases, kept so the update flow can be tried out.
installer\ The NSIS script + build script that produce the installer.
prebuilt\ Ready-to-run build (LiveWall.exe + DLLs, ~1.6 MB). Needs the .NET 8 Desktop Runtime.
LiveWall\ Full source code (C# + XAML).
LiveWall.Sdk\ The plugin contract assembly (LiveWall.Sdk.dll) — what plugins are written against.
samples\ClockOverlayPlugin\ Complete example plugin that uses every extension point.
docs\plugins\ Developer guide for plugins (also shipped next to the app, and readable in Markdown).
build.ps1 One-command build / run / publish / self-contained packaging.
README.md This document.

2. Install it

The easy way — the installer

Run LiveWall-Setup-1.8.4.exe. It is a per-user install, so Windows shows no UAC prompt and nothing is written outside your own profile:

Program files %LOCALAPPDATA%\Programs\LiveWall
Start-menu shortcut LiveWall
Optional desktop shortcut, start at sign-in
Uninstall Settings ▸ Apps ▸ Installed apps ▸ LiveWall (or Uninstall.exe in the folder)
Your settings %APPDATA%\LiveWall — kept by installer upgrades and by the uninstaller (it asks first)

The window matches the app: same dark palette and accent colour, the app mark, one page for the options and one for the result — there is no white wizard chrome and no stock "Nullsoft" text. Every control is drawn with nsDialogs (installer/LiveWall.nsi), positioned as a percentage of the window so the layout holds at any DPI, and the stock Next/Back/Cancel row is replaced by flat buttons.

The installer checks for the .NET Desktop Runtime 8 (or newer) and offers the Microsoft download page if it can't find one; it also closes a running LiveWall before replacing files.

Pictures of the four screens: setup, update, finished, uninstall.

Updating an existing installation

The installer records InstallDir and Version under HKCU\Software\LiveWall, and compares the installed version with its own before it touches anything:

What it finds What happens
Nothing installed Normal fresh install, you pick the folder.
Older version An Update page appears: "LiveWall 1.6.3 is already installed in … This will update it to 1.8.4." It installs into the same folder (the folder page is skipped), replaces the program files and keeps %APPDATA%\LiveWall. A checkbox offers to wipe the settings and start from scratch.
Same version Asks "LiveWall 1.7.0 is already installed. Reinstall it?" before doing anything.
Newer version Warns that it would be a downgrade and needs an explicit Yes.

Version comparison is numeric on major.minor.patch, so 1.6.10 sorts above 1.6.9 and 10.0.0 above 9.9.9. Installs made before this logic existed (no Version value) are treated as older and upgraded in place. /S silent installs skip the prompts and always update in place.

Antivirus and SmartScreen warnings

The exe is not code-signed, so:

  • SmartScreen shows "Windows protected your PC" on the first run — More info ▸ Run anyway. Signing needs a paid certificate.
  • On VirusTotal, LiveWall-Setup-1.8.2.exe was flagged by 3 of 71 engines (SecureAge, Trapmine's ML score, VBA32's "TScope.Malware-Cryptor.SB"), and clean on the other 68 — including Microsoft Defender, Kaspersky, BitDefender, ESET, Malwarebytes, Sophos and Symantec. Those three are reputation/heuristic verdicts on an unsigned installer with zero prevalence, not detections of behaviour. Vendor false-positive reports are filed; see docs/antivirus.md for the full analysis, the report template and the per-release checklist.

Verify what you downloaded — the published hash for this build is:

d2de043f02179034c011faae92853178c0d72277265ed39227b432cbf96906e4  LiveWall-Setup-1.8.4.exe            (724 KB)
5c2d046abb9d491913cd4393bfc4664b120a5c4804b83d6895b0413755ad5c87  LiveWall-Setup-1.8.4-zlib.exe       (992 KB)
3f704c9355ad8348c85151619c784f0f23a6596c5b837a8950e66eb035cfb1a6  LiveWall-1.8.4-portable.zip         (875 KB)

If your engine still objects, two alternatives ship from the same source and have no NSIS self-extracting stub at all:

Download What it is
LiveWall-Setup-1.8.4-zlib.exe Same installer, non-solid zlib compression (the solid archive is what the heuristic engines score)
LiveWall-1.8.4-portable.zip (.\build.ps1 -Task portable) Plain zip — unpack anywhere, run LiveWall.exe. Nothing to unpack, nothing for an engine to score

Rebuilding the installer

sudo apt-get install nsis        # or the Windows NSIS package
./installer/build-installer.sh   # reads the version from LiveWall.csproj

# alternate container for antivirus triage (see docs/antivirus.md)
COMPRESS=zlib OUT_SUFFIX=-zlib ./installer/build-installer.sh

On Windows, sign the result (publisher instead of "Unknown publisher", and what every antivirus vendor asks for when you report a false positive):

.\installer\sign.ps1 -Thumbprint <sha1-of-your-code-signing-cert>

It packs everything in prebuilt\ (a full publish, including runtimes/), so publish first:

.\build.ps1 -Task publish

Option A — use the prebuilt binary without installing (fastest)

  1. Install the .NET 8 Desktop Runtime (x64) if you don't have it: https://dotnet.microsoft.com/download/dotnet/8.0/runtime (Windows 11 usually has it already if you use any modern .NET app.)
  2. Copy the whole prebuilt\ folder somewhere permanent, e.g. C:\Program Files\LiveWall\.
  3. Run LiveWall.exe.
  4. Pick a video / GIF / image (or paste a YouTube link) → the wallpaper starts immediately.

Option B — build from source

# from the folder that contains build.ps1
.\build.ps1              # framework-dependent build -> .\prebuilt
.\build.ps1 -Task run    # build and launch

Or plainly:

dotnet publish LiveWall\LiveWall.csproj -c Release -r win-x64 --self-contained false -o prebuilt

Requires the .NET 8 SDK. Want a build that runs on a PC without .NET installed? .\build.ps1 -Task selfcontained (produces a ~180 MB folder — WPF cannot be trimmed).

First run

LiveWall creates %APPDATA%\LiveWall\ containing:

  • settings.json — every setting (human readable)
  • logs\livewall-YYYYMMDD.log — diagnostics
  • web\player.html — the local YouTube player host page
  • WebView2\ — Edge WebView2 profile for web wallpapers

It also adds a tray icon. Closing the settings window keeps the wallpaper running (configurable).


3. Feature tour

Wallpaper sources (Wallpaper tab)

  • Video files — mp4, m4v, mov, wmv, avi, mkv, webm, mpg, ts (played through WPF/Media Foundation, H.264 MP4 is the most reliable).
  • Animated GIF — frames are composited by hand (per-frame rects, disposal methods 0–3, transparency), so even huge multi-hundred-frame GIFs animate correctly with constant memory use.
  • Still images — png, jpg, bmp, tif, webp.
  • YouTube — paste watch?v=…, youtu.be/…, /shorts/…, /live/…, /embed/…, m.youtube.com, a youtube-nocookie link, or just the 11-character video id. ?t=/&t=1m30s start times are detected.
  • Web page — any https:// URL becomes a live dashboard/wallpaper.
  • Drag & drop a file anywhere onto the window, browse for it, or pick from the Recent list.

Playback (Playback tab)

Setting What it does
Fit mode Fill (cover/crop), Fit (letterbox), Stretch, Center, Tile (repeats small GIFs/images)
Dim overlay 0–95 % darkening of the wallpaper + custom tint colour
Mute / volume Audio is muted by default; unmute and set volume 0–100
Speed 0.25×–4× for video, GIF and YouTube
Start at Skip intros (seconds), also applied on every loop
Loop forever Or stop at the end / advance the playlist
Restart on resume Jump back to the start offset whenever playback resumes

Displays (Display tab)

  • All displays · primary only · one specific display (live device list with resolution).
  • Span mode: one wallpaper stretched across every monitor (surround setups).
  • Interaction mode: click-through (icons stay usable, default) or interactive (wallpaper raised above the icon layer so YouTube controls and web pages are clickable — Windows hides desktop icons while it's on; toggle with Ctrl+Alt+I).
  • Re-attach to desktop button for the rare case where the wallpaper lost its host window.

Playlist (Playlist tab)

Multiple wallpapers of any mix of types, sequential or shuffle, rotation interval (1–240 min), "advance when the current video/GIF ends", reorder/add/remove/play-now.

Automation (Automation tab)

  • Pause when: a full-screen app is in the foreground, a maximized window is in front, running on battery, the session is locked, or over Remote Desktop.

  • Hide the wallpaper completely while paused so the GPU goes idle.

  • Configurable poll interval (0.25–5 s).

  • Start with Windows (HKCU Run entry), start minimized, close-to-tray, tray icon, tray notifications.

  • Four global hotkeys (any Ctrl/Alt/Shift/Win + key combination):

    Action Default
    Pause / resume Ctrl+Alt+P
    Next wallpaper Ctrl+Alt+N
    Reload wallpaper Ctrl+Alt+R
    Toggle interactive mode Ctrl+Alt+I

    A conflict with another app is reported right under the boxes instead of failing silently.

YouTube (YouTube tab)

Preferred quality (auto/4K/1440p/1080p/720p/480p/360p), start offset, loop, show controls, show related videos, privacy-enhanced youtube-nocookie.com embeds, and a free-text field for any raw player parameter (hl=de&cc_load_policy=1…).

Desktop icons on the wallpaper (Display tab)

When the wallpaper has to run as an overlay (see above), it sits in front of the shell's icon window, so the real icons are hidden. LiveWall therefore draws your desktop shortcuts itself:

  • items are read from %USERPROFILE%\Desktop and %PUBLIC%\Desktop (hidden/system entries skipped), sorted folders-first then alphabetically, with the real shell icons (SHGetFileInfo);
  • click selects, double-click opens (ShellExecute), right-click offers Open / Show in File Explorer / Refresh / LiveWall settings / Stop drawing icons;
  • the folders are watched with a FileSystemWatcher, so new/deleted files appear within ~1.5 s;
  • icon size (24–128 px), labels, "show on all displays" and "answer right-clicks on empty desktop space" are configurable.

Since v1.6 the icons live in their own per-pixel transparent window, pinned directly above the wallpaper window instead of being drawn inside it. That matters: WebView2 (YouTube / web pages) and hardware video render into a child HWND that is always composited above every WPF element of the same window, so the icons used to vanish for exactly those sources. Only the icon pixels are opaque, so clicks between the icons fall through to Windows as usual.

Since v1.6.3 the icon window is an owned window of the wallpaper window (GWLP_HWNDPARENT), which makes Windows itself guarantee that it stays above the wallpaper — no timer, no re-raising, no repaint storm. On top of that a watchdog asks Windows every 2 s which window is really on top of the first icon: if the desktop shell is sitting above them, it repairs the layer automatically and says so in the log. Display ▸ Repair desktop icons runs the same repair by hand and writes a report.

Since v1.6.2 the icon window keeps its own size explicitly (window Left/Top/Width/Height in DIPs and an explicit canvas size), so it can never be laid out into a zero-sized window — that is how the icons could vanish completely. It also checks itself 1.5 s after it appears, repairs the geometry if needed, and writes a breadcrumb to the log: Icon window: icons hwnd=0x… shown=True windowVisible=True rect=0,0 1920x1080 expected=… layer=1920x1080 tiles=17 (directly above wallpaper). That line is the fastest way to tell "no icons drawn" (tiles=0) from "icons drawn but invisible" (windowVisible=False, or rect not matching expected).

Since v1.6.1 the two layers no longer fight over the z-order: the icon window re-raises itself only when it is really out of place, the wallpaper only re-orders when it is really not directly above the desktop, and a re-order is never "just in case". Each SetWindowPos on a layered window forces a repaint, so doing it on every 150 ms timer tick made the icons flicker over video.

Limitations of this mode: the layout is a grid (Explorer's own icon positions can't be read reliably), there is no drag-to-arrange, and (unless you enable the right-click option) the shell's desktop context menu is the one you get between the icons. Turn the checkbox off for a bare wallpaper with no icons at all.

YouTube and web pages (Wallpaper tab)

The player page is served over https through a WebView2 virtual-host mapping (https://livewall.local/player.html, mapped to %APPDATA%\LiveWall\web). Up to v1.5 it was loaded as file://, which cannot work: a file:// page sends no Referer (YouTube answers error 153 — "video player configuration error") and its opaque origin breaks the IFrame API postMessage handshake, so onReady never fires and nothing ever plays. Both are fixed by the https origin.

LiveWall also keeps an eye on itself and writes the result to the log:

  • WebView2 runtime 1xx…; https://livewall.local/ -> … on start-up;
  • WebView2 navigation ok (http 200) / failed: <WebErrorStatus>;
  • Web probe: {"api":1,"state":1,"t":12.3,…} every few seconds — state 1 = playing, -1 = the API never became ready, fallback 1 = playing through a plain embed without API control;
  • if autoplay with sound is refused, the page mutes itself and retries, then reports forced-mute; if the API cannot start at all it falls back to a plain embed/ iframe.

Advanced (Advanced tab)

WebView2 DevTools + context menu, extra Chromium switches, verbose logging, automatic re-attach after Explorer restarts or display changes, recent-list length, open log folder / settings file, reset every setting to defaults, live status log.

Plugins (Plugins tab)

LiveWall 1.8 adds a plugin system: .NET 8 assemblies you drop into %APPDATA%\LiveWall\plugins\ can add wallpaper renderers, draw on the desktop, add settings pages, commands, tray entries and global hotkeys, rewrite wallpaper requests and react to every app event.

The plugin system is off by default and every plugin needs two explicit consents. Turning it on shows a warning that unverified plugins may cause harm to your computer; enabling each individual plugin shows its name, author, folder, SHA-256 hash and the full list of permissions it declared, and nothing is loaded until you tick the acknowledgement and press Enable. The accepted hash is remembered: if the file changes, the plugin is unverified again.

What you see What it does
Enable the plugin system Master switch (asks first, stores your consent)
Also allow plugins that are not verified on this machine Off by default; required for plugins you have not approved before
Rescan plugins / Open plugin folder / Create plugin template / Developer docs Day-to-day plugin management
Installed plugins One row per plugin: name, author, state, permissions, Enable/Disable, Settings (the plugin's own pages), Forget trust
Plugin commands Every command a plugin contributes, with a Run button
Plugin log Each loaded plugin, its hash, permissions and what it registered

Failed plugins never take LiveWall down: every call into a plugin is guarded, and the reason is shown in the row and written to %APPDATA%\LiveWall\logs. A working example ships in samples\ClockOverlayPlugin\ (a clock overlay + settings page + command + filter + hotkey), and the developer guide is in docs\plugins\ (index.md is the entry point).

Tray menu

Settings · Pause · Interactive mode · Next wallpaper · Reload wallpaper · Plugins (submenu, when a plugin contributes commands) · Open log folder · Exit.


4. How it works (and why it behaves like a real wallpaper)

Windows draws the desktop in two layers: a shell window (Progman) that paints the static wallpaper, and a hidden WorkerW window that sits behind the one hosting SHELLDLL_DefView (your icons). Programs can ask the shell to create that window by sending WM_SPAWN_WORKER (0x052C) to Progman.

LiveWall:

  1. sends 0x052C (with the documented 0xD w/l parameter variants) and enumerates top-level windows to find the WorkerW that is behind the icon host;
  2. creates a borderless WPF HwndSource window (WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE) per selected display, at the monitor's exact pixel rectangle;
  3. SetParents it into that WorkerW, converts it to a genuine WS_CHILD window and keeps it at the bottom of the z-order.

Because it is a normal child window in the shell's own layer it never appears in Alt+Tab, never steals focus, is covered by normal windows, and the icons draw on top of it. A 1-second watchdog notices when the desktop window disappeared (Explorer restart, resolution change, monitor hot-plug) and rebuilds.

Layout-aware, self-verifying attach (v1.4). The desktop layer is not arranged the same way on every Windows build (Windows 11 24H2+ differs from Windows 10), so the app never assumes a layout. It builds a list of candidate parents, in an order that reflects how the shell is actually built on your machine (icons inside Progman → the wallpaper goes inside Progman below the icon view; classic layout → the WorkerW behind the icon window), reparents into one, and then proves it is on screen: it paints two unmistakable colours in nine small patches spread across the wallpaper, captures those exact pixels from the screen and compares them. Only a strategy that really shows up on screen is kept; the rest are tried in turn and the winner is remembered for the session.

Each layout is additionally tried with three hosting techniques, because whether a window is composited at all depends on the Windows build and on DPI awareness of the shell:

  • parent at creation — the HWND is born as a child of the shell window (HwndSourceParameters.ParentWindow);
  • adopt after first render — the HWND is born as a normal top-level window, renders one frame, and is then converted to a child with SetParent (the classic technique);
  • overlay — the window stays a normal top-level window and is pinned exactly one slot above the desktop window (re-pinned 7×/second, and immediately when the z-order changes). This always composites, but it covers the desktop icons.

While the shell-child techniques are attempted, the app briefly switches its thread to the shell's own DPI awareness context — a mismatch there is a documented cause of "parenting succeeds but the child is never drawn". On builds where child windows are never composited the app now lands on the overlay automatically, so a wallpaper is always visible. The Display tab exposes this as Wallpaper layer: Auto / Inside the desktop / Overlay.

The probe decides which combination paints here. During the very first attach you may see a short flash while it tests — the winner is cached, so later rebuilds are instant and invisible. The host window is created hidden and only shown after it has been adopted, which is why there is no black flash while attaching any more.

Rendering backends:

  • Media Foundation (MediaElement) for video,
  • a custom GIF compositor (WriteableBitmap + DispatcherTimer),
  • WebView2 for YouTube/web pages, driven through the official YouTube IFrame API with window.chrome.webview.postMessage reporting back (e.g. "video ended" → next playlist item).

Application manifest: asInvoker (never needs admin), Per-Monitor V2 DPI aware.


5. Troubleshooting

Symptom Fix
The desktop flashes black for a moment and then nothing happens Fixed in v1.1/v1.2: the window is created hidden and only shown after it has been adopted and proven visible, and the attach no longer assumes one fixed desktop layout. Make sure you replaced the whole prebuilt\ folder (About tab shows the version).
Diagnostics said SetParent … failed for every strategy Fixed in v1.2. The parent check ran while the window was still WS_POPUP, where GetParent() reports the owner instead of the new parent — every successful attach looked like a failure. The check now runs after the window becomes a child (and also cross-checks GetAncestor).
Nothing appears on the desktop Advanced ▸ Desktop diagnostics → “Test visibility”. It prints which shell windows were found, which strategy is active, whether the pixels were confirmed on screen — and it automatically re-detects and re-attaches if the test fails. Also close other desktop-shell modifiers (StartAllBack, ExplorerPatcher, Rainmeter skins that grab WorkerW, Wallpaper Engine) and retry.
Diagnostics shows every attempt as NOT visible with our window on top at N points Send that line: it separates "the window is covered / mis-layered" (N = 0) from "the window is on top but WPF is not painting" (N > 0). captureBroken=True means the screen grab is unusable (HDR) and hit-testing alone decided.
Wallpaper works but desktop icons are hidden Fixed in v1.5/v1.6 by the Desktop icons on the wallpaper layer (Display tab). If you prefer no icons at all, untick it.
Desktop icons do not appear at all v1.6.3. Press Display ▸ Repair desktop icons, then Advanced ▸ Diagnostics ▸ Refresh ▸ Copy and send the desktop icons: lines — they state tiles=N (0 = nothing was read from your desktop folders), windowVisible=, rect= vs expected=, and whether the window is directly above wallpaper. The log also records Icon watchdog: lines when the shell covers the icons.
Older note: v1.6.2. First check Display ▸ Draw desktop icons on top of the wallpaper is still ticked (the icon menu can switch it off), and that you are not in Interactive mode (the icons step aside so the mouse can reach the web page). Then look for the Icon window: … line in the log: tiles=0 means nothing was read from your desktop folders, windowVisible=False or a rect= that differs from expected= means the window itself is wrong.
Desktop icons flicker or flash Fixed in v1.6.1 (the wallpaper and the icon layer kept re-raising each other every timer tick; every re-order repaints a layered window). If it still happens, check the log for repeated Display configuration changed – rebuilding lines - that would mean something keeps changing the display signature, and v1.6.1 throttles it and says so.
Icons missing only with video / YouTube / web wallpapers Fixed in v1.6: the icons moved into their own transparent window, because WebView2 and video paint over anything WPF draws in the wallpaper window.
YouTube never plays, any video, black screen Fixed in v1.6 (the player page was loaded from file://, which YouTube rejects with error 153). If it still happens, open Advanced ▸ Desktop diagnostics and send the web probe: line - it says whether the API became ready and which player state it reached.
A message says “something went wrong” That is LiveWall's error surface. Since v1.5 it shows the exception type and message, and the full stack goes to %APPDATA%\LiveWall\logs. Paste that line and the problem can be pinned down.
Wallpaper disappeared after an Explorer crash It re-attaches automatically within a second or two; otherwise press Re-attach or restart LiveWall.
Video is black / won't play MP4/H.264 is safest. MKV/AV1/VP9/HEVC usually fail in Media Foundation — re-encode with HandBrake.
YouTube stays black Needs internet + WebView2 runtime (ships with Win 11). Some videos forbid embedding — the app tells you the exact error code.
Can't click YouTube controls Switch to Interactive mode (Display tab or Ctrl+Alt+I). Desktop icons are hidden while it's on.
High CPU/GPU Enable "pause when a full-screen app is in the foreground", keep "hide while paused", prefer 1080p sources, keep the app muted.
Wallpaper pauses itself immediately The status line under the title names the reason (full-screen app, battery, locked session, RDP). v1.1 no longer pauses on battery or hides while paused by default — if you upgraded from 1.0, reset those two checkboxes in the Automation tab.
Wallpaper is blurry on one of two monitors Windows blends DPI-scaling when monitors have different scale factors; setting both monitors to the same scale gives pixel-perfect output.
Hotkey doesn't work The box turns red with the reason (invalid or already taken). Pick another combination.

6. Project layout

LiveWall/
├─ LiveWall.csproj          net8.0-windows, UseWPF + UseWindowsForms, WebView2 package
├─ app.manifest             asInvoker, PerMonitorV2 DPI, long paths
├─ App.xaml(.cs)            startup, single instance, tray, hotkeys, save debounce, exit
├─ MainWindow.xaml(.cs)     the whole settings UI (8 tabs) + all handlers
├─ Themes/Dark.xaml         dark theme: buttons, sliders, tabs, combos, checkboxes, cards
├─ Models/AppSettings.cs    settings model (INotifyPropertyChanged tree + change bubbling)
├─ Services/
│  ├─ WallpaperEngine.cs    host windows, renderers, pause/playlist state machines, watchdog
│  ├─ SystemState.cs        full-screen/maximized detection, battery + session-lock tracking
│  ├─ SettingsStore.cs      JSON persistence (with corrupt-file backup)
│  ├─ StartupManager.cs     HKCU Run autostart
│  ├─ HotkeyManager.cs      global hotkeys on a message-only window
│  └─ TrayService.cs        NotifyIcon + dark context menu
├─ Wallpaper/
│  ├─ WallpaperWindow.cs    host window + self-verifying attach (colour-patch probe)
│  ├─ WallpaperRenderer.cs  renderer contract + factory
│  ├─ VideoRenderer.cs      MediaElement playback
│  ├─ ImageRenderer.cs      images
│  ├─ ImageView.cs          fit/tile drawing for images & GIFs
│  ├─ GifAnimation.cs       hand-written GIF frame compositor
│  ├─ WebRenderer.cs        WebView2 (YouTube + web pages)
│  └─ PlayerPage.cs         embedded YouTube player host page
├─ Interop/
│  ├─ Native.cs             user32 P/Invokes
│  └─ DesktopAttacher.cs    WorkerW discovery, parenting, interactive mode
├─ Plugins/
│  ├─ PluginManifest.cs     plugin.json parsing + validation
│  ├─ PluginLoader.cs       collectible AssemblyLoadContext, SHA-256, state machine
│  ├─ PluginHost.cs         the host half of IPluginContext: registrar, actions, events, hotkeys
│  ├─ PluginSecurity.cs     trust store (%APPDATA%\LiveWall\plugin-trust.json)
│  ├─ PluginStorage.cs      per-plugin JSON key/value storage
│  ├─ PluginEventBus.cs     type-based publish/subscribe
│  ├─ PluginRendererAdapter.cs  bridges plugin renderers into the wallpaper window
│  └─ PluginWarningWindow   the mandatory "unverified plugins may harm your computer" dialog
└─ Util/                    logging, paths, display enumeration, YouTube URL parser, converter

7. Known limitations

  • Video decoding is whatever Media Foundation supports on your PC (no bundled codecs). For exotic formats, re-encode to H.264 MP4.
  • Interactive mode hides the desktop icons while active (a Windows layering constraint, same as every live-wallpaper app that offers clickable content).
  • YouTube playback is subject to YouTube's embedding rules and terms of service. Use it the way you'd use the website (this app is not downloading or redistributing anything).
  • Signing: the binary is unsigned, so SmartScreen may warn on first launch ("More info → Run anyway") and three VirusTotal engines flag the installer. Both go away with a code-signing certificate — see docs/antivirus.md.

8. Release notes

1.8.4 — a side menu that stays put

  • Fixed: the settings window's navigation strip jittered. The tab headers lived in a WPF TabPanel, which is built for a horizontal tab strip: it packs the headers into rows and re-measures the whole set whenever one of them changes size. Because the selected header is drawn semi-bold, picking an item re-flowed the list and the other entries jumped around.
  • The strip now hosts its tabs in a plain vertical StackPanel inside a scroll viewer: one item per row, every row the full width of the 196 px column, and a fixed width that does not depend on the selection. The accent bar, hover state and semi-bold label are unchanged.
  • The column also scrolls now, so the list still fits if a future release adds more sections (or on a very short window).
  • The app binaries are otherwise unchanged from 1.8.3.

1.8.3 — a setup that looks like the app

  • New installer UI. The setup window is now built to match LiveWall's own dark theme instead of the stock Modern-UI wizard: the app's #0E1116 background, the #6C8CFF accent, the icon's indigo-to-violet mark with its green dot, one page that does the choosing and one that confirms. No white header band, no "Nullsoft Install Script" footer, no native button row.
  • Flat controls. The three options (desktop shortcut, start with Windows, start after setup) are square tick boxes, the folder link and the Install/Update/Remove/Finish buttons are flat blocks, all clickable. Enter and Esc still work because the hidden native buttons remain the dialog's defaults.
  • Layout scales with DPI. The page measures the window at run time and places every control as a percentage of it, so 125%/150%/200% displays keep their proportions instead of clumping in a corner.
  • No InstFiles page at all. The files are written while the first page closes, so the window never flashes a second, differently themed screen; the second page simply follows.
  • Uninstaller follows the same look, with the "also delete my settings" choice now on the confirm page instead of a pop-up question.
  • Everything else is unchanged: per-user install with no UAC, in-place upgrades that keep %APPDATA%\LiveWall, same-version and downgrade prompts, /S silent installs, and version comparison on major.minor.patch.
  • The app binaries are unchanged apart from the version stamp.

1.8.2 — the cursor comes back

  • Fixed: 1.8.1 could make the mouse pointer vanish over the desktop. Two causes, both removed:
    • the page-level input guard asked for cursor: none, which tells Chromium to install a null cursor; when the pointer left the page nothing replaced it, and the desktop kept drawing nothing. The guard now asks for cursor: default — it still refuses hover feedback, but it never hides the pointer;
    • the native shield answered WM_SETCURSOR with "handled" without setting a cursor itself, so whatever cursor the page left behind stayed in place. It now puts the standard arrow back every time (LiveWall/Interop/Native.cs ▸ RestoreArrowCursor), including on mouse-leave and whenever the shield is switched off.
  • If the pointer ever does go missing on some configuration, Ctrl+Alt+I twice (interactive on/off) forces the shield through a full restore.

1.8.1 — the wallpaper stops listening to the mouse

  • Fixed: with a YouTube (or any web page) wallpaper, moving the cursor across the desktop made the player react — controls appearing on hover, links highlighting, the progress bar scrubbing, the cursor turning interactive. WebView2 hosts Chromium in real child windows inside the wallpaper window, and nothing that makes a WPF window click-through reaches them: the desktop icon layer is a transparent layered window, so the pointer fell straight through it onto the Chromium surface. Now, unless you turn on Interactive mode:
    • the wallpaper window answers WM_NCHITTEST with HTTRANSPARENT (this is the part that WS_EX_TRANSPARENT cannot do for a plain child window, and the part that previously let clicks stop at the wallpaper instead of reaching the desktop);
    • every Chromium child window is subclassed: HTTRANSPARENT, no mouse/pointer/wheel/touch messages, no cursor changes, no activation — plus WS_EX_TRANSPARENT so the hit test skips them in the first place (see LiveWall/Wallpaper/WebInputShield.cs);
    • as a second layer, the page itself gets pointer-events: none and a capture-phase blocker for wheel/drag/selection, so nothing can show a hover state even if a message slips through. Interactive mode removes all three layers again, and the diagnostics report now says which state the web surface is in (web input: blocked (mouse pass-through, N window(s) shielded)).
  • The desktop icons keep their normal behaviour: clicks over the wallpaper still land on the desktop, never on the page.

1.8.0 — plugins

  • Plugin system with overlay, renderer, filter, settings-page, command, tray and hotkey extension points, a hash-pinned trust store, and a mandatory warning before anything runs.
  • LiveWall.Sdk, a complete example plugin (samples/ClockOverlayPlugin) and a developer guide (docs/plugins/), shipped inside the installer.