Wallopino
Wallopino is a Windows-focused Rust library for turning an ordinary application window into an interactive desktop wallpaper.
Instead of forcing your application to implement a traditional wallpaper renderer, Wallopino works with an existing HWND and integrates it into the Windows desktop window hierarchy. This makes it possible to build interactive live wallpapers, desktop visualizations, WebView-based backgrounds, animated scenes, and other desktop experiences using the UI technology or rendering engine you already like.
Status:
0.1.0β early-stage / experimental API.
Showcase
See Wallopino in action. Each example below is a normal application window transformed into an animated desktop wallpaper.
π¦ Ferris
Native Macroquad rendering with desktop attachment and interactive mouse input.

β¨οΈ Keyboard
Interactive WebView content built with Wry/Tao, attached to the desktop with forwarded mouse input.

π Neon Village
A large animated WebView/Three.js-style scene running directly as an interactive desktop background.

β¨ Strings
An animated WebView experience attached to the Windows desktop.

π³οΈ Wormhole
A WebView-based animated black-hole scene running behind the desktop icons.

Why Wallopino?
Windows desktop wallpaper is more than a single background image. The Shell maintains a hierarchy of windows for the desktop, icons, wallpaper surfaces, and other system UI.
Wallopino provides the low-level plumbing needed to work with that hierarchy:
- Attach an existing window behind the desktop icons.
- Work across multiple monitors.
- Normalize monitor coordinates for a virtual desktop.
- Watch the desktop hierarchy and repair wallpaper z-order changes.
- Capture global mouse and keyboard input.
- Forward captured input as normal Windows messages to the target window.
- Redirect forwarded events to a descendant window when frameworks such as WebView2 need it.
- Track mouse button state for frame-based applications.
- Clean up the wallpaper integration when the application shuts down.
The core idea is simple:
Your application
β
β creates a normal HWND
βΌ
Wallopino
β
βββ Attach HWND to Windows desktop layer
β
βββ Keep desktop z-order stable
β
βββ Optionally forward mouse/keyboard input
βΌ
Interactive desktop wallpaper
Features
π₯οΈ Window-to-desktop attachment
Attach an existing window to the Windows desktop layer with:
let mut wallpaper = auto_attach?;
Wallopino discovers the relevant desktop windows and configures the target HWND accordingly.
π§± Desktop hierarchy / z-order watching
Desktop window topology can change while Windows is running. Wallopino can start a background watcher to detect relevant changes and restore the wallpaper placement:
wallopino.start_watcher?;
You can stop the watcher explicitly with stop_watcher().
π±οΈ Global mouse input forwarding
EventForwarder can capture low-level mouse input and forward it to your wallpaper window:
let forwarder =
new?;
let controller = forwarder.forward_events?;
Supported mouse events include movement, left/right/middle button press/release, and wheel scrolling.
β¨οΈ Keyboard input forwarding
Keyboard forwarding can be enabled independently:
let forwarder =
new?;
let controller = forwarder.forward_events?;
Mouse and keyboard forwarding can also be enabled together.
π― Descendant-window targeting
Some UI frameworks do not process input on the top-level HWND. Wallopino can search the target's descendants for a specific window class and use that child as the forwarding destination:
let forwarder = new?;
This is particularly useful for WebView2/Wry-style applications.
π₯οΈ Multi-monitor support
Wallopino can enumerate connected monitors and normalize their coordinates into a virtual-desktop coordinate system:
let monitors = wallpaper.enumerate_monitors?;
for in monitors.iter.enumerate
It also exposes monitor work-area information through MonitorInfo.
π±οΈ Frame-based mouse state
For render loops and game-style applications, AttachWindow can track the current and previous state of five mouse buttons:
wallpaper.update_mouse_state;
if wallpaper.is_mouse_button_pressed
if wallpaper.is_mouse_button_down
if wallpaper.is_mouse_button_released
Button indices are:
| Index | Button |
|---|---|
0 |
Left |
1 |
Right |
2 |
Middle |
3 |
X1 |
4 |
X2 |
Installation
Wallopino is currently developed as a Windows-specific crate.
From GitHub
[]
= { = "https://github.com/amir-frjn/wallopino" }
If your application directly uses Windows types such as HWND, add the windows crate as a direct dependency too:
[]
= { = "https://github.com/amir-frjn/wallopino" }
= { = "0.61", = [
"Win32_Foundation",
"Win32_UI_WindowsAndMessaging",
] }
Wallopino currently uses the windows crate version 0.61 internally.
Quick Start
The following example shows the basic Wallopino workflow.
use Duration;
use AttachWindow;
The hwnd is the normal Windows handle of the window you want to use as the wallpaper.
For example, frameworks that expose a native Windows handle, such as tao, can provide the HWND for you.
Interactive Wallpaper
Wallopino becomes especially interesting when the wallpaper is interactive.
A typical application has two independent pieces:
- Attach the window to the desktop
- Forward input to that window when required
use Duration;
let event_forwarder =
new?;
let controller = event_forwarder.forward_events?;
let mut wallpaper =
auto_attach?;
wallpaper.start_watcher?;
// ... run your application ...
controller.pause;
controller.resume;
// Shut down the forwarding session when finished.
controller.exit?;
The forwarding controller is thread-safe and can pause, resume, query, or terminate an active forwarding session.
WebView / Wry Example
One of Wallopino's useful applications is combining it with a WebView.
The repository contains examples built with wry and tao. The important part is still very small:
use Duration;
use WindowExtWindows;
let hwnd = window.hwnd;
let event_forwarder =
new?;
event_forwarder.forward_events?;
let mut wallpaper =
auto_attach?;
wallpaper.start_watcher?;
For WebView-based windows, the top-level window may not be the element that actually processes mouse messages. The optional descendant class-name parameter lets Wallopino target an appropriate child window instead.
Examples
The examples/ directory contains several complete demos.
| Example | What it demonstrates | Video |
|---|---|---|
ferris.rs |
Native rendering with Macroquad, desktop attachment, and interactive mouse input | βΆοΈ Demo |
keyboard.rs |
Interactive WebView content with Wry/Tao, desktop attachment, and forwarded mouse input | βΆοΈ Demo |
neonvillage.rs |
A large WebView/Three.js-style animated scene running as an interactive desktop background | βΆοΈ Demo |
strings.rs |
A WebView animation attached to the desktop | βΆοΈ Demo |
wormhole.rs |
A WebView-based animated black-hole scene attached to the desktop | βΆοΈ Demo |
Run an example with:
or:
The examples are intentionally useful as reference implementations: each one shows how a normal application window can be converted into a desktop background rather than building a dedicated wallpaper renderer from scratch.
Architecture
At a high level, Wallopino is split into two responsibilities.
AttachWindow
AttachWindow is responsible for the desktop side of the problem.
It can:
- discover the relevant Windows desktop windows,
- select a monitor or the virtual desktop,
- configure the target
HWND, - enumerate monitors,
- calculate desktop-relative mouse coordinates,
- maintain mouse button state,
- watch the wallpaper's z-order,
- stop the watcher,
- restore desktop state during cleanup.
The most convenient entry point is:
auto_attach
For more control, the lower-level flow is:
AttachWindow::initialize()
β
βΌ
enumerate_monitors()
β
βΌ
get_wallpaper_target(...)
β
βΌ
configure_wallpaper_window(...)
β
βΌ
start_watcher(...)
EventForwarder
EventForwarder handles input.
Internally it uses low-level Windows hooks to capture selected input events, then forwards those events as Windows messages to the selected target window.
Its lifecycle looks like:
EventForwarder::new(...)
β
βΌ
forward_events()
β
βΌ
ForwardingController
/ | \
/ | \
pause resume exit
This separation is useful because not every wallpaper needs input forwarding. Static visualizations can use only AttachWindow, while interactive wallpapers can opt into EventForwarder.
Input Events
Wallopino exposes an Events enum representing captured input:
use Events;
let event = LeftDown ;
println!;
Current event categories include:
Mouse
MoveLeftDownLeftUpRightDownRightUpMiddleDownMiddleUpScroll
Keyboard
KeyDownKeyUp
Mouse coordinates are converted from screen coordinates toward the target window's client coordinate system before the corresponding Windows message is posted.
Controlling Input Forwarding
ForwardingController lets you manage a running forwarding session:
let controller = forwarder.forward_events?;
// Temporarily stop forwarding.
controller.pause;
// Continue forwarding.
controller.resume;
// Check the current state.
if controller.is_forwarding
// Permanently terminate the forwarding session.
controller.exit?;
Dropping the controller also signals the forwarding thread to terminate.
Cleanup
When the wallpaper is no longer needed, you can explicitly clean up the attachment:
wallpaper.cleanup?;
The watcher can also be stopped directly:
wallpaper.stop_watcher?;
AttachWindow also cleans up its watcher when it is dropped.
static_edge_mode
auto_attach accepts a second boolean parameter:
auto_attach
This controls the library's static-edge attachment mode.
The examples use true, particularly for applications where keeping the wallpaper anchored to the desktop hierarchy is important.
Platform Support
Wallopino is currently Windows-only.
The crate is designed around the Win32 desktop window hierarchy and uses the Windows API for:
- window discovery,
- desktop window management,
- monitor enumeration,
- input hooks,
- cursor state,
- z-order maintenance,
- desktop wallpaper restoration.
The project currently targets modern Windows desktop environments and is primarily developed/tested around Windows 10 and Windows 11.
Requirements
- Windows
- Rust (edition 2024)
- A Windows desktop application that exposes a native
HWND
Optional libraries such as wry, tao, or macroquad can be used alongside Wallopino depending on how you render your wallpaper.
Use Cases
Wallopino can be used as a foundation for:
- Interactive live wallpapers
- WebView-based desktop backgrounds
- Three.js / Canvas visualizations
- Macroquad or other native rendering engines
- Animated desktop widgets
- Audio-reactive desktop scenes
- Experimental desktop environments
- Applications that need a normal window to live behind desktop icons
The important distinction is that Wallopino does not dictate how your wallpaper is rendered.
You can render it using native graphics, a game engine, WebView, HTML/CSS/JavaScript, or another window-based technologyβas long as you have a window handle to attach.
Project Layout
wallopino/
βββ assets/
β βββ Ferris.mp4
β βββ Keyboard.mp4
β βββ Neonvillage.mp4
β βββ Strings.mp4
β βββ Wormhole.mp4
βββ examples/
β βββ ferris.rs
β βββ keyboard.rs
β βββ neonvillage.rs
β βββ strings.rs
β βββ wormhole.rs
βββ src/
β βββ platform/
β β βββ windows/
β βββ lib.rs
βββ Cargo.toml
βββ LICENSE
βββ README.md
Public API
The main items re-exported by the crate are:
AttachWindow
EventForwarder
ForwardingController
Events
functions
For detailed API documentation, see the Rust documentation generated from the crate source.
Safety
Wallopino interacts directly with Win32 APIs and therefore contains unsafe code internally.
Because the library operates on real Windows handles and global input hooks:
- pass valid window handles,
- ensure your target window remains alive while it is being used,
- stop forwarding sessions when they are no longer needed,
- be mindful that global input hooks affect the entire desktop session.
Wallopino does not try to hide the low-level nature of this functionality; it wraps the Windows-specific plumbing so the application can focus on the wallpaper itself.
Contributing
Issues, experiments, improvements, and Windows-specific findings are welcome.
Because the project is still young, API design may evolve between releases.
For development:
License
Wallopino is licensed under the MIT License.
Credits & Inspiration
Wallopino was created as a Rust-oriented exploration of the Windows desktop window hierarchy and the techniques required to build interactive desktop backgrounds.
Some example visuals are inspired by public CodePen projects; the example source files contain the relevant attribution and inspiration notes.
Roadmap
Some directions that fit naturally with the project include:
- Better multi-monitor wallpaper management
- More robust desktop topology recovery
- Cleaner high-level APIs for wallpaper engines
- Improved event-target discovery for WebView frameworks
- More rendering-framework examples
- Better automated testing around Windows desktop state changes
- Expanded platform abstraction for future non-Windows implementations
The idea in one line
Build your desktop experience as a normal window. Let Wallopino put it where the wallpaper belongs.