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.
147 lines
3.7 KiB
Markdown
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`.
|