Learn Miracle-WM's WASM plugin architecture. Step-by-step tutorial for writing custom window rules, keybindings, and animations. Rust API vs. WebAssembly explained.
What Is Miracle-WM and Why Does It Matter?
Miracle-WM is a Wayland compositor inspired by i3 and Sway, built on Canonical’s Mir project. Unlike traditional window managers that lock you into compiled binaries or fragile scripting, Miracle-WM introduces a WebAssembly (WASM) plugin system – allowing you to modify window management, animations, and keybindings with portable, sandboxed code.
This guide explains the core concepts of Miracle-WM’s plugin architecture, shows you how to write a simple plugin, and highlights safety practices. Target audience: intermediate Linux users comfortable with the command line and basic programming concepts.
Prerequisites
- A Linux distribution with Wayland support (most modern distros)
- Mir libraries (installed automatically with Miracle-WM on supported distros)
- Basic familiarity with Rust or WebAssembly (not mandatory, but helpful)
- A text editor
Core Concepts: Why WebAssembly?
- Static configuration files (JSON, YAML) – limited logic
- IPC sockets – powerful but insecure and fragile
- Built-in scripting – vendor-specific and often deprecated
- Sandboxed execution – plugins cannot crash the compositor or access arbitrary files
- Hot reloading – change behavior without restarting your session
Step-by-Step: Your First Miracle-WM Plugin
1. Install Miracle-WM
# Example for Debian/Ubuntu (adjust for your distro) sudo apt install meson ninja-build libmir-dev libwayland-dev git clone https://github.com/miracle-wm-org/miracle-wm cd miracle-wm meson build && ninja -C build sudo ninja -C build install
2. Understand the Plugin API (Rust)
cargo new my-miracle-plugin --lib cd my-miracle-plugin
[package] name = "my-miracle-plugin" version = "0.1.0" edition = "2021" [lib] crate-type = ["cdylib"] [dependencies] miracle-wm-api = "0.9"
3. Write a Simple Plugin
use miracle_wm_api::prelude::*; #[no_mangle] pub extern "C" fn on_window_created(window: &mut Window) -> PluginResult { // Log when a window appears (viewable in miracle-wm logs) eprintln!("New window created: {}", window.title()); // Resize all new windows to 800x600 window.set_size(800, 600); PluginResult::Success } #[no_mangle] pub extern "C" fn on_key_press(key: &KeyEvent) -> PluginResult { if key.modifiers.contains(Modifiers::SUPER) && key.sym == "q" { // Close focused window when Super+Q is pressed let focused = get_focused_window(); if let Some(mut win) = focused { win.close(); } } PluginResult::Success }
4. Compile to WebAssembly
rustup target add wasm32-unknown-unknown cargo build --target wasm32-unknown-unknown --release
5. Load the Plugin in Miracle-WM
[plugins] paths = [ "/home/<username>/my-miracle-plugin/target/wasm32-unknown-unknown/release/my_miracle_plugin.wasm" ] [plugins.settings] enable_logging = true
# Check Miracle-WM logs journalctl --user -u miracle-wm -f
Common Pitfalls and How to Avoid Them
- Why: WASM traps (e.g., out-of-bounds memory) are caught but may not be logged clearly.
- Fix: Wrap plugin logic in try/catch (Rust catch_unwind) and return PluginResult::Error.
- Why: Miracle-WM processes plugins after internal bindings by default.
- Fix: Set priority = 10 in config under [plugins.settings] to run plugins first.
- Why: Each window event triggers all plugins synchronously.
- Fix: Use async plugin stubs (if your language supports WASM async) or combine logic into fewer plugins.
4. Cursor theme ignored after plugin load
- Why: Some plugins override cursor settings inadvertently.
- Fix: Set [cursor] theme explicitly in config:
[cursor] theme = "Adwaita" size = 24
Beyond Basics: The New Rust API
- Direct access to Mir internals (lower latency)
- No WASM compilation step
- Ability to use system libraries
use miracle_wm_rust_api::{Compositor, Plugin}; struct MyPlugin; impl Plugin for MyPlugin { fn init(&mut self, compositor: &mut Compositor) { compositor.on_window_created(|win| { println!("Window created: {}", win.title()); }); } }
Further Reading
- Built-in documentation: man miracle-wm and miracle-wm --help-plugins
- API reference: info miracle-wm-api (if installed)
- Example plugins: /usr/share/doc/miracle-wm/examples/ (after installation)
- Community: GitHub Discussions at github.com/miracle-wm-org/miracle-wm

Nenhum comentário:
Postar um comentário