From c9b466e0da4460c188accf79ad98b9bef3452ed5 Mon Sep 17 00:00:00 2001 From: Alexey Martemyanov Date: Wed, 27 May 2026 14:08:38 +0600 Subject: [PATCH] =?UTF-8?q?[2026-05-27]=20Whale:=20update=20magic4pc=20doc?= =?UTF-8?q?s=20=E2=80=94=20letterbox=20scaling,=20display=20switching,=20c?= =?UTF-8?q?lamp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- family/how-to/htpc-magic4pc.md | 39 ++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/family/how-to/htpc-magic4pc.md b/family/how-to/htpc-magic4pc.md index aaeab6db..e7c18dfd 100644 --- a/family/how-to/htpc-magic4pc.md +++ b/family/how-to/htpc-magic4pc.md @@ -21,6 +21,7 @@ Go-клиент для LG Magic Remote (webOS приложение на TV). | Кривые координаты мыши | Динамический scale через `xdotool getdisplaygeometry` | | Крестик слал Ctrl/a/s/d | TV keycodes 37-40 → `Left/Up/Right/Down` keysym | | Цифры слали мусор | ASCII keycodes → `string(rune(key))` | +| Мышь не двигалась на gamescope алерте | Letterbox-алгоритм: `xdotool search --onlyvisible` → 16:9 viewport → scale+offset с clamp нуля | ## Маппинг кнопок | Кнопка | Keycode | Gaming Mode (gamescope) | KDE Desktop | @@ -49,12 +50,42 @@ Go-клиент для LG Magic Remote (webOS приложение на TV). ## Определение сессии `isGamescopeSession()` — читает `/proc/*/cmdline`, ищет `kwin_wayland`. Если нет → gamescope. -## Koordinаты мыши -TV шлёт координаты в пространстве 0–1920 × 0–1080. -При старте xdotool запрашивается `xdotool getdisplaygeometry` → вычисляется scale. -Работает корректно при любом разрешении экрана. +## Координаты мыши + +TV шлёт координаты в пространстве 0–1920 × 0–1080. + +### В gamescope (Steam Big Picture) + +При открытии окна (алерт, диалог) клиент определяет его размер через `xdotool search --onlyvisible`, так как `getactivewindow` не работает в gamescope (нет `_NET_ACTIVE_WINDOW`). Если окно единственное видимое — используется **letterbox-алгоритм**: + +1. Активное окно находится через `xdotool search --onlyvisible`, отсекая `steamcompmgr`, `Default IME` и окна ≤5×5 +2. Вычисляется **letterbox viewport** в пропорции 16:9 на основе ширины окна: `lb_h = win_w * 9/16` +3. Вычисляется **отступ**: `off_y = -(lb_h - win_h) / 2` (отрицательный — сдвигает viewport вверх, чтобы TV y=0 совпадал с верхом чёрной полосы) +4. TV-координаты маппятся в X11 через scale и offset: + `x11_x = tv_x * scale_x + off_x` + `x11_y = tv_y * scale_y + off_y` + где `scale_x = scale_y = lb_w / 1920` +5. Отрицательные координаты обрезаются до 0 (xdotool их не принимает) +6. Если окно не найдено — фолбэк на `getdisplaygeometry` (весь дисплей) + +**Пример для алерта 288×89:** +- Letterbox viewport: 288×162 +- Scale: 0.15×0.15 +- Offset: 0, -36.5 +- TV (0,0) → X11 (0,0); TV (288,89) → X11 (43, 13) + +### В KDE десктопе + +Используется `getdisplaygeometry` — scale = display_size / 1920×1080. Офсет 0,0. + +### Определение сессии +- `isGamescopeSession()` — ищет `kwin_wayland` по argv[0] в /proc. Нет → gamescope +- `activeDisplay()` — находит X display для инъекции: + - KDE: берёт Xwayland display из аргументов kwin_wayland + - Gamescope: использует `:1` (game Xwayland) если есть visible окна, иначе `:0` (Steam BP) ## Проблемы которые могут вернуться - **xdotool умирает** (write error) → KDE показывает XTest диалог. Разрешить и включить `XwaylandEisNoPrompt=true`. - **TV "service error"** — если висит намертво, cold reboot TV (выдернуть из розетки). - **Бинарь слетает** после `rpm-ostree upgrade` → пересобрать и скопировать. +- **Display switching** — при смене между `:0` и `:1` xdotool перезапускается. Если переключение происходит часто (мигающие окна) — возможны краткие потери мыши.