Skip to content

biboete/Bibo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Bibo

A minimal, native Windows desktop wallpaper manager — built with WPF on .NET 8, Magick.NET for decoding every common image format (including WebP), and a clean MVVM architecture. The interface is a restrained grey/black/white "Slate" design in the spirit of the Zen browser and the Zed editor: monochrome chrome, hairline borders, and the only colour on screen coming from your images.

Bibo also sets live video wallpapers (mp4/mov/webm/mkv/avi/wmv) — looping, muted, and rendered straight onto the desktop with libVLC (hardware-decoded, and auto-paused while a full-screen game is in front so it costs no FPS) in the style of the Lively app.

Bibo — gallery and docked preview

The visual design was explored as four competing mockups and chosen by an independent critique pass — see design/mockups/DESIGN-DECISION.md.


Features

  • Import via a multi-select file picker and drag-and-drop onto the window (folders are accepted and scanned recursively). Accepted images: jpg, jpeg, png, gif, bmp, webp, tif, tiff. Accepted video: mp4, m4v, mov, webm, mkv, avi, wmv. Unsupported or corrupt files are skipped with a clear, counted message.
  • Gallery — a scrollable grid of thumbnails with a Large / Comfort / Compact density toggle. Thumbnails are decoded with Magick.NET, downscaled, and cached on disk, so a library of hundreds of images stays fast across sessions. Filename + resolution show on hover.
  • Preview — click a thumbnail to open a docked preview with the full image and its metadata (dimensions, file size, format).
  • Set as wallpaper — converts the selected image to a 24-bit BMP under %AppData%\Bibo\current_wallpaper, writes the fit-mode registry values (WallpaperStyle / TileWallpaper), and applies it via the Win32 SystemParametersInfo call (the return value is checked). Fit modes: Fill / Fit / Stretch / Tile / Center.
  • Live video wallpaper — a video tile shows a poster frame with a ▶ duration badge, and selecting it offers Set as live wallpaper. A lightweight host process plays the looping, muted clip on the desktop's WorkerW layer — behind your icons — via libVLC, with the fit mode mapped to libVLC crop/aspect (cover / contain / stretch). It pauses automatically for full-screen apps and restarts at login (an HKCU\…\Run entry). A Live indicator in the status bar stops it in one click, and setting a static image turns it off.
  • Persistence — imported paths and settings are remembered between sessions in %AppData%\Bibo\library.json. Moved or deleted files show a first-class Missing state with Locate… / Remove recovery instead of crashing.
  • Responsive UI — all decoding, thumbnailing and I/O run on background threads and marshal back to the UI thread for binding; bitmaps are frozen for safe cross-thread use.

Tech stack

Concern Choice
Language / runtime C# on .NET 8 (net8.0-windows, x64)
UI WPF (XAML), MVVM, no third-party MVVM toolkit
Image decoding Magick.NET-Q8-AnyCPU (14.14.0)
Video / live wallpaper LibVLCSharp (3.8.2) + VideoLAN.LibVLC.Windows (3.0.20), rendered on the desktop WorkerW layer
Persistence System.Text.Json (atomic temp-file + move)
Wallpaper Win32 SystemParametersInfo P/Invoke + HKCU\Control Panel\Desktop; live video via a --wallpaper-host process

Prerequisites

Newer runtime already installed? The project sets <RollForward>Major</RollForward>, so a framework-dependent run will roll forward onto a newer major runtime (e.g. .NET 10) when the .NET 8 runtime isn't present. The self-contained publish below bundles its own .NET 8 runtime and needs nothing installed on the target machine.


Run from source

# from the repository root
dotnet run --project src/Bibo/Bibo.csproj

Build only:

dotnet build src/Bibo/Bibo.csproj -c Release

Tests

dotnet test

Unit tests cover the deterministic logic layer — fit-mode → registry mapping, supported-format detection and image/video classification, video resolution/duration formatting, the JSON library store (round-trip, missing-file, corrupt-file quarantine), and the Magick.NET-backed image service (metadata, validation, thumbnail generation, wallpaper BMP conversion).


Publish a single-file .exe

Produces one self-contained, single-file x64 Bibo.exe (no .NET install required on the target machine; native Magick.NET libraries are bundled and extracted on first run):

dotnet publish src/Bibo/Bibo.csproj -p:PublishProfile=SingleFile

Output: src/Bibo/bin/publish/Bibo.exe.

The publish settings live in src/Bibo/Properties/PublishProfiles/SingleFile.pubxml (SelfContained, PublishSingleFile, IncludeNativeLibrariesForSelfExtract, EnableCompressionInSingleFile).

The published Bibo.exe is already sendable as-is — no install, no admin, no .NET needed on the recipient's machine. Just hand them the file.


Build the installer (instant-launch)

