Files
Nebula-OS/shells/desktop/native/README.md
T
andrew 2dadead399 Add native Wayland shell host scaffolding
Introduce a Linux-only C++20 `nebula-shell` host built with CMake, GTK4, gtk4-layer-shell, and WebKitGTK 6.0. Add a shared `Surface` abstraction and concrete Desktop/TopBar/Launcher surfaces with layer placement, sizing, transparency, and per-surface `?surface=` URL loading.

Add `ShellApplication` startup flow that validates `NEBULA_SHELL_DEV_URL`, checks layer-shell support, creates/presents desktop and top bar, and keeps launcher created but hidden for future bridge-driven toggling. Update the native README to document architecture, development setup, dependencies, and current milestone scope.
2026-08-26 15:44:44 +12:00

147 lines
3.7 KiB
Markdown

# Nebula Desktop native host
`nebula-shell` hosts the React-based Nebula Desktop chrome as real Wayland Layer Shell surfaces.
It is a C++ process that creates **several** GTK4 windows, each backed by WebKitGTK 6.0 and placed with **gtk4-layer-shell**. It does not composite application windows. Those remain ordinary Wayland / XWayland clients of the compositor.
Stack:
- C++20
- GTK4
- gtk4-layer-shell
- WebKitGTK 6.0
- CMake
- Wayland
This host is Linux-only. It will not compile on Windows.
## Purpose
Nebula Desktop's React UI is shell chrome only: wallpaper/desktop, top bar, and launcher. `nebula-shell` maps each of those to a Wayland layer surface so they sit in the compositor like a real desktop environment, not like a browser window.
Normal applications and games never render inside WebKit.
## Architecture
```text
Nebula Shell
├── DesktopSurface
│ ├── WebKitGTK
│ ├── ?surface=desktop
│ └── BACKGROUND
├── TopBarSurface
│ ├── WebKitGTK
│ ├── ?surface=topbar
│ └── TOP
└── LauncherSurface
├── WebKitGTK
├── ?surface=launcher
└── OVERLAY
```
| Surface | Query | Layer Shell layer | Placement |
|-----------|-----------------------|-------------------|-----------|
| Desktop | `?surface=desktop` | `BACKGROUND` | Anchored to all monitor edges |
| Top Bar | `?surface=topbar` | `TOP` | Anchored top/left/right, 40px (matches the React top bar), exclusive zone enabled |
| Launcher | `?surface=launcher` | `OVERLAY` | Created at startup, hidden/unmapped until later toggle work |
```text
OVERLAY
Nebula Launcher ← created, currently unmapped
notifications
OSDs
TOP
Nebula Top Bar ← exclusive zone; apps do not go under it
NORMAL APPLICATION WINDOWS
Firefox, Steam, Blender, games, terminals, …
BACKGROUND
Nebula Desktop
wallpaper
```
React draws **shell chrome only**. Applications and games render through the compositor, not through WebKit:
```text
App
Wayland / XWayland
Compositor
GPU
```
## Development
The host must not hardcode a Vite host or port. It reads a base origin from the environment and appends the surface query parameter.
Start the React UI (the port is an example, not part of the native architecture):
```bash
cd shells/desktop/ui
npm run dev -- --host 127.0.0.1 --port 5174 --strictPort
```
Point the shell at that origin:
```bash
export NEBULA_SHELL_DEV_URL=http://127.0.0.1:5174
```
That loads:
```text
{NEBULA_SHELL_DEV_URL}/?surface=desktop
{NEBULA_SHELL_DEV_URL}/?surface=topbar
{NEBULA_SHELL_DEV_URL}/?surface=launcher
```
Build:
```bash
cd shells/desktop/native
cmake -S . -B build
cmake --build build -j$(nproc)
```
Run inside a Wayland compositor such as Sway:
```bash
./build/nebula-shell
```
On startup the desktop and top bar are presented. The launcher is created but left hidden.
A combined browser preview (`/?surface=preview`, also the default) is for Windows UI work only. The native host loads the three surfaces separately.
### Linux packages
Build dependencies (install on the Ubuntu machine, not from this tree):
```text
libgtk-4-dev
libgtk4-layer-shell-dev
libwebkitgtk-6.0-dev
pkg-config
cmake
build-essential
```
## Production
Production loading from bundled `shells/desktop/ui/dist` files is not implemented yet. This milestone is development-URL loading only.
## Shell bridge
Not implemented in this milestone. Each WebKit view will later talk to the host through a JavaScript bridge (`shellBridge` in the React UI) so the top bar can map and unmap `LauncherSurface`.
## Current development compositor
Sway is the temporary compositor. See `compositor/sway/nebula-sway.conf`.