From b06272437ce5174efbe9c22c87f915cdbac91150 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20Sonic?= Date: Thu, 30 Jul 2026 13:40:04 +0300 Subject: [PATCH] =?UTF-8?q?fix(gui):=20=D0=BF=D1=80=D0=BE=D1=81=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9=20=D1=80=D0=B5=D0=BD=D0=B4=D0=B5=D1=80,=20?= =?UTF-8?q?=D1=87=D1=82=D0=BE=D0=B1=D1=8B=20=D0=BE=D0=BA=D0=BD=D0=BE=20?= =?UTF-8?q?=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=B2=D0=B0=D0=BB=D0=BE=D1=81?= =?UTF-8?q?=D1=8C=20=D0=B1=D0=B5=D0=B7=203D=20(#28)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Интерфейс построен на системном WebView, а тот без 3D-ускорения окно не создаёт. Отсюда весь класс жалоб: не стартует в виртуалке, не стартует с дефолтным драйвером Microsoft, не стартует без монитора. Диагноз в #17 дал @de4me: в VirtualBox приложение запускается только после включения галочки «Включить ускорение 3D». Перед стартом Tauri TGLock теперь сам запрашивает программный рендер: - Windows: WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS с --disable-gpu и --disable-gpu-compositing; - Linux: WEBKIT_DISABLE_COMPOSITING_MODE и WEBKIT_DISABLE_DMABUF_RENDERER; - macOS: не требуется, WebKit сам уходит в программный рендер. Для панели со статусом программный рендер не стоит ничего заметного, поэтому он выбран значением по умолчанию, а не аварийным режимом. Уже заданные оператором переменные не перезаписываются, TGLOCK_FORCE_GPU=1 отключает механизм целиком. Логика вынесена в чистую функцию software_rendering_vars и покрыта четырьмя тестами: значение по умолчанию, отключение через TGLOCK_FORCE_GPU, уважение чужой переменной и правильный набор ключей на каждой платформе. Версия поднята до 2.0.0-beta.2 в Cargo.toml, package.json и tauri.conf.json: нужен тег, чтобы в релиз попали и tglock-cli, и этот фикс. README получил отдельный вопрос в FAQ про «окно не появляется», ARCHITECTURE_V2.md — обновлённый пункт в Current limitations. Co-authored-by: by-sonic <171230345+by-sonic@users.noreply.github.com> --- Cargo.lock | 2 +- Cargo.toml | 2 +- README.md | 10 +++++ docs/ARCHITECTURE_V2.md | 20 +++++---- package.json | 2 +- src/main.rs | 96 +++++++++++++++++++++++++++++++++++++++++ tauri.conf.json | 2 +- 7 files changed, 122 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index af7996b..4d1f669 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3553,7 +3553,7 @@ dependencies = [ [[package]] name = "tglock" -version = "2.0.0-beta.1" +version = "2.0.0-beta.2" dependencies = [ "aes", "cipher", diff --git a/Cargo.toml b/Cargo.toml index 5552a2a..bc5edab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "tglock" -version = "2.0.0-beta.1" +version = "2.0.0-beta.2" edition = "2021" rust-version = "1.88" description = "Telegram unblock via local WebSocket tunnel" diff --git a/README.md b/README.md index 92507f9..a77c23f 100644 --- a/README.md +++ b/README.md @@ -323,6 +323,16 @@ xattr -cr /Applications/TGLock.app - На macOS — убедись что снят Gatekeeper (`xattr -cr ...`). +
+Приложение вообще не запускается — окно не появляется + +Так проявляется отсутствие 3D-ускорения: интерфейс построен на системном WebView, а тот без ускорения окно не создаёт. Отсюда же случаи «не работает в виртуалке», «не стартует с дефолтным драйвером Microsoft» и «нет монитора». + +Начиная с **2.0.0-beta.2** TGLock сам просит у WebView программный рендер, так что на таких машинах должен запускаться. Если хочется вернуть аппаратное ускорение — запусти с переменной `TGLOCK_FORCE_GPU=1`. + +Если окно всё равно не появилось, интерфейс тебе и не нужен: возьми [`tglock-cli`](#-без-графического-интерфейса-tglock-cli), которому WebView не требуется вообще. И напиши в [#10](https://github.com/by-sonic/tglock/issues/10) или [#17](https://github.com/by-sonic/tglock/issues/17), что именно за система — это как раз те ишью. +
+
Порт 1080 уже занят другим приложением diff --git a/docs/ARCHITECTURE_V2.md b/docs/ARCHITECTURE_V2.md index fc39c20..7f4ec37 100644 --- a/docs/ARCHITECTURE_V2.md +++ b/docs/ARCHITECTURE_V2.md @@ -12,9 +12,11 @@ Фича `gui` включена по умолчанию и подтягивает `tauri`, `tauri-build` и `open`. При `--no-default-features` ни Tauri, ни системный WebView, ни фронтенд в сборку -не попадают, и `build.rs` не вызывает `tauri_build`. Это единственный способ -собрать и запустить TGLock там, где WebView не создаёт окно: сервер, контейнер, -виртуалка, машина без монитора или без 3D-ускорения. +не попадают, и `build.rs` не вызывает `tauri_build`. Так TGLock собирается и +работает там, где WebView недоступен в принципе: сервер без графического +окружения, контейнер, машина без монитора. Для случаев, где WebView есть, но нет +3D-ускорения, GUI дополнительно просит программный рендер — см. Current +limitations. ## Local protocols @@ -109,11 +111,13 @@ Worker должен принимать WebSocket на: - SNI camouflage не включена: небезопасное отключение hostname verification из референсной реализации не переносится. - Голосовые звонки по UDP не поддерживаются. -- **GUI не запускается там, где WebView не может создать окно** — нет - 3D-ускорения, дефолтный видеодрайвер, отсутствует монитор, виртуальная - машина. Это ограничение Tauri, а не транспорта; программный рендер как - обходной путь не проверен. Рабочий вариант для таких машин — `tglock-cli` - (issues #10, #17). +- **GUI зависит от WebView, а тот — от 3D-ускорения.** Начиная с + 2.0.0-beta.2 приложение перед стартом Tauri само просит программный рендер: + на Windows через `WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS`, на Linux через + `WEBKIT_DISABLE_COMPOSITING_MODE` и `WEBKIT_DISABLE_DMABUF_RENDERER`. Уже + заданные оператором значения не перезаписываются, а `TGLOCK_FORCE_GPU=1` + возвращает аппаратное ускорение. Для машин без монитора остаётся + `tglock-cli`, которому WebView не нужен вовсе (issues #10, #17). - Windows-инсталлятор не подписан, macOS-сборка не нотарифицирована. Часть антивирусов реагирует на неподписанный установщик, открывающий локальный сокет; проверяемый ответ — сборка из исходников либо публичные логи diff --git a/package.json b/package.json index 026709e..dd341ef 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "tglock-ui", "private": true, - "version": "2.0.0-beta.1", + "version": "2.0.0-beta.2", "type": "module", "scripts": { "dev": "vite --port 1420", diff --git a/src/main.rs b/src/main.rs index 06c7ed9..2938e3b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -222,7 +222,56 @@ fn push_log(logs: &Arc>>, message: String, error: bool) { }); } +/// Environment variables that make the WebView render without a GPU. +/// +/// The window is never created when 3D acceleration is unavailable: no +/// monitor, the default Microsoft display driver, a virtual machine without +/// 3D enabled (by-sonic/tglock#10, by-sonic/tglock#17). For a small status +/// panel software rendering costs nothing noticeable, so preferring it is the +/// safer default. +/// +/// Values already present in the environment are never overwritten, and +/// `TGLOCK_FORCE_GPU` disables the whole mechanism. +fn software_rendering_vars( + force_gpu: bool, + is_set: impl Fn(&str) -> bool, +) -> Vec<(&'static str, &'static str)> { + if force_gpu { + return Vec::new(); + } + + let candidates: &[(&str, &str)] = if cfg!(target_os = "windows") { + &[( + "WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS", + "--disable-gpu --disable-gpu-compositing", + )] + } else if cfg!(target_os = "macos") { + // WebKit on macOS falls back to software rendering on its own. + &[] + } else { + &[ + ("WEBKIT_DISABLE_COMPOSITING_MODE", "1"), + ("WEBKIT_DISABLE_DMABUF_RENDERER", "1"), + ] + }; + + candidates + .iter() + .filter(|(key, _)| !is_set(key)) + .copied() + .collect() +} + +fn prefer_software_rendering() { + let force_gpu = std::env::var_os("TGLOCK_FORCE_GPU").is_some(); + for (key, value) in software_rendering_vars(force_gpu, |key| std::env::var_os(key).is_some()) { + std::env::set_var(key, value); + } +} + fn main() { + prefer_software_rendering(); + tauri::Builder::default() .setup(|app| { let settings_path = app @@ -243,3 +292,50 @@ fn main() { .run(tauri::generate_context!()) .expect("failed to run TGLock"); } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn software_rendering_is_requested_by_default() { + let vars = software_rendering_vars(false, |_| false); + if cfg!(target_os = "macos") { + assert!(vars.is_empty(), "macOS needs no override"); + } else { + assert!( + !vars.is_empty(), + "a machine without 3D acceleration must still get a window" + ); + } + } + + #[test] + fn force_gpu_disables_the_override() { + assert!(software_rendering_vars(true, |_| false).is_empty()); + } + + #[test] + fn an_operators_own_value_is_never_overwritten() { + assert!(software_rendering_vars(false, |_| true).is_empty()); + } + + #[test] + fn windows_uses_webview2_arguments_and_linux_uses_webkit_ones() { + let keys: Vec<_> = software_rendering_vars(false, |_| false) + .into_iter() + .map(|(key, _)| key) + .collect(); + if cfg!(target_os = "windows") { + assert_eq!(keys, ["WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS"]); + } else if cfg!(target_os = "linux") { + assert_eq!( + keys, + [ + "WEBKIT_DISABLE_COMPOSITING_MODE", + "WEBKIT_DISABLE_DMABUF_RENDERER" + ] + ); + } + } +} diff --git a/tauri.conf.json b/tauri.conf.json index 5438986..8ba74b4 100644 --- a/tauri.conf.json +++ b/tauri.conf.json @@ -1,7 +1,7 @@ { "$schema": "https://schema.tauri.app/config/2", "productName": "TGLock", - "version": "2.0.0-beta.1", + "version": "2.0.0-beta.2", "identifier": "com.bysonic.tglock", "build": { "beforeDevCommand": "npm run dev",