WebDesktopGL — это фреймворк для преобразования веб-сайтов в настольные приложения на основе Chromium. Совместим с Astra Linux и другими системами Linux. В статье рассказано о следующем:

Как использовать браузер Chromium в качестве отдельного графического движка (параметры запуска Chromium).

Как на виртуальном экране Xephyr или Xvfb (X-сервере) реализованном над Xorg, добавить поддержку GPU видеокарты.

Как реализовать буфер обмена между дисплеями с помощью xclip в Astra Linux и других системах Linux.

Цель работы — это создание аналога фреймворка Electron, альтернативного программного продукта WebDesktopGL, для Astra Linux и других систем Linux. Фреймворк WebDesktopGL был протестирован в средах Wayland и X11 в Ubuntu 24.04 (KDE), в X11 Ubuntu 22.04 (KDE) и Astra Linux 1.8.

Краткая предыстория

Краткая предыстория, в ходе работы с Astra Linux понадобилось сделать информационную систему из старой ВЕБ-системы с ограничениями для пользователя. Далее с помощью Bash был сделан фреймворк WebDesktopGL для Astra Linux. По техническому заданию в системе нельзя было использовать нелицензионный софт, поэтому был сделан фреймворк WebDesktopGL.

Установка и запуск

Перед установкой требуется сначала скачать git-lfs для выполнения команды git clone, иначе большие файлы не удастся скачать.

sudo apt install git-lfs
git clone https://github.com/PVE-Vladimir/WebDesktopGL.git
# Использовать скрипт установки Install_bash_WebDesktopGL.sh
./WebDesktopGL/Install_bash_WebDesktopGL.sh
cd ./WebDesktopGL

Видео установки и запуска фреймворка WebDesktopGL на X11 Ubuntu 24.04 (KDE)

Видео установки и запуска фреймворка WebDesktopGL на Wayland Ubuntu 24.04

Команда git clone https://github.com/PVE-Vladimir/WebDesktopGL.git скачает все файлы проекта:

Install_bash_WebDesktopGL.sh — это скрипт bash, который самостоятельно устанавливает все зависимости, собирает Virtualgl-main, разархивирует локальную версию ungoogled-chromium_146.0.7680.143_1 и собирает xdotool_xseticon.

Virtualgl-main — это переработанный код Virtualgl, который позволяет подключить поддержку GPU, в нём добавлены параметры сборки и запуска в динамическом каталоге. Virtualgl не поддерживает Wayland.

Demo — это ВЕБ-сайт с 3d сценой для тестирования поддержки видео карты. ВЕБ-сайт имеет структуру, необходимую для работы фреймворка WebDesktopGL. Структура сайта содержит пользовательские ограничения которые отключают нежелательный интерфейс chromium. На сайте реализована 3d сцена, переходы между вкладками, модифицированный просмотрщик (вьювер) pdf.js и просмотрщик (вьювер) форматов изображений '.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg', '.ico'.

ungoogled-chromium_146.0.7680.143_1.vaapi_linux.tar.xz — это архив локальной версии Chromium для работы исполняемых файлов InfoDoc_light.sh и InfoDoc.sh. Это стандартная версия Chromium (вместо неё можно использовать любую версию, в том числе нелокальную).

InfoDoc_light.sh — это упрощённая версия запуска ВЕБ-сайта. В этой версии не используются расширенные ограничения, такие как виртуальный экран Xephyr, а поддержка видеокарты доступна без Virtualgl-main. В скрипте по умолчанию используется локальная версия chromium. Её возможно по желанию заменить на любую другую. Для этого нужно заменить путь $dir_chromium/chrome на chromium, а "$dir_chromium/$chromium_sessionon" на тот каталог, куда сохранять данные сессии браузера. Так же убрать проверку Error: Chromium launch file missing. Внутри скрипта уже содержатся код утилиты Xdotool_xseticon и иконка для окна. Скрипт создан для того, чтобы на удалённый хост с Astra Linux через scp отправлялся только скрипт, а программа там запускалась через общий адрес сайта на сервере без тяжёлого клиента.

