A lightweight, hackable Linux desktop stack built around Wayland, Rust, and an HTML/CSS-driven native shell.
Luna combines a Rust Wayland compositor, a native C desktop shell powered by Luna UI, and an optional Rust libwayland-client implementation into one experimental desktop environment.
Luna is designed to be small enough to understand, flexible enough to theme, and low-level enough to experiment with the whole Linux desktop stackβfrom the Wayland wire protocol and DRM/KMS output to the menu bar, Dock, Launchpad, widgets, and application themes.
Project status: Luna Desktop is under active development. It is already usable as a development desktop/session, but the direct DRM/evdev path is still experimental and should be treated as such on real hardware.
Every image below is a real luna-shell framebuffer capture. The shell is built with its X11/EGL capture backend and run under Xvfb with the named skin; these are not browser previews or recreated mockups. The normal desktop can run through Luna's own KMS/Wayland hosts and does not require GLFW.
| Nocturne Atelier | Windows XP |
|---|---|
![]() |
![]() |
| Windows 95 | Classic Mac OS |
|---|---|
![]() |
![]() |
| BeOS | Amiga Workbench |
|---|---|
![]() |
![]() |
Regenerate the gallery with:
./tools/capture-shell-skins.sh| Luna Desktop | |
|---|---|
| Own the full stack | A Rust compositor handles the Wayland protocol, composition, input, DRM/KMS and optional browser streaming. |
| Native shell, web-like styling | luna-shell is a native C program, while Luna UI renders its interface from HTML/CSS-style layouts without embedding a browser. |
| Theme more than wallpaper | Skins can change shell layout, chrome placement, widgets, GTK styling, Qt styling and server-side decoration colors. |
| Multiple rendering paths | Run on DRM/KMS, use the software backend for development/VM work, or stream a Wayland app to a browser through the WebGL backend. |
| Wayland implementation playground | The repository includes both a Rust Wayland server and an optional Rust libwayland-client.so.0 replacement for protocol/runtime experiments. |
Clone with the Luna UI submodule:
git clone --recurse-submodules https://github.com/Berry-OS/luna-shell.git
cd luna-shellThe project uses Rust nightly and also builds native C components. Typical development dependencies include GCC, make, pkg-config, Wayland development tools (wayland-scanner), DRM/GBM/EGL/OpenGL, libinput, libudev, xkbcommon, D-Bus, X11 and OpenSSL development packages.
The desktop shell uses the distribution-provided libwayland-client by default. This is also the path used by the RPM packaging.
make build-desktop-systemIf your user/session already has access to the required DRM/input devices, the one-command DRI path is:
make desktop-systemFor a software-oriented development session:
make desktop-soft-systemThe direct DRI session currently expects a real Linux VT and direct DRM/input access. On machines where that requires elevated privileges, build as your normal user first, then launch the already-built session from a VT with the appropriate permissions, for example:
sudo LUNA_TTY=/dev/tty2 PROFILE=release ./luna-sessionKeep SSH or another recovery path available when testing a new compositor on physical hardware.
luna-session
βββ luna-compositor Rust Wayland compositor / window manager
βββ luna-shell Native C desktop shell + Luna UI
βββ luna-clipboard Wayland clipboard manager
βββ luna-tray-notify tray / notification helper
βββ applications GTK / Qt / SDL / other Wayland clients
| Component | Implementation | Role |
|---|---|---|
| Luna Desktop | Full session | The complete desktop environment presented to the user. |
luna-compositor |
Rust (wayland-server-rs) |
Wayland server, composition, window management, DRM/KMS, input and alternate rendering backends. |
luna-shell |
C + Luna UI | Menu bar/taskbar, Dock, Launchpad, Control Center, widgets, settings and desktop chrome. |
| Luna UI | ui/luna-ui submodule |
Native HTML/CSS-style layout and OpenGL rendering engine used by the shell. |
luna-clipboard |
C | Clipboard persistence/management for the Luna session. |
luna-tray-notify |
C | Tray/notification compatibility helper. |
wayland-client-rs |
Rust | Optional libwayland-client-compatible implementation for development and compatibility experiments. |
The internal codename Vespera still appears in parts of the source history, but the user-facing desktop is Luna.
ui/luna-shell.c is the main desktop shell. It renders the desktop using Luna UI and talks to the compositor over Wayland.
Current shell features include:
- translucent Luna menu bar / alternative taskbar and deskbar layouts
- Dock with hover magnification, running-app indicators and Trash
- Launchpad with application discovery, incremental search and keyboard shortcuts
- Control Center and system status UI
- Wi-Fi, Ethernet and Bluetooth integration
- notification toasts and tray/SNI integration
- desktop clock, system-statistics and weather widgets
- monitor/display integration
- language, keyboard-layout and NumLock settings
- keyboard-layout switching for multi-layout configurations
- About This Luna, Log Out, Restart and Shut Down flows
- XDG-based configuration, data, state, cache and runtime paths
Applications are launched as native Wayland clients. luna-session exports the usual desktop environment variables for GTK, Qt, Mozilla and SDL so applications can use the Luna compositor directly.
Dock and Launchpad entries can be redirected with LUNA_APP_<NAME> variables:
LUNA_APP_TERMINAL=foot ./luna-sessionThe shell layout and stylesheet can also be replaced for development:
LUNA_DESKTOP_LAYOUT=/path/to/layout.html \
LUNA_DESKTOP_CSS=/path/to/style.css \
./luna-shell --desktopEquivalent --layout / --css command-line options are available.
Open System Settings β Appearance β Desktop Skin to switch skins while Luna is running. The selected skin is saved in:
~/.config/luna-shell/settings.conf
Bundled skins currently include:
- Luna / Default
- Nocturne Atelier
- Windows XP
- Windows 95
- Classic Mac OS
- BeOS
- Amiga Workbench
A skin is not limited to shell colors. It can also describe chrome placement, GTK/Qt integration and compositor decoration preferences.
my-skin/
βββ skin.conf
βββ style.css
βββ layout.html
βββ gtk/<ThemeName>/ # optional GTK 3/4 theme
β βββ index.theme
β βββ gtk-3.0/gtk.css
β βββ gtk-4.0/gtk.css
βββ qt/
βββ style.qss # optional Qt stylesheet
βββ colors.conf
A minimal skin.conf can look like this:
name=My Skin
description=A custom Luna desktop skin
css=style.css
layout=layout.html
# Shell chrome
chrome=taskbar # taskbar | deskbar | menubar | luna
menubar_edge=bottom # top | bottom
menubar_height=34
dock_mode=hidden # float | hidden
# Application toolkit themes
gtk_theme=LunaWindows95
qt_style=Fusion
qt_qss=qt/style.qss
# Compositor/server-side decorations
titlebar_style=2 # 0 modern | 1 classic dots | 2 flat retro
titlebar_active=#000080
titlebar_inactive=#808080
titlebar_frame=#c0c0c0
prefer_ssd=1chrome=taskbar, for example, can move the shell strip to the bottom of the display and hide the floating Dock, while deskbar / menubar keep top-oriented chrome. This is handled by native Wayland layer-surface anchoring rather than CSS positioning alone.
When a skin supplies toolkit metadata, Luna can propagate its appearance to newly launched GTK/Qt applications and update compositor-side decoration colors as well.
Custom skins can be placed in:
~/.local/share/luna-desktop/skins/
/usr/local/share/luna-desktop/skins/
/usr/share/luna-desktop/skins/
or in a path named by LUNA_SKIN_PATH.
You can also select a skin explicitly:
luna-shell --desktop --skin windows-95
# or
LUNA_DESKTOP_SKIN=windows-95 luna-shell --desktopFor skin development, open skins/<name>/layout.html in a browser to iterate on the HTML/CSS structure, then use those same files in Luna. Custom layouts must preserve the shell element IDs expected by luna-shell so native actions stay connected.
Linux kernel
β
ββ DRM/KMS + evdev/libinput
β
βΌ
βββββββββββββββββββββββββββββββββ
β luna-compositor β
β Rust Wayland server β
β β
β software / DRI+GPU / WebGL β
ββββββββββββββββ¬βββββββββββββββββ
β Wayland
βββββββββΌββββββββββββββββ
β β β
βΌ βΌ βΌ
luna-shell GTK/Qt apps luna-clipboard
C + Luna UI
β
ββ HTML/CSS-style shell layouts + skins
Wayland is the internal desktop bus. A normal Luna session does not need Weston, Mutter or Xorg between Luna and native Wayland applications.
The compositor implements the Wayland wire protocol and object model directly in Rust rather than wrapping libwayland-server.
Highlights include:
wl_compositor,wl_subcompositor,wl_shm,wl_seat,wl_outputand data-device supportxdg_wm_basefor application windowszwp_linux_dmabuf_v1v4 / dmabuf feedback support- Luna shell/window-management IPC
- evdev input and VT handling
- software composition
- DRM/KMS output
- GPU-assisted rendering paths
- WebGL/WebSocket streaming backend
The repository also contains an experimental Rust implementation that builds a libwayland-client.so.0-compatible library and vendors compatible client headers.
It is useful for testing how far a desktop can go without the system client implementation, but it is not required for the recommended Luna shell build.
To explicitly build/run the shell against the vendored client implementation:
make desktop LUNA_WAYLAND_CLIENT=vendored| Command | Purpose |
|---|---|
make desktop-system |
Full DRI desktop using the system Wayland client library. |
make desktop-soft-system |
Software-backend desktop using the system Wayland client library. |
make desktop LUNA_WAYLAND_CLIENT=vendored |
DRI desktop while testing the Rust client implementation. |
make demo |
Start the compositor and connect the sample GTK app; writes compositor screenshots to /tmp/luna-compositor.ppm. |
make webgl |
Stream the sample GTK app through the compositor's browser backend. |
make webgl APP=gtk4-demo |
Run another GTK application through the WebGL backend. |
make rpm |
Build the source tarball and RPM package. |
make webgl
# then open http://localhost:8081/Or use the helper directly:
./run-gtk
./run-gtk gtk4-demo
PORT=9090 ./run-gtk /usr/bin/your-gtk-appThe browser receives RGBA frames over WebSocket and sends mouse, keyboard and wheel input back to the compositor.
For the recommended system-Wayland-client installation:
sudo make install-system PREFIX=/usr/localThe source install also provides a luna-desktop.service unit that can be enabled for a dedicated tty-based session:
sudo systemctl enable luna-desktop.service
sudo systemctl start luna-desktop.serviceIf you deliberately want Luna's replacement libwayland-client installed as part of the Luna prefix, use:
sudo make install PREFIX=/usr/localBerry Linux packaging uses the distribution Wayland client library and expects the display manager to launch luna-session rather than enabling the optional kiosk-style systemd unit.
The DRI backend is a real compositor path, not a nested desktop preview. It can take control of DRM/KMS, the active VT and physical input devices.
- use a real Linux VT for direct DRI testing
LUNA_TTY=/dev/ttyNselects the VT explicitlyCtrl+Alt+F1β¦F12can switch VTs when physical input is enabled- Luna restores DRM/KD/VT state during normal shutdown
- prefer a normal TERM/session logout over
SIGKILL, because a killed process cannot run its cleanup path LUNA_PHYSICAL_INPUT=0disables direct physical input handling when neededLUNA_EGL_SOFTWARE=1can force software EGL on problematic GPU setups
luna-shell/
βββ Cargo.toml
βββ rust-toolchain.toml
βββ Makefile
βββ luna-session
βββ luna-shell.spec
βββ run-gtk
β
βββ ui/
β βββ luna-shell.c # native desktop shell
β βββ luna-ui/ # Luna UI git submodule
β βββ luna-wifi.h
β βββ luna-ethernet.h
β βββ luna-bluetooth.h
β βββ luna-weather.h
β βββ luna-monitor.h
β βββ protocols/
β
βββ skins/ # shell + GTK + Qt themes
βββ docs/screenshots/ # generated real-shell captures
βββ clipboard/ # clipboard helper
βββ tray/ # tray / notification helper
βββ systemd/ # optional desktop service
βββ udev/ # device rules
βββ tools/ # screenshot/gallery tools
β
βββ wayland-server-rs/ # Rust Wayland compositor
βββ wayland-client-rs/ # optional Rust client library
βββ hello-gtk/ # sample GTK application
cargo build
cargo build -p wayland-server-rs --features dri,gpu
cargo build --features webgl
make build
make build-dri
make build-webgl
make build-shell
make build-desktop-system
make cleanLuna is intentionally experimental. Contributions that improve protocol compatibility, hardware support, shell polish, accessibility, performance, documentation, application compatibility or skin quality are welcome.
When changing shell skins, keep the screenshot gallery reproducible with:
./tools/capture-shell-skins.shLuna Desktop is released under the Mozilla Public License 2.0 (MPL-2.0). See LICENSE.
If you enjoy low-level Linux desktop experiments, custom desktop shells, Wayland internals or delightfully unnecessary retro skins, you can support continued development through GitHub Sponsors.
Build the desktop from the wire protocol to the pixels. π¦π






