diff --git a/vm/README.md b/vm/README.md
index db1a27a..b9f6ec7 100644
--- a/vm/README.md
+++ b/vm/README.md
@@ -1,7 +1,7 @@
# WayRay VM Testing Setup
-Visual testing environment for the WayRay compositor using an Arch Linux
-aarch64 VM on macOS Apple Silicon via UTM.
+Visual testing environment for the WayRay compositor using an Ubuntu
+22.04 aarch64 VM on macOS Apple Silicon via UTM.
## Prerequisites
@@ -10,60 +10,40 @@ aarch64 VM on macOS Apple Silicon via UTM.
## Create the VM
-### 1. Download the Arch Linux ARM ISO
+### 1. Get the Ubuntu 22.04 image from the UTM Gallery
-Go to and download the latest aarch64
-ISO image.
+1. Open UTM
+2. Click **+** to create a new VM
+3. Select **Browse UTM Gallery...**
+4. Find and download **Ubuntu 22.04**
+5. The VM is pre-configured with reasonable defaults
-### 2. Create a new VM in UTM
+### 2. Adjust VM settings (optional)
-1. Open UTM, click **Create a New Virtual Machine**
-2. Select **Virtualize**
-3. Select **Linux**
-4. Browse to the downloaded ISO
-5. Configure hardware:
- - **CPU:** 4 cores
+The gallery image works out of the box, but for faster Rust compilation:
+
+1. Select the VM in UTM, click the **settings icon**
+2. Under **System**:
+ - **CPU:** 4 cores (or more)
- **RAM:** 8192 MB (8 GB)
-6. Configure storage:
- - **Disk size:** 30 GB
-7. Give it a name (e.g., "WayRay Dev")
-8. Click **Save**
-The VM defaults to VirtIO display and shared networking, which is what
-we need.
+### 3. Boot and run the setup script
-### 3. Install Arch Linux
-
-1. Boot the VM from the ISO
-2. Run `archinstall`
-3. Recommended settings:
- - **Mirrors:** Select your region
- - **Disk configuration:** Use entire disk, ext4
- - **Bootloader:** systemd-boot
- - **Profile:** Minimal
- - **User:** Create a user with sudo privileges
- - **Network:** NetworkManager
-4. Complete the installation and reboot
-5. Remove the ISO from the VM's CD drive in UTM settings
-
-### 4. Run the setup script
-
-Boot into the installed system and log in, then:
+1. Start the VM and log in (gallery image credentials are shown in UTM)
+2. Open a terminal and run:
```bash
-# Install git first (needed to clone the repo)
-sudo pacman -S git --noconfirm
-
# Clone WayRay and run the setup script
-git clone ~/wayray
+git clone https://github.com/CloudNebulaProject/wayray.git ~/wayray
bash ~/wayray/vm/setup.sh
# Reboot to apply auto-login and start Sway
sudo reboot
```
-Note: the script skips cloning if `~/wayray` already exists, so passing
-the repo URL to `setup.sh` is only needed if you haven't cloned yet.
+The setup script installs all dependencies (Wayland libs, Mesa, Sway,
+Rust), builds WayRay, and configures auto-login into a minimal Sway
+session.
## Testing the Compositor
@@ -103,29 +83,40 @@ A foot terminal should appear inside the wrsrvd window. You can:
### Sway fails to start
-If Sway fails with a GPU error, the VirtIO GPU may not be working
-with Apple Virtualization.framework. Try switching UTM to QEMU backend:
+If Sway fails with a GPU or seat error:
+
+```bash
+# Check seatd is running
+systemctl status seatd
+
+# Check group membership (need seat and video)
+groups
+
+# If missing, add and reboot
+sudo usermod -aG seat,video $USER
+sudo reboot
+```
+
+If the VirtIO GPU isn't working, try switching UTM to QEMU backend:
1. Shut down the VM
-2. In UTM, edit the VM settings
+2. Edit VM settings
3. Under **System**, uncheck "Use Apple Virtualization"
-4. Under **Display**, ensure VirtIO GPU is selected
-5. Boot again
+4. Boot again
### Black screen after reboot
-The auto-login or Sway autostart may have failed. Switch to TTY2 with
-`Ctrl+Alt+F2`, log in, and check:
+Switch to TTY2 with `Ctrl+Alt+F2`, log in, and check:
```bash
-# Check if seatd is running
-systemctl status seatd
-
-# Check if user is in seat group
-groups
-
# Try starting Sway manually
sway
+
+# Check the auto-login override
+cat /etc/systemd/system/getty@tty1.service.d/override.conf
+
+# Check .profile for Sway launch
+tail ~/.profile
```
### Build fails
@@ -140,3 +131,12 @@ rustc --version
# Retry
cargo build --workspace
```
+
+### Missing Wayland/EGL libraries
+
+If `cargo build` fails with missing `-lwayland-client` or EGL errors:
+
+```bash
+# Reinstall dev packages
+sudo apt-get install -y libwayland-dev libegl1-mesa-dev libgles2-mesa-dev libxkbcommon-dev
+```
diff --git a/vm/setup.sh b/vm/setup.sh
index 90967b8..75b5ea3 100755
--- a/vm/setup.sh
+++ b/vm/setup.sh
@@ -1,11 +1,11 @@
#!/usr/bin/env bash
# WayRay VM Provisioning Script
-# Run as a regular user inside a fresh Arch Linux aarch64 install.
+# Run as a regular user inside an Ubuntu 22.04 aarch64 VM (UTM gallery image).
# Idempotent — safe to run multiple times.
set -euo pipefail
-REPO_URL="${1:-}"
+REPO_URL="${1:-https://github.com/CloudNebulaProject/wayray.git}"
WAYRAY_DIR="$HOME/wayray"
info() { printf '\033[1;34m==> %s\033[0m\n' "$*"; }
@@ -15,45 +15,58 @@ ok() { printf '\033[1;32m==> %s\033[0m\n' "$*"; }
# ── 1. System packages ───────────────────────────────────────────────
info "Updating system packages..."
-sudo pacman -Syu --noconfirm
+sudo apt-get update
+sudo apt-get upgrade -y
PACKAGES=(
# Build tools
- base-devel
+ build-essential
+ pkg-config
+ cmake
# Wayland
- wayland
+ libwayland-dev
wayland-protocols
- libxkbcommon
+ libxkbcommon-dev
# Graphics (Mesa provides EGL/OpenGL for Winit's GlesRenderer)
- mesa
+ libgles2-mesa-dev
+ libegl1-mesa-dev
+ libgbm-dev
+ libdrm-dev
# Session
sway
- seatd
foot
+ seatd
# Tools
git
- openssh
+ curl
+ openssh-client
)
info "Installing packages..."
-sudo pacman -S --needed --noconfirm "${PACKAGES[@]}"
+sudo apt-get install -y "${PACKAGES[@]}"
# ── 2. Services ──────────────────────────────────────────────────────
info "Enabling seatd..."
-sudo systemctl enable --now seatd
+sudo systemctl enable --now seatd || true
# Add user to seat group if not already a member.
-if ! groups | grep -q '\bseat\b'; then
+if getent group seat &>/dev/null && ! groups | grep -q '\bseat\b'; then
info "Adding $USER to seat group..."
sudo usermod -aG seat "$USER"
warn "Group change requires re-login. Re-run this script after reboot."
fi
+# Some Ubuntu setups need the user in video group for GPU access.
+if ! groups | grep -q '\bvideo\b'; then
+ info "Adding $USER to video group..."
+ sudo usermod -aG video "$USER"
+fi
+
# ── 3. Rust toolchain ────────────────────────────────────────────────
if command -v cargo &>/dev/null; then
@@ -65,11 +78,15 @@ else
source "$HOME/.cargo/env"
fi
+# Make cargo available in this session if .cargo/env exists.
+# shellcheck disable=SC1091
+[ -f "$HOME/.cargo/env" ] && source "$HOME/.cargo/env"
+
# Verify edition 2024 support (Rust 1.85+).
-RUST_VERSION=$(rustc --version | grep -oP '\d+\.\d+')
+RUST_VERSION=$(rustc --version | sed -n 's/rustc \([0-9]*\.[0-9]*\).*/\1/p')
RUST_MAJOR=$(echo "$RUST_VERSION" | cut -d. -f1)
RUST_MINOR=$(echo "$RUST_VERSION" | cut -d. -f2)
-if (( RUST_MAJOR < 1 || (RUST_MAJOR == 1 && RUST_MINOR < 85) )); then
+if [ "$RUST_MAJOR" -lt 1 ] || { [ "$RUST_MAJOR" -eq 1 ] && [ "$RUST_MINOR" -lt 85 ]; }; then
warn "Rust $RUST_VERSION may not support edition 2024. Run: rustup update"
fi
@@ -78,15 +95,7 @@ fi
if [ -d "$WAYRAY_DIR" ]; then
ok "WayRay repo already cloned at $WAYRAY_DIR"
else
- if [ -z "$REPO_URL" ]; then
- echo ""
- echo "WayRay repo URL not provided."
- echo "Usage: $0 "
- echo "Example: $0 https://github.com/user/wayray.git"
- echo " $0 git@github.com:user/wayray.git"
- exit 1
- fi
- info "Cloning WayRay..."
+ info "Cloning WayRay from $REPO_URL..."
git clone "$REPO_URL" "$WAYRAY_DIR"
fi
@@ -106,13 +115,13 @@ else
sudo tee "$GETTY_OVERRIDE" > /dev/null </dev/null; then
info "Adding Sway auto-start to $PROFILE..."