InfoDoc.sh — это полная версия запуска ВЕБ-сайта. Тут запуск chromium происходит на отдельном виртуальном экране Xephyr. Поддержка видео карты через Virtualgl-main доступна на X11 Linux. В Wayland Virtualgl-main не работает, поэтому обработка всех функций сайта происходит на CPU. Для работы этой версии необходима полная установка через Install_bash_WebDesktopGL.sh. Буфер обмена между экранами происходит через xclip. Утилита xdotool_xseticon необходима для работы работы сайта на виртуальном экране.

Xdotool_xseticon.c — исходный код утилиты xdotool_xseticon на языке Си. Необходим для сборки проекта с помощью скрипта Install_bash_WebDesktopGL.sh.

make_window_icon_txt.sh — скрипт для конвертирования изображений в различные форматы и создания иконки окна для утилиты xdotool_xseticon.

set_gif.sh — Пример bash скрипта, который устанавливает анимацию для иконки любого окна

Images — Примеры изображений для иконок окон, в том числе и анимированных иконок. Подробнее тут.

Install_bash_WebDesktopGL.sh скрипт на Bash автоматизирует установку необходимых зависимостей и компиляцию программ для работы графического интерфейса на Linux (в частности, для работы с X11 и VirtualGL, а также для запуска браузера Chromium в графическом режиме из консоли). Скрипт Install_bash_WebDesktopGL.sh работает через konsole. Если существует konsole то, он запустится в отдельном терминале konsole.

Шаги работы скрипта Install_bash_WebDesktopGL.sh

1. Проверка переменной среды DISPLAY

Скрипт сначала проверяет, задана ли переменная DISPLAY, которая указывает на активный X-сервер (т.е. графическую сессию).

Если DISPLAY не установлена, выводится ошибка и скрипт завершается с кодом 1.

2. Определение директории скрипта

Определяется путь к скрипту (SCRIPT_DIR) с помощью dirname "$(realpath "$0")".

Проверка и запуск в консоли konsole

3. Если утилита konsole (терминал KDE) не установлена, выводится ошибка и тут же вызывается функция установки (Install_bash_WebDesktopGL).

Если konsole установлена — запускается новый экземпляр konsole, который в фоне (через nohup) запускает новую сессию с вызовом функции установки и компиляции внутри её (bash -c "$(declare -f Install_bash_WebDesktopGL); Install_bash_WebDesktopGL \"$SCRIPT_DIR\"").

4. Функция Install_bash_WebDesktopGL

Эта функция устанавливает необходимые пакеты и собирает программы:

Установка зависимостей через sudo требует подтверждения yes

Для Debian/Ubuntu (через apt-get):

sudo apt-get install cmake build-essential libx11-dev libx11-xcb-dev \
libxcb-glx0-dev libxcb-keysyms1-dev libgl1-mesa-dev libxtst-dev \
libjpeg-turbo*-dev libjpeg-turbo* libglu1-mesa-dev libxext-dev libxi-dev \
libxmu-dev ocl-icd-opencl-dev opencl-headers libturbojpeg-dev \
xserver-xorg-video-fbdev xserver-xorg-video-dummy x11-utils libxdo3 xclip

Для Arch Linux (через pacman) этот подход не тестировался:

sudo pacman -S cmake build-essential libx11-dev libx11-xcb-dev \
libxcb-glx0-dev libxcb-keysyms1-dev libgl1-mesa-dev libxtst-dev \
libjpeg-turbo*-dev libjpeg-turbo* libglu1-mesa-dev libxext-dev libxi-dev \
libxmu-dev ocl-icd-opencl-dev opencl-headers libturbojpeg-dev \
xserver-xorg-video-fbdev xserver-xorg-video-dummy x11-utils libxdo3 xclip

