Композитор Wayland на smithay: сессия, xdg-shell, ввод, рендеринг через OpenGL ES с отслеживанием повреждений. Протоколы xdg-decoration, viewporter и presentation-time. Окна в стиле Windows 11: заголовок с названием и кнопками, перетаскивание, изменение размера за края и углы, сворачивание и разворачивание. Панель задач с подписями окон, часами и переключателем рабочих областей. Меню «Пуск» со списком приложений и поиском в текущей раскладке. Переключение окон по Alt+Tab с подтверждением при отпускании Alt. Собственный растровщик текста на fontdb + fontdue с гамма-коррекцией покрытия: без хинтинга штрихи на мелком кегле выходят рваными. Приложения запускаются в отдельной сессии D-Bus, иначе однопользовательские программы находят уже запущенный экземпляр во внешней сессии и открывают окно не в Lark. 127 тестов, clippy без замечаний.
120 lines
4.4 KiB
Bash
Executable file
120 lines
4.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
||
# Запускает Lark DE на виртуальном X-сервере и проверяет, что клиентское
|
||
# окно появилось: поднимает Xvfb, стартует `lark`, запускает клиента и
|
||
# делает снимок экрана.
|
||
#
|
||
# Переменные окружения:
|
||
# LARK_TEST_DISPLAY дисплей Xvfb (по умолчанию :78)
|
||
# LARK_TEST_RUNTIME каталог для сокета (по умолчанию /tmp/lark-test-run)
|
||
# LARK_TEST_SHOT путь к снимку (по умолчанию /tmp/lark-shot.png)
|
||
# LARK_TEST_CLIENT клиент (по умолчанию eglgears_wayland)
|
||
# LARK_TEST_WAIT секунд до снимка (по умолчанию 6)
|
||
# RUST_LOG уровень журналирования
|
||
set -uo pipefail
|
||
|
||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||
DISPLAY_NUM="${LARK_TEST_DISPLAY:-:78}"
|
||
RUNTIME_DIR="${LARK_TEST_RUNTIME:-/tmp/lark-test-run}"
|
||
SCREENSHOT="${LARK_TEST_SHOT:-/tmp/lark-shot.png}"
|
||
CLIENT="${LARK_TEST_CLIENT:-eglgears_wayland}"
|
||
WAIT_SECONDS="${LARK_TEST_WAIT:-6}"
|
||
LOG="${LARK_TEST_LOG:-/tmp/lark-dev-run.log}"
|
||
|
||
BIN="$ROOT/target/debug/lark"
|
||
if [[ ! -x "$BIN" ]]; then
|
||
echo "Сборка не найдена, выполните: cargo build" >&2
|
||
exit 1
|
||
fi
|
||
|
||
cleanup() {
|
||
[[ -n "${CLIENT_PID:-}" ]] && kill "$CLIENT_PID" 2>/dev/null
|
||
[[ -n "${LARK_PID:-}" ]] && kill "$LARK_PID" 2>/dev/null
|
||
wait 2>/dev/null
|
||
return 0
|
||
}
|
||
trap cleanup EXIT
|
||
|
||
# --- Виртуальный дисплей -----------------------------------------------------
|
||
if [[ ! -S "/tmp/.X11-unix/X${DISPLAY_NUM#:}" ]]; then
|
||
if ! command -v Xvfb >/dev/null 2>&1; then
|
||
echo "Xvfb не установлен: apt install xvfb" >&2
|
||
exit 1
|
||
fi
|
||
rm -f "/tmp/.X${DISPLAY_NUM#:}-lock"
|
||
Xvfb "$DISPLAY_NUM" -screen 0 1280x800x24 -nolisten tcp >/tmp/lark-xvfb.log 2>&1 &
|
||
for _ in $(seq 1 40); do
|
||
[[ -S "/tmp/.X11-unix/X${DISPLAY_NUM#:}" ]] && break
|
||
sleep 0.25
|
||
done
|
||
fi
|
||
|
||
# --- Каталог для сокета ------------------------------------------------------
|
||
mkdir -p "$RUNTIME_DIR"
|
||
chmod 700 "$RUNTIME_DIR"
|
||
rm -f "$RUNTIME_DIR"/wayland-*
|
||
|
||
# --- Композитор --------------------------------------------------------------
|
||
: >"$LOG"
|
||
DISPLAY="$DISPLAY_NUM" \
|
||
WAYLAND_DISPLAY= \
|
||
XDG_RUNTIME_DIR="$RUNTIME_DIR" \
|
||
RUST_LOG="${RUST_LOG:-lark=info}" \
|
||
"$BIN" >"$LOG" 2>&1 &
|
||
LARK_PID=$!
|
||
|
||
SOCKET=""
|
||
for _ in $(seq 1 60); do
|
||
SOCKET=$(ls "$RUNTIME_DIR" 2>/dev/null | grep -E '^wayland-[0-9]+$' | head -1)
|
||
[[ -n "$SOCKET" ]] && break
|
||
sleep 0.25
|
||
done
|
||
|
||
if [[ -z "$SOCKET" ]]; then
|
||
echo "Lark DE не создал сокет. Журнал:" >&2
|
||
cat "$LOG" >&2
|
||
exit 1
|
||
fi
|
||
|
||
echo "Lark DE слушает: $RUNTIME_DIR/$SOCKET"
|
||
|
||
# --- Клиент ------------------------------------------------------------------
|
||
CLIENT_LOG=/tmp/lark-client.log
|
||
: >"$CLIENT_LOG"
|
||
|
||
if ! command -v "$CLIENT" >/dev/null 2>&1; then
|
||
echo "Клиент $CLIENT не найден, снимок будет без окна" >&2
|
||
else
|
||
XDG_RUNTIME_DIR="$RUNTIME_DIR" WAYLAND_DISPLAY="$SOCKET" \
|
||
"$CLIENT" >"$CLIENT_LOG" 2>&1 &
|
||
CLIENT_PID=$!
|
||
|
||
# Клиент может завершиться сразу, если не смог инициализировать
|
||
# графику. Это стоит сообщить явно, иначе пустой снимок выглядит как
|
||
# ошибка композитора.
|
||
sleep "$WAIT_SECONDS"
|
||
if kill -0 "$CLIENT_PID" 2>/dev/null; then
|
||
echo "Клиент $CLIENT работает"
|
||
else
|
||
echo "ВНИМАНИЕ: клиент $CLIENT завершился, окно на снимке может отсутствовать" >&2
|
||
fi
|
||
fi
|
||
|
||
# --- Снимок ------------------------------------------------------------------
|
||
if command -v import >/dev/null 2>&1; then
|
||
if DISPLAY="$DISPLAY_NUM" import -window root "png:$SCREENSHOT" 2>/dev/null; then
|
||
echo "Снимок: $SCREENSHOT"
|
||
else
|
||
echo "Не удалось сделать снимок экрана" >&2
|
||
fi
|
||
fi
|
||
|
||
echo "Журнал Lark: $LOG"
|
||
if grep -qE '^Error' "$LOG"; then
|
||
echo "--- Журнал Lark ---" >&2
|
||
tail -20 "$LOG" >&2
|
||
fi
|
||
|
||
if [[ -s "$CLIENT_LOG" ]]; then
|
||
echo "--- Журнал клиента ---" >&2
|
||
tail -10 "$CLIENT_LOG" >&2
|
||
fi
|