libvw · Wayland × Vulkan
Your desktop, drawn on the GPU.
vw builds bars, docks, notification centres, launchers, lock screens and ordinary windows. Describe a surface in C++ or Lua every frame; vw keeps state, animates it, and renders it with Vulkan compute.
One function per surface
No widget tree to keep in sync. The build function runs again after input, events and on its refresh interval; anything that must survive — scroll offsets, text fields, tweens — is keyed by id.
#include <vw/vw.hpp>
int main() {
vw::App app([](vw::Ui& ui) {
const bool playing = vw::mpris::available();
ui.rectangle({.width = 220, .height = 56, .radius = 28,
.color = vw::rgb(0x263b4d)});
ui.text({.text = playing ? "Now playing" : "Quiet",
.font = "Roboto Flex", .size = 17,
.color = vw::rgb(0xd2e5ff),
.place = {.x = 24, .y = 17}});
ui.surface({.anchor = vw::anchor::top, .margin = {12, 0, 0, 0}});
});
app.on_event(vw::mpris::event_fd(), vw::mpris::drain_events);
return app.run();
}A layer surface anchored to the top edge, rebuilt whenever a media player changes.
How a frame happens
- 1Build
Your function describes the whole surface through a Ui, from scratch.
- 2Scene
Rectangles, shaped text, images and input regions, compared to the last one.
- 3Compute
Vulkan compute shaders rasterise it, rounded corners and all, in scene order.
- 4Present
A linear dma-buf goes to the compositor as a layer surface, window or lock.
What's in the box
Widgets, layout and motion, plus the services a shell needs — each one an event source the loop can wait on.