Также перечислены пакеты imagemagick и ffmpeg, но они не устанавливаются, поскольку упоминание о них есть в make_window_icon_txt.sh, где они и устанавливаются.

5. Сборка VirtualGL

Создаётся временная директория /tmp/virtualgl_main_build.

Скрипт находит исходники VirtualGL ("$SCRIPT_DIR"/virtualgl-main), собирает их с помощью cmake и make с оптимальным количеством потоков (nproc).

После сборки выполняется make install.

6. Распаковка Chromium

Ищет файл chromium в формате .tar в директории скрипта и распаковывает его.

После этого выводится сообщение об успешном завершении.

7. Компиляция xdotool_xseticon

Компилирует исходник Xdotool_xseticon.c с помощью gcc, линкует с библиотекой X11.

Если компиляция успешна — выводится сообщение, и скрипт завершается с кодом 0. Если нет — выводится ошибка и скрипт завершается с кодом 1.

Запуск через InfoDoc.sh

Основной скрипт InfoDoc.sh содержит в себе полный функционал, для запуска ВЕБ-сайта как отдельного десктопного приложения. Для работы этой версии запуска необходима полная установка через Install_bash_WebDesktopGL.sh.

1. Подготовка зависимостей

Скрипт начинается с проверки наличия компилятора gcc, требуемого для сборки кастомного бинарного инструмента xdotool_xseticon, через метод make_xdotool_xseticon. Переменная input_png хранит иконку окна в формате ARGB для установки через xdotool_xseticon.

Также необходимы:

xdotool_xseticon (имеет кастомный бинарник, который скрипт компилирует сам)

xclip — для обмена данных буферов между хостом и гостем X сервера

Xephyr — для создания временного X-сервера

VirtualGL — (если требуется 3D-ускорение)

Пакеты разработки X11: libx11-dev

Скрипт проверяет и параметры окружения

Ошибка: Отсутствует переменная среды DISPLAY

Ошибка: В вашей среде отсутствует тип сессии X11 или Wayland

Ошибка: Отсутствует файл запуска VirtualGL

Ошибка: Отсутствует файл запуска Chromium

Эти проверки можно убрать, если вы хотите изменить запуск.

Как можно было заметить ранее, в проекте убраны стандартные инструменты xdotool xseticon и заменены на единое кастомное решение xdotool_xseticon. Однако в скрипте остались примеры блоков кода на стандартных утилитах.

В скрипте есть комментарии с кодом, который изменяет параметры запуска для расширения функционала фреймворка.

Сверните окно из полноэкранного режима и установите его размеры равными половине ширины всего экрана.

Возможность установить GIF-анимацию для значка окна. Раскомментируйте и проверьте, как это работает в вашем дистрибутиве. Замените 6 на 20 или удалите 6.

# Закомментируйте # по своему усмотрению. Включает и отключает общий буфер обмена через xclip.

2. Виртуальный экран (X-сервер) создаётся

display=$(xdpyinfo | grep dimensions | awk '{split($2, a, "x"); print a[1] "x" a[2]}');
Xephyr -br -ac -noreset -screen "$display" -resizeable -title "$title_InfoDoc" :$unique_id &
XEYPH_PID=$!

Затем происходит ожидание запуска окна.

window_id=$("$SCRIPT_DIR/xdotool_xseticon" search --name "$title_InfoDoc" | sort -n | tail -n1);

Тут выводится id для управления основным окном

echo "window_id: $window_id";

Затем задаются параметры окна: название и иконка окна.

"$SCRIPT_DIR/xdotool_xseticon" NETWM $window_id rename "InfoDoc"
"$SCRIPT_DIR/xdotool_xseticon" xseticon $window_id $input_png

Экспорт нового окна дисплея нужен для того, чтобы затем Chromium и все другие программы работали внутри созданного окна.

export DISPLAY=:$unique_id ;