The custom themed installer dist/Bibo-Setup.exe deploys Bibo as loose ReadyToRun files into %LocalAppData%\Programs\Bibo, so the installed app launches instantly — there's nothing to self-extract at startup (unlike the single packed exe above). It's a per-user install (no admin) with a Start-menu shortcut, an optional desktop icon, an Add/Remove-Programs entry, and a silent uninstaller. It also closes any running copy before upgrading.

Build it with one command:

powershell -ExecutionPolicy Bypass -File installer\build.ps1

That script (1) publishes the app as multi-file ReadyToRun (Folder.pubxml), (2) zips it, (3) embeds the zip in the installer (installer/BiboInstaller, a small themed WPF app), and (4) copies dist/Bibo-Setup.exe out.

Measured cold/warm launch: ~2.7 s / ~0.57 s for the installed loose-file build, vs ~3.7 s / ~0.78 s for the single packed exe.

Trade-off: the installed folder is ~187 MB of loose files (ReadyToRun is larger than packed IL) — disk space in exchange for fast, self-extract-free launches. A legacy Inno Setup script is kept as a plain alternative.

SmartScreen: both the standalone exe and the installer are unsigned, so Windows shows "More info → Run anyway" on first launch. Code-sign with an Authenticode certificate to remove it.


Where Bibo stores data

Everything lives under %AppData%\Bibo:

Path Purpose
library.json Imported image/video paths + settings (schema version, fit mode, thumbnail size, active live-wallpaper path)
thumbnails\ Cached thumbnail PNGs — image thumbnails and video poster frames (keyed by source path + size + last-write time)
current_wallpaper\ The materialized BMP that Windows points at as the static wallpaper

library.json shape:

{
  "version": 1,
  "images": [ { "path": "C:\\Users\\me\\Pictures\\sunset.webp", "addedUtc": "2026-06-08T12:00:00+00:00" } ],
  "settings": { "fitMode": "Fill", "thumbnailMaxEdge": 320, "videoWallpaperPath": null }
}

A live video wallpaper additionally registers HKCU\Software\Microsoft\Windows\CurrentVersion\Run\Bibo Wallpaper so it resumes at login; stopping it (or applying a static image) removes that entry.


Project layout

src/Bibo/
├── Bibo.csproj                 # net8.0-windows, WPF, x64, Magick.NET
├── app.manifest                # PerMonitorV2 DPI awareness
├── App.xaml(.cs)               # composition root + global error handling
├── MainWindow.xaml(.cs)        # the Slate UI + drag/drop + viewport thumbnail loading
├── Views/                      # WallpaperHostWindow — the borderless libVLC live-wallpaper host
├── Common/                     # ObservableObject, RelayCommand, AsyncRelayCommand
├── Interop/                    # SystemParametersInfo, WorkerW desktop attach, shell video thumbnails/props
├── Models/                     # FitMode, MediaKind, AppPaths, ImageMetadata, VideoInfo, SupportedFormats, LibraryState
├── Services/                   # ImageService, VideoService, ThumbnailCache, WallpaperService, VideoWallpaperService, LibraryStore, DialogService
├── ViewModels/                 # MainViewModel, ImageItemViewModel
├── Converters/                 # Bool/Null → Visibility
├── Themes/                     # Tokens.xaml (palette/type) + Controls.xaml (styles)
└── Properties/PublishProfiles/ # SingleFile.pubxml
tests/Bibo.Tests/              # xUnit tests for the logic + service layer
design/mockups/                 # the four explored designs, renders, and the decision record

Architecture notes

  • MVVM with hand-wired composition — the object graph is small, so App.OnStartup constructs the services and the MainViewModel directly (no DI container). View models depend on interfaces (IImageService, IThumbnailCache, IWallpaperService, ILibraryStore, IDialogService) so the logic stays unit-testable.
  • Thumbnails — WPF has no built-in virtualizing wrap panel, so the gallery uses a WrapPanel (cheap, empty containers) and decodes a tile's thumbnail only when it scrolls into (or near) the viewport. With the on-disk cache this keeps memory bounded and scrolling smooth for hundreds of images.
  • Resilience — JSON loads tolerate a missing or corrupt file (the bad file is quarantined as library.json.corrupt); saves are atomic; the wallpaper call checks its Win32 return value and surfaces failures; a global handler keeps the app alive on unexpected errors.
  • Live wallpaper hostBibo.exe --wallpaper-host "<video>" <Fit> runs the same executable in a headless mode that attaches a borderless libVLC window to the desktop WorkerW layer (handling both the Windows 10 sibling and the Windows 11 child-of-Progman variants) so the video renders behind the icons. The main app starts/stops this process via a named stop event and registers it under HKCU\…\Run for login persistence; a foreground watcher pauses playback while a full-screen app is in front so it costs no FPS. Video poster frames and properties come from the Windows shell (IShellItemImageFactory / IShellItem2), not from decoding the clip.

About

A minimal Windows desktop wallpaper manager - images + libVLC live video wallpapers (WPF/.NET 8).

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages