Production-grade Wayland desktop environment for HackerOS Linux. Using in HackerOS Blue Edition
# System packages (Debian/Ubuntu/HackerOS)
sudo apt install \
build-essential curl git \
libssl-dev libgbm-dev libseat-dev \
libinput-dev libxkbcommon-dev \
libudev-dev libdrm-dev \
libgtk-3-dev libwebkit2gtk-4.0-dev \
libayatana-appindicator3-dev \
librsvg2-dev pkg-config \
seatd wmctrl xdotool
# Node.js 18+
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt install nodejs
# Rust stable
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env
# Tauri CLI v1
cargo install tauri-cli --version "^1"
# Enable seatd (needed for DRM/bare-metal mode)
sudo systemctl enable --now seatd
sudo usermod -aG seat $USER
# (re-login after this)npm install
npm run build:tauri
# This runs: npm run build β vite build β tauri buildnpm run build:compositor
# Output: ~/.hackeros/Blue-Environment/libs/blue-compositornpm run build:allnpm run dev # Start Vite dev server on :1420
cargo tauri dev # Or: npm run tauri -- devnpm run build:tauri
ββ tauri build
ββ beforeBuildCommand: "npm run build"
β ββ tsc --noEmit (type-check)
β ββ vite build β dist/
ββ cargo build (src-tauri/) β blue-environment binary
The key insight: tauri build calls npm run build automatically via
beforeBuildCommand in tauri.conf.json. You should NOT call
npm run build manually before npm run build:tauri.
blue-environment/
βββ index.html β entry HTML (project root)
βββ src/ β TypeScript/React frontend
β βββ App.tsx β Desktop shell
β βββ constants.tsx β App registry
β βββ types.ts β All TypeScript types
β βββ vite.config.ts β Vite config (root = ..)
β βββ tsconfig.json
β βββ index.tsx β React entry point
β βββ components/
β β βββ Window.tsx
β β βββ TopBar.tsx
β β βββ StartMenu.tsx
β β βββ ControlCenter.tsx
β β βββ NotificationCenter.tsx
β β βββ WindowSwitcher.tsx
β β βββ WorkspaceSwitcher.tsx
β β βββ ClipboardPanel.tsx
β β βββ ToastContainer.tsx
β β βββ apps/
β β βββ BlueAI.tsx
β β βββ BlueCodeApp.tsx β Monaco + xterm
β β βββ BlueSoftwareApp.tsx
β β βββ BlueWebApp.tsx
β β βββ ExplorerApp.tsx
β β βββ MailApp.tsx β Full mail client
β β βββ SettingsApp.tsx β Full settings
β β βββ TerminalApp.tsx
β β βββ SystemMonitorApp.tsx
β β βββ NotepadApp.tsx
β β βββ CalculatorApp.tsx
β β βββ AboutApp.tsx
β β βββ MailApp.tsx
β βββ hooks/
β β βββ useWindowManager.ts
β β βββ useKeyboardShortcuts.ts
β βββ utils/
β β βββ systemBridge.ts β Tauri IPC bridge
β β βββ configStore.ts β Reactive config (wallpaper etc.)
β β βββ notificationManager.ts
β βββ contexts/
β βββ LanguageContext.tsx
βββ src-tauri/ β Rust/Tauri backend
β βββ Cargo.toml
β βββ tauri.conf.json
β βββ build.rs
β βββ icons/icon.png
β βββ src/
β βββ main.rs β Tauri commands
β βββ ai.rs β AI API proxy
β βββ apps.rs β .desktop scanner
β βββ cache.rs β Config/cache
β βββ session.rs β Session detection
β βββ window_tracker.rs β External windows
βββ src-tauri/lib/blue-compositor/ β Smithay compositor
βββ Cargo.toml
βββ src/
βββ main.rs
βββ state.rs
βββ input.rs
βββ render.rs
βββ xwayland.rs
βββ ipc.rs
| Shortcut | Action |
|---|---|
Super |
Toggle Start Menu |
Super+Tab |
Full-screen App Picker |
Super+1β4 |
Switch Workspace |
Super+β/β |
Switch Workspace |
Super+β |
Maximize Window |
Super+β |
Minimize Window |
Super+D |
Show Desktop |
Super+L |
Lock Screen |
Alt+Tab |
Window Switcher |
Alt+Shift+Tab |
Window Switcher (backwards) |
Alt+F4 |
Close Window |
Ctrl+Alt+T |
Open Terminal |
Ctrl+Alt+C |
Control Center |
Ctrl+Shift+V |
Clipboard History |
PrintScreen |
Screenshot |
Escape |
Close Panels / Cancel |
When running inside VirtualBox or any VM:
- Compositor auto-detects
WAYLAND_DISPLAY/DISPLAYβ uses winit (nested) backend - Full 3D rendering via host GPU
- XWayland started automatically for X11 app support
On bare metal (TTY, no display server):
- Uses DRM/KMS backend via libseat
- Requires seatd running and user in
seatgroup
This means npm run build was not run before tauri build.
Solution: Always use npm run build:tauri (not npm run tauri).
The beforeBuildCommand in tauri.conf.json handles this automatically.
Ensure Cargo.toml has chrono = "0.4" (no features).
The local-offset feature does not exist in chrono 0.4.x.
sudo systemctl enable --now seatd
sudo usermod -aG seat $USER
# Then re-loginΒ© 2026 HackerOS Team