Внутри метода start_resize() происходит запуск приложения, размеры которого будут подгоняться под размеры созданного окна.

Внутри этого метода используется VirtualGL, он необходим для обработки графики на видео карте.

"$dir_VirtualGL" -d $(ls /dev/dri/card* | tail -n1) "$dir_chromium/chrome"

3. После загрузки браузера Chromium в отдельном потоке в методе start_resize() происходит ожидание его полного запуска.

Метод sync_buffer_xephyr обеспечивает полноценный обмен данными буфера обмена (primary и clipboard) между основным дисплеем и созданным окном.

Затем запускается бесконечный цикл работы программы. В нём раз в секунду происходит масштабирование содержимого Chromium по размеру созданного окна. Условием выхода из цикла является завершение работы браузера Chromium.

if ! kill -0 "$pid" 2>/dev/null; then
        echo "The browser has terminated."
        break
fi

Запуск через InfoDoc_light.sh

Скрипт InfoDoc_light.sh представляет собой облегчённую версию запуска InfoDoc.sh. Отличия заключаются в том, что в нём нет виртуального экрана Xephyr, соответственно, отпадает надобность в Virtualgl-main и xclip. Это позволяет реализовать другую архитектуру работы фреймворка. К примеру, если на удалённом хосте установлен Chromium, возможно заменить путь $dir_chromium/chrome на chromium (вызов браузера через bash), а "$dir_chromium/$chromium_sessionon" — на тот каталог, куда сохранять данные сессии браузера. В --app="file://$SCRIPT_DIR/Demo/index.htm" указывается путь или ссылка на открываемый сайт. Её можно заменить на ваш сайт, который вы хотите открыть. Также нужно убрать проверку Error: Chromium launch file missing. Внутри скрипта уже содержатся код утилиты Xdotool_xseticon и иконка для окна. После этого скрипт можно просто передать на удалённый хост, например Astra Linux, через scp. Это позволит открывать по локальной сети большие каталоги с данными, используя вызов bash скрипта. Далее в любой программе на C++ можно создать кнопку открытия приложения «Информационная система», эта кнопка вызывает скрипт InfoDoc_light.sh, который откроет сайт как отдельное десктопное приложение.

Ещё одно отличие InfoDoc_light от InfoDoc заключается в том, что окно InfoDoc_light в Chromium ведёт себя не так, как Xephyr. Соответственно, иконка окна всё время меняется на иконку сайта в плохом качестве. Именно для этого в InfoDoc_light.sh есть вечный цикл, который обновляет иконку окна на более качественную, используя изображение из переменной input_png.

Также в некоторых дистрибутивах Linux (но не в Astra Linux) у окон Chromium есть нежелательные функции, поэтому создан InfoDoc с дополнительными ограничениями для пользователя.

Как использовать браузер Chromium как отдельный графический движок (Параметры запуска Chromium) Запуск InfoDoc.

У Chromium есть множество параметров запуска, с помощью которых можно добиться, чтобы локальный сайт запускался через Chromium как десктопное приложение. Ссылки на параметры Chromium: первая , вторая.

Для Chromium с представленными параметрами неважно, запускается ли сайт или ссылка. С приведёнными параметрами запуска возможно запускать и локальную версию Chromium, к примеру из архива ungoogled-chromium_146.0.7680.143_1. vaapi_linux.tar.xz, игнорируя политику безопасности linux.

Пример запуска Chromium как отдельного приложения с обработкой графики.

chromium \
    --user-data-dir="/tmp/chromium_sessionon" \
    --no-sandbox \
    --app="http://infodoc.fun/" \
    --disable-web-security \
    --test-type \
    --start-maximized \
    --no-zygote

Параметры запуска Chromium

