Chromium only builds the renderer's accessibility tree when it detects
an assistive technology — and dictation tools that insert text through
the OS accessibility APIs (Wispr Flow etc.) do not register the way a
screen reader does, so the tree never appeared: the window exposed only
its chrome and the contenteditable composer was unreachable. No
setAccessibilitySupportEnabled call existed anywhere in the electron
tree, on any platform.
- apps/desktop/electron/renderer-accessibility.ts (new): the
platform/env decision in a dependency-free module (app object
injected) — ON by default on darwin/win32 where the typed API exists,
opt-out via HERMES_DESKTOP_RENDERER_ACCESSIBILITY=0. Linux is untouched
(ATK flow needs no manual enable; the API is not typed there).
- main.ts calls it right after app ready (the API's requirement).
- hermes desktop launcher: `desktop.renderer_accessibility: false` in
config.yaml bridges to the env var — only the opt-out is bridged, so
the default never depends on the launcher path. Same shape as
desktop.disable_gpu. config_defaults documents the key.
Family note: the same seam on Windows is #92607 (Wispr Flow there);
this one enablement should resolve both platforms, but the Windows leg
is unverified on this machine, so #92607 stays open. The dictation
keybind half of #118271 already landed separately in 3cc24b0130
(composer.dictate action; rebindable-key ask tracked by #112118/#71658,
left alone).
Tests: 4 electron-side unit tests (default-on per platform, Linux skip,
opt-out words + explicit env precedence, injected app switch flips
exactly when enabled); Python side: 12-case normalization parametrize +
env-bridging precedence test (ON sets nothing, opt-out bridges, explicit
env wins) in test_gui_command.py; _desktop_launch_options signature
consumers updated. All green; the remaining lucide-react TS2307 in
onboarding setup.tsx is pre-existing on base (missing dep of that
workspace file, untouched here).
Fixes #118271
55 lines
2.6 KiB
Python
55 lines
2.6 KiB
Python
"""``hermes gui`` under WSLg selects the installed Mesa D3D12 driver before Electron spawns
|
|
its GPU process (#106117) — and never overrides an explicit Mesa choice or fires off-WSL."""
|
|
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
from hermes_cli import main_desktop
|
|
from hermes_platform.host import runtime as host_runtime
|
|
|
|
|
|
def _launch_env(monkeypatch, tmp_path, *, wsl: bool, dxg: bool, driver: bool) -> dict:
|
|
"""Run the real launcher env builder against a fake WSL host laid out under ``tmp_path``."""
|
|
dxg_path = tmp_path / "dxg"
|
|
driver_path = tmp_path / "d3d12_dri.so"
|
|
dxg_path.unlink(missing_ok=True)
|
|
driver_path.unlink(missing_ok=True)
|
|
if dxg:
|
|
dxg_path.touch()
|
|
if driver:
|
|
driver_path.write_bytes(b"\x7fELF")
|
|
monkeypatch.setattr(host_runtime, "_wsl_detected", wsl)
|
|
monkeypatch.setattr(main_desktop, "_WSL_DXG_DEVICE", dxg_path)
|
|
monkeypatch.setattr(main_desktop, "_WSL_D3D12_DRIVERS", (tmp_path / "missing_dri.so", driver_path))
|
|
monkeypatch.setattr(main_desktop, "_desktop_launch_options", lambda: ([], "auto", "auto", "auto", True))
|
|
monkeypatch.setattr(main_desktop, "_detect_linux_password_store", lambda: None)
|
|
env, _flags = main_desktop._desktop_launch_env(argparse.Namespace(cwd=str(tmp_path)))
|
|
return env
|
|
|
|
|
|
def test_wslg_with_dxg_and_installed_d3d12_driver_selects_gpu_mesa_backend(monkeypatch, tmp_path):
|
|
for var in main_desktop._MESA_DRIVER_OVERRIDES:
|
|
monkeypatch.delenv(var, raising=False)
|
|
|
|
env = _launch_env(monkeypatch, tmp_path, wsl=True, dxg=True, driver=True)
|
|
|
|
assert env["GALLIUM_DRIVER"] == "d3d12"
|
|
assert Path(env["HERMES_DESKTOP_CWD"]) == tmp_path.resolve() # the rest of the env still builds
|
|
|
|
|
|
def test_explicit_mesa_choice_and_non_wsl_hosts_are_left_alone(monkeypatch, tmp_path):
|
|
for var in main_desktop._MESA_DRIVER_OVERRIDES:
|
|
monkeypatch.delenv(var, raising=False)
|
|
|
|
# WSL + GPU present, but the user pinned software rendering: their choice is authoritative.
|
|
monkeypatch.setenv("LIBGL_ALWAYS_SOFTWARE", "1")
|
|
env = _launch_env(monkeypatch, tmp_path, wsl=True, dxg=True, driver=True)
|
|
assert "GALLIUM_DRIVER" not in env and env["LIBGL_ALWAYS_SOFTWARE"] == "1"
|
|
monkeypatch.delenv("LIBGL_ALWAYS_SOFTWARE")
|
|
|
|
# Any one leg missing → untouched: plain Linux with a dxg-like node and driver installed,
|
|
# WSL without /dev/dxg, WSL with /dev/dxg but no Mesa d3d12 driver on disk.
|
|
for wsl, dxg, driver in ((False, True, True), (True, False, True), (True, True, False)):
|
|
env = _launch_env(monkeypatch, tmp_path, wsl=wsl, dxg=dxg, driver=driver)
|
|
assert "GALLIUM_DRIVER" not in env, (wsl, dxg, driver)
|