1 unstable release
Uses new Rust 2024
| 0.1.0 | Mar 6, 2026 |
|---|
#380 in GUI
125KB
3K
SLoC
orilla
orilla is a Rust-based window manager for the river Wayland compositor.
Inspired by XMonad, it exists for a simple reason: layout is ergonomics. How your tools are arranged affects how well you can use them.
(too much) more: https://man.sr.ht/~hokiegeek/orilla/#philosophy
features
- Dynamic tiling for river, configured in Rust.
- Composable layouts with predictable keyboard-driven navigation.
- Strong integration with river protocol behavior and seat/input handling.
- Two entry points: code-first
orillalibrary and TOML-basedorilla-run.
Would you like to know more?: https://man.sr.ht/~hokiegeek/orilla/roadmap.md
crates
This repo is split into two crates:
orilla(crates/orilla): the core library crate and primary interface for building your window manager config in Rust.orilla-run(crates/orilla-run): a convenience binary that loads a simple TOML config and runsorilla, useful for bootstrapping intoorilla.
how to get started
Use the cargo-generate template to scaffold a code-first orilla config:
# generate it
cargo install cargo-generate
cargo generate --git https://git.sr.ht/~hokiegeek/orilla.git --subfolder template --name my-orilla
# build it
cd my-orilla
cargo build --release
Then:
- Edit
src/main.rsin your generated project to match your keybindings and layout preferences. - Add this to
~/.config/river/init:<location of your file>/my-orilla/target/release/my-orilla &
configuration
orilla is configured in Rust. Your generated project is just a normal Rust binary that builds an Orilla instance, sets options, registers keybindings, and calls run().
A minimal example:
use orilla::prelude::*;
fn main() {
let tags: Vec<char> = "1234567890".chars().collect();
let mut wm = orilla::Orilla::new()
.layouts(layout_set![layouts::Tall::new(), layouts::Full])
.borders(Borders::new(2, "#9e9e9e80").focused("#008080e6").urgent((3, "#ff0000")))
.tags(tags.iter().map(|&t| t.to_string()).collect())
.keys(vec![
Keybinding::new(Mods::Super, 'm', action::focus_primary()),
Keybinding::new(Mods::Super, 'n', action::focus_next()),
Keybinding::new(Mods::Super, 'e', action::focus_prev()),
Keybinding::new(Mods::Super | Mods::Shift, 'c', action::close()),
Keybinding::new(Mods::Super, keysyms::space, action::cycle_layout()),
Keybinding::new(Mods::Super, 't', action::spawn("fuzzel")),
Keybinding::new(Mods::Super, keysyms::Return, action::spawn("foot")),
// Bindings related to the 'Tall' layout
Keybinding::new(Mods::Super, keysyms::comma, action::message(Tall::IncMainCount)),
Keybinding::new(Mods::Super, keysyms::period, action::message(Tall::DecMainCount)),
Keybinding::new(Mods::Super, 'h', action::message(Tall::ShrinkMain)),
Keybinding::new(Mods::Super, 'l', action::message(Tall::GrowMain)),
Keybinding::new(Mods::Super, 'm', action::message(Tall::FocusMain)),
]
.into_iter())
.chain(tags.iter().map(|&tag| Keybinding::new(Mods::Super, tag, action::switch_tag(tag.to_string()))))
.chain(tags.iter().map(|&t| Keybinding::new(Mods::Super | Mods::Shift, t, action::shift_tag(t.to_string()))))
.collect());
if let Err(e) = wm.run() {
eprintln!("orilla failed: {e}");
std::process::exit(1);
}
}
Dig deeper: https://man.sr.ht/~hokiegeek/orilla/configuration.md
Dependencies
~13–22MB
~352K SLoC