--no-zygote Отключает использование процесса zygote для создания дочерних процессов. Вместо этого дочерние процессы будут создаваться и запускаться напрямую. Это необходимо для запуска Headless Chrome в средах, где поддержка форкингового сервера, такого как zygote, не требуется и/или нецелесообразна. Обратите внимание, что --no-sandbox также следует использовать вместе с этим флагом, поскольку для работы песочницы необходим процесс zygote.

--no-sandbox Отключает песочницу для всех типов процессов, которые обычно находятся в песочнице. Предназначено для использования в качестве переключателя на уровне браузера только в целях тестирования. Важный параметр для расширения возможностей веб приложений.

--disable-web-security Не применять политику одного источника; предназначено только для тестирования веб-сайтов. Этот параметр не будет иметь эффекта, если не присутствует также параметр --user-data-dir (как определено встраивающим контентом).

--user-data-dir Каталог, где браузер хранит профиль пользователя.

--test-type Тип текущей тестовой среды ("browser" или "ui"). Параметр нужен для отключения ненужных предупреждений в браузере.

--app Указывает, что соответствующая ссылка должна запускаться в режиме «приложения». Отключает интерфейс браузера.

--kiosk Включить режим киоска. Отключает контекстное меню и интерфейс браузера запускает сайт в весь экран F11 без возможности свернуть.

--start-maximized Запускает браузер в полноэкранном режиме, независимо от предыдущих настроек.

--force-device-scale-factor Переопределяет коэффициент масштабирования ссылки для пользовательского интерфейса браузера и его содержимого.

В скриптах используются методы start_main и start_resize, которые имеют параметры запуска, основанные на переменных окружения.

SCRIPT_DIR="$(dirname "$(realpath "$0")")"
dir_chromium="$(ls -d "$SCRIPT_DIR"/*chromium* | grep -v .tar | head -n1 )"

SCRIPT_DIR определяет директорию, в которой находятся локальная версия chromium и сайт, который будет запускаться --app="file://$SCRIPT_DIR/Demo/index.htm"

dir_chromium находит директорию с локальной версией браузера для запуска chromium через bash команду "$dir_chromium/chrome"

Перед каждым запуском скрипт очищает старую историю пользователя rm -rf "$dir_chromium/$chromium_sessionon";

Перед каждым запуском скрипт проверяет содержимое стандартной переменной окружения XDG_SESSION_TYPE, чтобы определить, возможно ли использование chromium и ускорителя dir_VirtualGL.

dir_VirtualGL="$(ls "$SCRIPT_DIR"/VirtualGL/bin/vglrun )" директория, где должен появиться скомпилированный файл. Об этом сказано подробно в следующем разделе: "Как на виртуальном экране Xephyr, Xvfb (X-сервере) реализованном над Xorg добавить поддержку GPU видео карты".

Для пользователя root создаётся отдельная директория chromium_sessionon_root, чтобы у программы был всегда доступ к директории сессии chromium.

start_main параметры запуска Chromium для InfoDoc_light.sh

start_main() {
#   --start-maximized --kiosk --force-device-scale-factor=1.5
#     rm -rf /tmp/chromium-new-sessionon;
#     nohup chromium --user-data-dir=/tmp/chromium-new-sessionon --app=http://stuk/InfoDoc --Auto >/dev/null 2>&1 &
    chromium_sessionon="chromium-new-sessionon"
    if [[ "$USER" == root ]]; then
    chromium_sessionon="chromium_sessionon_root"
    fi
    rm -rf "$dir_chromium/$chromium_sessionon";
    if [[ "$XDG_SESSION_TYPE" != x11 || "$XDG_SESSION_TYPE" != X11 ]]; then
        XDG_SESSION_TYPE=notX11
    fi
    nohup "$dir_chromium/chrome" \
    --user-data-dir="$dir_chromium/$chromium_sessionon" \
    --no-sandbox \
    --app="file://$SCRIPT_DIR/Demo/index.htm" \
    --disable-web-security \
    --test-type \
    --start-maximized \
    --no-zygote >/dev/null 2>&1 &
    echo $!
}

