libLuna Dokumentacja
PL EN
GitHub

Pod maską

Architektura

Sześć crate'ów, jeden kierunek zależności i jeden kontrakt rysowania. libLuna nie próbuje odtworzyć GTK — próbuje być wystarczająco mała, żeby dało się ją objąć wzrokiem i naprawić.

Nazwy warstw

WarstwaOdpowiednik GNOMEOdpowiednik KDELuna
ToolkitGTKQtlibLuna
Środowisko / powłokaGNOMEKDE PlasmaLuna
Kompozytor WaylandMutterKWinSelene

Dokumentacja dotyczy libLuny, ale architektura całego projektu ma sens tylko razem: aplikacja rysuje libLuną, mówi standardowym Waylandem, a Selene przyjmuje okna i zarządza ekranem.

Mapa crate'ów

Zależności idą tylko w dół. Widgety nie wiedzą, jak działa DRM. Platforma nie wie, jak narysować przycisk. Motyw nie wie, kto go używa.

Rysowanie i tekst

Graf sceny

libluna-render::scene to lista DrawCommand niezależna od backendu. Widgety budują scenę, nie dotykając pikseli.

Backend CPU

tiny-skia rasteryzuje kształty z antyaliasingiem; bufor RGBA8888 trafia przez wl_shm.

Tekst

fontdue + font systemowy. Dziś bez kerningu i pism złożonych; docelowo cosmic-text bez zmiany kontraktu.

Ikony

SVG rasteryzowane przez resvg (bez tekstu i rastrów) oraz zestaw pastelowych ikon wektorowych.

Rozdzielenie sceny od backendu pozwala dodać GPU (EGL/dmabuf) bez zmian w widgetach. To także powód, dla którego testy można robić bez okna: scenę da się porównać lub wyrenderować do PNG.

Model widgetu

Docelowy model jest retencyjny, ale kontrakt rysowania pozostaje immediate:

text · kontrakt
Widget:
  measure(constraints) -> Size       // ile chce
  allocate(rect)                     // gdzie trafia
  paint(scene, theme)                // rysowanie
  hit(event) -> Handled | Propagate  // wejście
  focus / grab / hover

Dziś layout jest osobnym drzewem Node z dwoma przebiegami measure/allocate, a widgety pozostają liśćmi z metodami paint i *_at. Dzięki temu można używać ich ręcznie (jak w demo) albo przez layout.

Komunikacja z kompozytorem

PrzypadekProtokółW libLunie
Zwykłe okno aplikacjixdg-shell + CSDAppConfig::new(...), własny HeaderBar.
Panel / dock / tłowlr-layer-shellAppConfig::layer(LayerConfig::top_panel(...)).
OSD / powiadomieniawlr-layer-shell overlayLayerConfig::overlay(...), przezroczystość.
Ekran blokadyoverlay + klawiatura wyłącznaLayerConfig::lock_screen(...).
Schowekwl_data_deviceFrame::copy_to_clipboard / paste_from_clipboard.

Brak backendu X11 po stronie klienta. XWayland obsługuje okna aplikacji X11 w Selene, ale nowa aplikacja libLuny mówi natywnie Waylandem.

Motywowanie

Tokeny są w libluna-core::style: spacing, radius, typografia, metryki kontrolek i paleta. Widgety czytają je w paint i layout, więc styl zmienia geometrię, nie tylko kolory.

rust · trzy poziomy
// 1. wariant
frame.set_preference(ThemePreference::Dark);

// 2. akcent
frame.set_accent(Accent::Teal);

// 3. styl z pliku (kolory + geometria)
frame.set_style(Some("nord".into()));

Szczegóły: Motywy i tokeny.

Świadomie odłożone

Dostępność AT-SPI

Ważna dla realnego pulpitu, ale wymaga mostka D-Bus i drzewa dostępności. Zaplanowana później.

IME / text-input-v3

Wygodne wpisywanie CJK i klawiatura wirtualna. Dziś podstawowe zdarzenia tekstowe działają.

GPU / dmabuf

Zero-copy dla klientów Vulkan/EGL. Dziś render jest CPU, ale kontrakt sceny pozostaje.

Fractional scaling

HiDPI bez rozmycia. Skala jest już w Frame::scale i Scale.

Drag & drop

Schowek działa; DnD między aplikacjami jest późniejszy.

xdg_activation

Nowe okno czasem trzeba znaleźć za innym. Protokół jest w planach Selene.

Repozytorium i budowanie

bash
# cały projekt
make build
make test

# tylko libLuna
cd libluna
cargo test --workspace
cargo doc --no-deps

# demo i galeria
cargo run --manifest-path apps/luna-demo/Cargo.toml --bin gallery
cargo run --manifest-path apps/luna-demo/Cargo.toml --bin render -- docs/images/out.png

Każdy katalog jest osobnym workspace'em Cargo z własnym Cargo.lock. Meta-repo tylko orchestruje build. Więcej o wydaniach: docs/repositories.md.