Сборка: - Dockerfile (builder/runtime/headless/binary) и .dockerignore - scripts/build-remote.sh: сборка на другой машине, возврат бинарника и проверка без дисплея (--check) - в требования добавлен libseat-dev; dev-run.sh принимает LARK_BIN Интерфейс: - свой программный холст (src/canvas.rs): скругления, градиенты, тени, значки; слои кэшируются по отпечатку состояния, поэтому неизменный слой не перерисовывается - панель задач в раскладке Windows 10: «Пуск», строка поиска, рабочие области, кнопки окон с подписями и индикатором, трей, часы и полоска «показать рабочий стол» - меню «Пуск» «1 в 1»: полоса со списком, настройками и питанием, поиск, список по алфавиту с группами, плитки, прокрутка - настройки в стиле Windows 11: разделы и карточки, обои, анимации, раскладки, ввод, окна, сброс общий и у каждой настройки - рабочий стол: шесть вариантов обоев, значки приложений и ~/Desktop - значки вместо прямоугольников: свой набор фигур, включая кнопки заголовков окон - растровщик текста: целые кегли и базовая линия, кривая контраста вместо «загустения», кэш ширин для измерений Ввод и состояние: - список приложений читается из .desktop-файлов, ярлыки ~/Desktop тоже - индикаторы трея читают батарею, Wi-Fi, звук и Bluetooth - переключение раскладок (Super+Space) и настраиваемый их список - поиск в интернете через uv + ddgs из меню «Пуск» - анимации появления меню и настроек (отключаются в настройках) - исправлено: обои перекрывали окна, клик оболочки уходил приложению, значки рабочего стола отбирали указатель, тень вылезала из-за скруглений прямоугольником, ярлыки не сдвигались при панели сверху Документация: раздел про удалённую сборку, описание интерфейса и настроек, холст и слои в архитектуре, обновлённая дорожная карта.
122 lines
4.6 KiB
Bash
Executable file
122 lines
4.6 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_BIN собранный композитор (по умолчанию
|
||
# <корень репозитория>/target/debug/lark)
|
||
# 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="${LARK_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
|