start_resize параметры запуска для InfoDoc.sh

start_resize() {
#   --start-maximized --kiosk --force-device-scale-factor=1.5
#     rm -rf /tmp/chromium-new-sessionon;
#     nohup chromium --user-data-dir=/tmp/chromium-new-sessionon --app=http://stuk/InfoDoc --Auto >/dev/null 2>&1 &
    chromium_sessionon="chromium-new-sessionon"
    if [[ "$USER" == root ]]; then
    chromium_sessionon="chromium_sessionon_root"
    fi
    rm -rf "$dir_chromium/$chromium_sessionon";
    nohup bash << EOF_BASH > /dev/null 2>&1 &
    if [[ "$XDG_SESSION_TYPE" == x11 || "$XDG_SESSION_TYPE" == X11 ]]; then
        "$dir_VirtualGL" -d $(ls /dev/dri/card* | tail -n1) "$dir_chromium/chrome" \
        --user-data-dir="$dir_chromium/$chromium_sessionon" \
        --no-sandbox \
        --app="file://$SCRIPT_DIR/Demo/index.htm" \
        --disable-web-security \
        --test-type \
        --kiosk \
        --no-zygote
    else
        XDG_SESSION_TYPE=notX11 "$dir_chromium/chrome" \
        --user-data-dir="$dir_chromium/$chromium_sessionon" \
        --no-sandbox \
        --app="file://$SCRIPT_DIR/Demo/index.htm" \
        --disable-web-security \
        --test-type \
        --kiosk \
        --no-zygote
    fi
EOF_BASH
    echo "$!"
}

Как на виртуальном экране Xephyr, Xvfb (X-сервере) реализованном над Xorg добавить поддержку GPU видео карты.

Когда нужно запустить Xorg в фоне для предоставления glx API приложению. Существуют способы создания виртуальных дисплеев

Xvfb :99 -ac -screen 0 1x1x24 -listen tcp +extension GLX +render -noreset

или мой способ через Xephyr, который создаст дисплей окно.

Xephyr -br -ac -noreset -screen "$display" -resizeable -title "$title_InfoDoc" :$unique_id &

-ac отключить ограничения контроля доступа

-br создать корневое окно с черным фоном

-noreset Не сбрасывайте настройки после завершения работы последнего клиента.

-screen -ширина экрана[/ШИРИНАММ]xвысота[/ВЫСОТАМММ][+[-]смещение по оси X][+[-]смещение по оси Y][@поворот][X][Y][глубина/BPP[xчастота]] Укажите характеристики экрана 1920x1080

-resizable Сделать окна Xephyr изменяемыми по размеру

-title [title] устанавливает заголовок окна в свойстве WM_NAME

:$unique_id задаёт номер экрана в переменной окружения DISPLAY

Этот параметр +iglx «Разрешить создание косвенных контекстов GLX» не влияет на поддержку GPU видеокарты у Chromium.

Для того чтобы далее все операции по умолчанию происходили на созданном экране:

export DISPLAY=:$unique_id ;

Поддержка GPU видео карты затем происходит через вызов запускаемого приложения через команду "$dir_VirtualGL" -d $(ls /dev/dri/card* | tail -1) Пример:

/VirtualGL/bin/vglrun -d $(ls /dev/dri/card* | tail -1) chromium

/VirtualGL/bin/vglrun файл появляется после сборки virtualgl-main

зависимости для установки

sudo apt-get install cmake build-essential libx11-dev libx11-xcb-dev \
libxcb-glx0-dev libxcb-keysyms1-dev libgl1-mesa-dev libxtst-dev \
libjpeg-turbo*-dev libjpeg-turbo* libglu1-mesa-dev libxext-dev libxi-dev \
libxmu-dev ocl-icd-opencl-dev opencl-headers libturbojpeg-dev \
xserver-xorg-video-fbdev xserver-xorg-video-dummy x11-utils libxdo3 xclip

