update
This commit is contained in:
@@ -417,9 +417,15 @@ for_window [app_id="chromium-browser"] fullscreen enable
|
||||
name: string,
|
||||
enabled: boolean
|
||||
): Promise<boolean> {
|
||||
const command = `output ${name} ${enabled ? 'enable' : 'disable'}`;
|
||||
console.log(`[displays] ${command}`);
|
||||
return this.swaymsg(config, command);
|
||||
if (enabled) {
|
||||
console.log(`[displays] Enabling ${name}`);
|
||||
// First try to set resolution, then enable
|
||||
await this.swaymsg(config, `output ${name} resolution 1920x1080`);
|
||||
return this.swaymsg(config, `output ${name} enable`);
|
||||
} else {
|
||||
console.log(`[displays] Disabling ${name}`);
|
||||
return this.swaymsg(config, `output ${name} disable`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1 +1 @@
|
||||
export const VERSION = "0.4.2";
|
||||
export const VERSION = "0.4.4";
|
||||
|
||||
Binary file not shown.
@@ -48,7 +48,25 @@ else
|
||||
echo "KVM not available, using software emulation (slower)"
|
||||
fi
|
||||
|
||||
# Start QEMU with multiple displays (3 total) for multi-monitor testing
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
echo ""
|
||||
echo "Shutting down..."
|
||||
if [ -n "$VIEWER_PID" ] && kill -0 "$VIEWER_PID" 2>/dev/null; then
|
||||
kill "$VIEWER_PID" 2>/dev/null || true
|
||||
fi
|
||||
if [ -f "$PID_FILE" ]; then
|
||||
PID=$(cat "$PID_FILE")
|
||||
if kill -0 "$PID" 2>/dev/null; then
|
||||
kill "$PID" 2>/dev/null || true
|
||||
fi
|
||||
rm -f "$PID_FILE"
|
||||
fi
|
||||
echo "Done"
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# Start QEMU with virtio-gpu multi-head (3 outputs)
|
||||
> "$SERIAL_LOG" # Clear old log
|
||||
qemu-system-x86_64 \
|
||||
$KVM_OPTS \
|
||||
@@ -57,26 +75,81 @@ qemu-system-x86_64 \
|
||||
-bios /usr/share/qemu/OVMF.fd \
|
||||
-drive file="$ISO_PATH",media=cdrom \
|
||||
-drive file="$DISK_PATH",format=qcow2,if=virtio \
|
||||
-device virtio-gpu-pci,id=video0 \
|
||||
-device virtio-gpu-pci,id=video1 \
|
||||
-device virtio-gpu-pci,id=video2 \
|
||||
-device virtio-vga,max_outputs=3 \
|
||||
-display none \
|
||||
-spice port=5930,disable-ticketing=on \
|
||||
-device virtio-serial-pci \
|
||||
-chardev spicevmc,id=vdagent,name=vdagent \
|
||||
-device virtserialport,chardev=vdagent,name=com.redhat.spice.0 \
|
||||
-serial unix:"$SERIAL_SOCK",server,nowait \
|
||||
-monitor unix:"$MONITOR_SOCK",server,nowait \
|
||||
-nic user,model=virtio-net-pci,hostfwd=tcp::3006-:3006,hostfwd=tcp::2222-:22 \
|
||||
-pidfile "$PID_FILE" &
|
||||
|
||||
QEMU_PID=$!
|
||||
|
||||
echo ""
|
||||
sleep 1
|
||||
echo "=== EcoOS Test VM Started ==="
|
||||
echo "PID: $(cat $PID_FILE 2>/dev/null || echo 'running')"
|
||||
echo "SPICE: spicy -h localhost -p 5930"
|
||||
echo "Serial Log: $SERIAL_LOG"
|
||||
echo "QEMU PID: $QEMU_PID"
|
||||
echo "Management UI: http://localhost:3006"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " pnpm run test:screenshot - Take screenshot"
|
||||
echo " pnpm run test:stop - Stop VM"
|
||||
echo " tail -f $SERIAL_LOG - Watch serial console"
|
||||
echo " socat - UNIX-CONNECT:$SERIAL_SOCK - Interactive serial"
|
||||
|
||||
# Wait for QEMU to start and SPICE to be ready
|
||||
echo "Waiting for SPICE server..."
|
||||
sleep 3
|
||||
|
||||
# Check if remote-viewer is available
|
||||
if ! command -v remote-viewer &> /dev/null; then
|
||||
echo "WARNING: remote-viewer not installed"
|
||||
echo "Install with: sudo apt install virt-viewer"
|
||||
echo ""
|
||||
echo "Running without display viewer. Press Ctrl-C to stop."
|
||||
wait $QEMU_PID
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Detect DISPLAY if not set
|
||||
if [ -z "$DISPLAY" ]; then
|
||||
# Try to find an active X display
|
||||
if [ -S /tmp/.X11-unix/X0 ]; then
|
||||
export DISPLAY=:0
|
||||
elif [ -S /tmp/.X11-unix/X1 ]; then
|
||||
export DISPLAY=:1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Detect WAYLAND_DISPLAY if not set
|
||||
if [ -z "$WAYLAND_DISPLAY" ] && [ -z "$DISPLAY" ]; then
|
||||
# Try common Wayland sockets
|
||||
if [ -S "$XDG_RUNTIME_DIR/wayland-0" ]; then
|
||||
export WAYLAND_DISPLAY=wayland-0
|
||||
elif [ -S "/run/user/$(id -u)/wayland-0" ]; then
|
||||
export XDG_RUNTIME_DIR="/run/user/$(id -u)"
|
||||
export WAYLAND_DISPLAY=wayland-0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Launch remote-viewer - use Xvfb if no display available
|
||||
if [ -z "$DISPLAY" ] && [ -z "$WAYLAND_DISPLAY" ]; then
|
||||
echo "No display found, using Xvfb for headless SPICE client..."
|
||||
# Use Xvfb with large virtual screen to support 3 monitors (5760x1080 = 3x1920x1080)
|
||||
xvfb-run -a -s "-screen 0 5760x1080x24" remote-viewer spice://localhost:5930 &
|
||||
VIEWER_PID=$!
|
||||
echo "remote-viewer running headlessly under Xvfb (PID: $VIEWER_PID)"
|
||||
else
|
||||
echo "Launching remote-viewer (DISPLAY=$DISPLAY, WAYLAND_DISPLAY=$WAYLAND_DISPLAY)..."
|
||||
remote-viewer spice://localhost:5930 &
|
||||
VIEWER_PID=$!
|
||||
fi
|
||||
echo ""
|
||||
|
||||
echo "=== Press Ctrl-C to stop ==="
|
||||
echo ""
|
||||
echo "Tips:"
|
||||
echo " - View > Displays > Enable Display 2/3 for multi-monitor"
|
||||
echo " - pnpm run test:screenshot - Take screenshot"
|
||||
echo " - http://localhost:3006 - Management UI"
|
||||
echo ""
|
||||
|
||||
# Wait for either process to exit
|
||||
wait $QEMU_PID 2>/dev/null || true
|
||||
|
||||
@@ -4,6 +4,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
PROJECT_ROOT="$SCRIPT_DIR/.."
|
||||
VM_DIR="$PROJECT_ROOT/.nogit/vm"
|
||||
SCREENSHOT_DIR="$PROJECT_ROOT/.nogit/screenshots"
|
||||
TIMESTAMPED_DIR="$SCREENSHOT_DIR/timestamped"
|
||||
MONITOR_SOCK="$VM_DIR/qemu-monitor.sock"
|
||||
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
||||
|
||||
@@ -15,57 +16,38 @@ if [ ! -S "$MONITOR_SOCK" ]; then
|
||||
fi
|
||||
|
||||
mkdir -p "$SCREENSHOT_DIR"
|
||||
mkdir -p "$TIMESTAMPED_DIR"
|
||||
|
||||
# Screenshot all displays (video0, video1, video2)
|
||||
DISPLAYS="video0 video1 video2"
|
||||
SCREENSHOTS=()
|
||||
echo "Taking screenshot..."
|
||||
|
||||
echo "Taking screenshots of all displays..."
|
||||
PPM_FILE="$SCREENSHOT_DIR/temp.ppm"
|
||||
LATEST_FILE="$SCREENSHOT_DIR/latest.png"
|
||||
TIMESTAMPED_FILE="$TIMESTAMPED_DIR/ecoos-$TIMESTAMP.png"
|
||||
|
||||
for DISPLAY in $DISPLAYS; do
|
||||
PPM_FILE="$SCREENSHOT_DIR/ecoos-$TIMESTAMP-$DISPLAY.ppm"
|
||||
PNG_FILE="$SCREENSHOT_DIR/ecoos-$TIMESTAMP-$DISPLAY.png"
|
||||
# Take screenshot (virtio-vga captures all outputs in one framebuffer)
|
||||
echo "screendump $PPM_FILE" | socat - UNIX-CONNECT:"$MONITOR_SOCK" > /dev/null 2>&1
|
||||
sleep 0.5
|
||||
|
||||
# Take screenshot of this display
|
||||
echo "screendump $PPM_FILE $DISPLAY" | socat - UNIX-CONNECT:"$MONITOR_SOCK" 2>/dev/null
|
||||
sleep 0.5
|
||||
|
||||
if [ -f "$PPM_FILE" ]; then
|
||||
# Convert to PNG if imagemagick is available
|
||||
if command -v convert &> /dev/null; then
|
||||
convert "$PPM_FILE" "$PNG_FILE"
|
||||
rm "$PPM_FILE"
|
||||
SCREENSHOTS+=("$PNG_FILE")
|
||||
echo " $DISPLAY: $PNG_FILE"
|
||||
else
|
||||
SCREENSHOTS+=("$PPM_FILE")
|
||||
echo " $DISPLAY: $PPM_FILE"
|
||||
fi
|
||||
else
|
||||
echo " $DISPLAY: (no output or not connected)"
|
||||
fi
|
||||
done
|
||||
|
||||
# Create a combined image if we have multiple screenshots and imagemagick
|
||||
if command -v convert &> /dev/null && [ ${#SCREENSHOTS[@]} -gt 1 ]; then
|
||||
COMBINED_FILE="$SCREENSHOT_DIR/ecoos-$TIMESTAMP-combined.png"
|
||||
LATEST_FILE="$SCREENSHOT_DIR/latest.png"
|
||||
|
||||
# Combine images horizontally
|
||||
convert "${SCREENSHOTS[@]}" +append "$COMBINED_FILE"
|
||||
cp "$COMBINED_FILE" "$LATEST_FILE"
|
||||
|
||||
echo ""
|
||||
echo "Combined screenshot: $COMBINED_FILE"
|
||||
echo "Also saved as: $LATEST_FILE"
|
||||
elif [ ${#SCREENSHOTS[@]} -eq 1 ]; then
|
||||
LATEST_FILE="$SCREENSHOT_DIR/latest.png"
|
||||
cp "${SCREENSHOTS[0]}" "$LATEST_FILE"
|
||||
echo ""
|
||||
echo "Also saved as: $LATEST_FILE"
|
||||
if [ ! -f "$PPM_FILE" ]; then
|
||||
echo "ERROR: Failed to capture screenshot"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Keep only last 20 screenshot sets (excluding latest.png)
|
||||
cd "$SCREENSHOT_DIR"
|
||||
ls -t ecoos-*-combined.png 2>/dev/null | tail -n +21 | xargs -r rm -f
|
||||
ls -t ecoos-*-video*.png 2>/dev/null | tail -n +61 | xargs -r rm -f
|
||||
# Convert to PNG
|
||||
if command -v convert &> /dev/null; then
|
||||
convert "$PPM_FILE" "$LATEST_FILE"
|
||||
cp "$LATEST_FILE" "$TIMESTAMPED_FILE"
|
||||
rm "$PPM_FILE"
|
||||
echo "Screenshot saved: $LATEST_FILE"
|
||||
echo "Timestamped copy: $TIMESTAMPED_FILE"
|
||||
else
|
||||
mv "$PPM_FILE" "$SCREENSHOT_DIR/latest.ppm"
|
||||
cp "$SCREENSHOT_DIR/latest.ppm" "$TIMESTAMPED_DIR/ecoos-$TIMESTAMP.ppm"
|
||||
echo "Screenshot saved: $SCREENSHOT_DIR/latest.ppm"
|
||||
echo "(Install ImageMagick for PNG conversion)"
|
||||
fi
|
||||
|
||||
# Keep only last 50 timestamped screenshots
|
||||
cd "$TIMESTAMPED_DIR"
|
||||
ls -t ecoos-*.png 2>/dev/null | tail -n +51 | xargs -r rm -f
|
||||
ls -t ecoos-*.ppm 2>/dev/null | tail -n +51 | xargs -r rm -f
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@ecobridge/eco-os",
|
||||
"version": "0.4.2",
|
||||
"version": "0.4.4",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "[ -z \"$CI\" ] && npm version patch --no-git-tag-version || true && node -e \"const v=require('./package.json').version; require('fs').writeFileSync('ecoos_daemon/ts/version.ts', 'export const VERSION = \\\"'+v+'\\\";\\n');\" && pnpm run daemon:bundle && cp ecoos_daemon/bundle/eco-daemon isobuild/config/includes.chroot/opt/eco/bin/ && mkdir -p .nogit/iso && docker build --no-cache -t ecoos-builder -f isobuild/Dockerfile . && docker run --privileged --name ecoos-build ecoos-builder && docker cp ecoos-build:/output/ecoos.iso .nogit/iso/ecoos.iso && docker rm ecoos-build",
|
||||
|
||||
Reference in New Issue
Block a user