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",