$SCRIPT_DIR директория в которой virtualgl-main

rm -rf "/tmp/virtualgl_main_build"
mkdir "/tmp/virtualgl_main_build" && cd "/tmp/virtualgl_main_build"
cmake -S "$SCRIPT_DIR"/virtualgl-main -B "/tmp/virtualgl_main_build" -DCMAKE_BUILD_PARALLEL_LEVEL=$(nproc) && \
# rm -rf "$SCRIPT_DIR"/virtualgl-main/build
# mkdir "$SCRIPT_DIR"/virtualgl-main/build && cd "$SCRIPT_DIR"/virtualgl-main/build
# cmake .. -DCMAKE_BUILD_PARALLEL_LEVEL=$(nproc) && \
make -j$(nproc) && \
make install && \

echo "FINISH VirtualGL"

$(ls /dev/dri/card* | tail -1) Этот запрос вернёт видеокарту, на которой будут происходить расчёты.

После вызова /VirtualGL/bin/vglrun -d $(ls /dev/dri/card* | tail -1) указывается одно приложение, которое будет запущено с поддержкой GPU видеокарты, но на новом экране Xephyr.

Работа VirtualGL с разными приложениями полностью актуальна, таким образом можно менять видеокарту, на которой будет запущен экземпляр приложения, тем самым обеспечивая балансировку нагрузки для сервисов облачного гейминга.

Как реализовать буфер обмена между дисплеями через xclip в Astra Linux и других системах Linux.

Существуют некоторые статьи, которые предлагают использовать различные способы для этого, но в этих статьях нет конкретных примеров. Я предлагаю синхронизировать буферы обмена через xclip, используя Bash-код.

DISPLAY_OLD=$(echo $DISPLAY)
Xephyr -br -ac -noreset -screen "$display" -resizeable -title "$title_InfoDoc" :$unique_id &
XEYPH_PID=$!
sync_buffer_xephyr() {

if ! command -v xclip >/dev/null 2>&1; then
    echo "Error: Install xclip (sudo apt install xclip or sudo pacman -S xclip)"
    exit 1
fi

primary_buffer=""
clipboard_buffer=""

check_pid_alive() {
    if ! kill -0 "$XEYPH_PID" 2>/dev/null; then
        echo "The XEYPH has terminated and sync_buffer_xephyr OFF"
        exit 0
    fi
}

while true; do

    check_pid_alive;

    buffer_primary_unique_id="$({ xclip -o -selection primary -display :$unique_id ; } 2>/dev/null)"
    buffer_primary_DISPLAY_OLD="$({ xclip -o -selection primary -display $DISPLAY_OLD ; } 2>/dev/null)"
    buffer_clipboard_unique_id="$({ xclip -o -selection clipboard -display :$unique_id ; } 2>/dev/null)"
    buffer_clipboard_DISPLAY_OLD="$({ xclip -o -selection clipboard -display $DISPLAY_OLD ; } 2>/dev/null)"

    if [[ "$primary_buffer" != "$buffer_primary_DISPLAY_OLD" ]]; then
        primary_buffer="$buffer_primary_DISPLAY_OLD"
        check_pid_alive && echo "$buffer_primary_DISPLAY_OLD" | xclip -selection primary -i -display :$unique_id
    elif [[ "$primary_buffer" != "$buffer_primary_unique_id" ]]; then
        primary_buffer="$buffer_primary_unique_id"
        check_pid_alive && echo "$buffer_primary_unique_id" | xclip -selection primary -i -display $DISPLAY_OLD
    fi

    if [[ "$clipboard_buffer" != "$buffer_clipboard_DISPLAY_OLD" ]]; then
        clipboard_buffer="$buffer_clipboard_DISPLAY_OLD"
        check_pid_alive && echo "$buffer_clipboard_DISPLAY_OLD" | xclip -selection clipboard -i -display :$unique_id
    elif [[ "$clipboard_buffer" != "$buffer_clipboard_unique_id" ]]; then
        clipboard_buffer="$buffer_clipboard_unique_id"
        check_pid_alive && echo "$buffer_clipboard_unique_id" |  xclip -selection clipboard -i -display $DISPLAY_OLD
    fi

# echo "$({ xclip -o -selection primary -display :$unique_id ; } 2>&1)"
# echo "$({ xclip -o -selection clipboard -display :$unique_id ; } 2>&1)"
#
# echo "$({ xclip -o -selection primary -display $DISPLAY_OLD ; } 2>&1)"
# echo "$({ xclip -o -selection clipboard -display $DISPLAY_OLD ; } 2>&1)"
sleep 0.5;
done
}

