Files
2026-11-04 14:29:22 -06:00

5.7 KiB

LiveWall plugin SDK

LiveWall 1.8.0 and later can be extended by plugins: .NET 8 assemblies that LiveWall loads at start-up and hands a context object. A plugin can add wallpaper renderers, draw on the desktop, add settings pages, add commands and tray entries, register hotkeys, rewrite wallpaper requests, and read the same events the app itself uses.

Plugins are third-party code. They run inside LiveWall's process with your rights. LiveWall does not review, sign or sandbox them, and unverified plugins may cause harm to your computer. The user is shown a warning listing the plugin's exact file hash and every permission it declared before it is allowed to run — see security.md.


Contents

Document What it covers
getting-started.md From an empty folder to a running plugin in ten minutes
api-reference.md Every interface, member and enum in LiveWall.Sdk
extension-points.md Overlays, renderers, filters, pages, commands, hotkeys — with the caveats
events.md The event catalogue, threading rules and lifetime
security.md Permissions, trust, hashes, the warning dialog, threat model
packaging.md Folder layout, versioning, checksums, distribution, updates
troubleshooting.md "My plugin does not load", reading the log, unload rules
examples.md Copy-paste recipes for the common shapes

The SDK itself is LiveWall.Sdk.dll — a small contract assembly. Plugins reference it and nothing else; LiveWall.exe is deliberately not a dependency.


What a plugin can change

Extension point Interface Typical use
Desktop overlay IWallpaperOverlay Clock, now-playing badge, visualiser, watermark, fps counter
Wallpaper renderer IWallpaperRendererPlugin + IWallpaperRenderer Shaders, emulators, animated 3D scenes, a custom video pipeline
Wallpaper filter IWallpaperFilter Resolve short links, pick a random source, block changes, add metadata
Settings page IPluginSettingsPage Your own configuration UI inside LiveWall
Command PluginCommand "Next quote", "Toggle rain", anything the user can trigger
Tray entry PluginCommand + TrayMenu permission Same commands, reachable with two clicks
Hotkey PluginHotkey Global shortcut for a plugin action
Events IPluginEvents React to wallpaper/playback/session changes
Host actions IHostActions Set the wallpaper, play/pause, notify, open settings
Storage IPluginStorage Persist your own JSON state, own folders

Everything is registered through IPluginContext.Extensions inside Initialize. There is no "unregister everything" step: LiveWall drops all of a plugin's registrations when it unloads it.


How loading works (short version)

%APPDATA%\LiveWall\plugins\
└── com.example.clock\            ← one folder per plugin, any name
    ├── plugin.json               ← identity + permissions (required)
    ├── ClockOverlayPlugin.dll    ← entry assembly
    └── (any other files you need)
  1. LiveWall scans the plugin folder at start-up (and whenever the user presses Rescan).
  2. plugin.json is validated: API version, host version, optional checksum.
  3. Plugins the user has not enabled stay on disk, unloaded, listed in Plugins ▸ Installed plugins.
  4. Enabling runs the warning dialog. Only after the user accepts is the assembly loaded — into a collectible AssemblyLoadContext — and ILiveWallPlugin.Initialize(context) called.
  5. Any exception in Initialize marks the plugin Failed and shows the message. The app keeps running; a plugin can never take LiveWall down.

Full details in packaging.md and troubleshooting.md.


Quick start

dotnet new classlib -n MyPlugin -f net8.0-windows
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0-windows</TargetFramework>
    <UseWPF>true</UseWPF>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
  <ItemGroup>
    <ProjectReference Include="path\to\LiveWall.Sdk\LiveWall.Sdk.csproj">
      <Private>false</Private>
    </ProjectReference>
  </ItemGroup>
</Project>
using LiveWall.Sdk;

public sealed class MyPlugin : ILiveWallPlugin
{
    public void Initialize(IPluginContext context)
        => context.Host.ShowNotification("MyPlugin", "Hello from the wallpaper!");

    public void Shutdown() { }
}
{
  "id": "com.example.myplugin",
  "name": "My plugin",
  "version": "1.0.0",
  "author": "you",
  "description": "Does one small thing.",
  "apiVersion": "1.0",
  "entry": "MyPlugin.dll",
  "type": "MyPlugin",
  "minHostVersion": "1.8.0",
  "permissions": ["Commands"]
}

Copy the build output next to the manifest, then use Plugins ▸ Rescan and Enable.

The repository ships a complete, buildable example in samples/ClockOverlayPlugin/ that uses every extension point — read it next to extension-points.md.


Stability promise

The contracts live in LiveWall.Sdk and are versioned separately from LiveWall's own version:

  • PluginApi.Version (currently 1.0) is what plugin.json must declare.
  • Adding members to an existing interface would break compiled plugins, so new capabilities arrive as new optional interfaces, and the major version only changes if something must be removed.
  • minHostVersion in the manifest refuses to run on an older LiveWall instead of failing mysteriously.

See packaging.md.