Этот скрипт реализует синхронизацию буфера обмена (клипборд и примари) между главным дисплеем и виртуальным дисплеем, созданным с помощью Xephyr. Это особенно полезно, если вы работаете с вложенными X-серверами, например, при запуске графических приложений внутри контейнера или виртуальной среды.

Функция sync_buffer_xephyr

Основная задача — непрерывно следить за содержимым буферов обмена (primary и clipboard) у главного дисплея и у виртуального Xephyr-дисплея. Если содержимое различается, скрипт копирует данные между ними, тем самым синхронизируя буферы.

Проверка жив ли Xephyr

Функция check_pid_alive проверяет, жив ли процесс Xephyr (через kill -0). Если процесс завершился — цикл завершается.

Чтение буферов обмена

Используется xclip для получения текущего содержимого буферов:

xclip -o -selection primary -display :$unique_id — читает primary буфер виртуального дисплея

xclip -o -selection primary -display $DISPLAY_OLD — читает primary буфер основного дисплея

То же для clipboard.

Сравнение и синхронизация

Скрипт сравнивает содержимое буферов:

Если содержимое primary буфера основного дисплея изменилось, это значение передаётся во виртуальный Xephyr.

Если изменилось во виртуальном Xephyr — отправляется назад.

То же для clipboard.

Это делается с помощью xclip -selection ... -i (инпут), что позволяет записать значение в буфер обмена указанного дисплея.

Цикл с задержкой

Всё делается в бесконечном цикле с задержкой 0.5 секунды, чтобы не нагружать процессор.

Заключение

WebDesktopGL — это стабильная и эффективная альтернатива Electron для Linux-систем с ограничениями лицензирования ПО. Она позволяет бесплатно и легко трансформировать веб-приложения в мощные десктопные программы с поддержкой аппаратного ускорения и полноценной интеграцией с операционной системой. Всё решение построено на открытых технологиях, легко модифицируемо и расширяемо. Использование Xephyr, VirtualGL, xclip и автоматизированных скриптов обеспечивает надёжную работу в широком диапазоне Linux-сред, включая такие специализированные системы, как Astra Linux.

Изоляция и безопасность: Приложения запускаются с минимальным набором прав и изолированного профиля пользователя, что повышает безопасность и предотвращает конфликты с родительской сессией.

Гибкость: Можно использовать как на X11, так и (частично) на Wayland (без аппаратного ускорения).

Кроссплатформенность и совместимость: Поддержка Astra Linux и других дистрибутивов Linux, возможность запускаа из консоли на удалённых серверах через SSH и скрипты.

Готовые для деплоя решения: Простота отправки скриптов на удалённую машину позволяет организовывать быстрое развертывание информационных систем без лишнего ПО.

Расширяемость: Архитектура позволяет легко добавлять новые функции (например, поддержку других браузеров, дополнительные параметры запуска, интеграцию с системой печати и т.д.).

Комментарии (1)


  1. gudvinr
    31.08.2026 04:22

    Это не альтернатива Electron. Важная часть Electron - это набор API для работы с хвостом за пределами браузера.

    Это просто аналог PWA для сайтов у которых нет манифеста с включением PWA.