Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,37 @@ The interface was rewritten from Tkinter to Qt (PySide6).

---

## 3.2.1 - 2026-10-25

- У кнопок «+ Добавить» и «Действия с профилем» своя стрелка ▾ рядом с текстом вместо крошечного значка Fusion под ним.
- Ширина колонок таблицы - по содержимому: «Название» больше не обрезается, а «Параметры» не держат лишнего места; если всё не влезает, колонки ужимаются пропорционально, по-прежнему без горизонтальной прокрутки.
- Состояние геймпада и вибрации внизу - обычным цветом текста, а не бледным.
- Дефис вместо длинного тире во всех текстах.
- Тестов 254 (+6): ширина колонок как закон, стрелки меню, цвет состояния, нет длинного тире.

## 3.2.0 - 2026-09-26

- Руль читается без pygame. Слой ввода работает с SDL через PySDL2, `SDL2.dll` берётся из `pysdl2-dll` и закреплена на SDL 2.28.4 - той же версии, что была у pygame 2.6.1. GUID устройств, оси, кнопки, крестовина, горячее подключение, вибрация и виртуальный геймпад работают как раньше; привязки в `config.json` находят свои устройства.
- `WheelScript.exe --selftest [файл]`: сервис ввода без окна на 2 секунды, в файл пишутся версия SDL, загруженная `SDL2.dll`, устройства и ошибки. Ничего не нажимает, руль не трясёт.
- В сборку кладётся только `SDL2.dll` (без библиотек картинок, звука и шрифтов, которые тянул pygame); сборка проверяет, что pygame в неё не попал, и прогоняет самопроверку собранного exe. Портативный архив стал меньше на 1,7 МБ.
- Тестов 248 (+43), среди них слой ввода с подделкой SDL и с настоящей SDL и виртуальным рулём.

## 3.1.0 - 2026-09-25

Место, размер и развёрнутость окна при закрытии пишутся в `window.json` рядом с `config.json` и возвращаются при следующем запуске. Если того монитора больше нет или заголовок окна оказался бы за пределами всех экранов, окно открывается обычного размера посередине. Испорченный `window.json` не трогает настройки: это отдельный файл, и он не может отправить `config.json` в `config.broken-*.json`.

Драйвер ViGEmBus для виртуального геймпада, как и раньше, ставится отдельно. Тестов 205, все зелёные.

## 3.0.1 - 2026-09-23

Ярлык раньше записывался через `WScript.Shell`, который сохраняет `.lnk` в кодовой странице ANSI. Если в пути были буквы вне этой кодовой страницы (кириллица на английской Windows, иероглифы на русской), ярлык не создавался вовсе, а текст ошибки PowerShell терял те же буквы в кодовой странице OEM по дороге к окну. Нашёл это CI на раннере GitHub с английской Windows: CI этого репозитория был красным с первой публикации. Теперь ярлык пишется через `IShellLinkW`, скрипт уходит в PowerShell как `-EncodedCommand`, а ошибки возвращаются в UTF-8. Тесты используют японские буквы, которых нет ни в одной кодовой странице русской Windows, поэтому без исправления они падают и на русской машине.

Драйвер ViGEmBus для виртуального геймпада, как и раньше, ставится отдельно. Тестов 196, зелёные локально и в CI.

## 3.0.0 - 2026-09-22

Интерфейс переписан с Tkinter на Qt (PySide6).

**Зачем:** Tk заметно тормозил при изменении размера окна на Windows, а тёмную тему приходилось собирать по виджету. Qt рисует окно целиком и следует системной светлой или тёмной теме.

**Что делает программа:** переводит руль, педали, кнопки и коробку передач в мышь, клавиатуру или виртуальный геймпад Xbox 360 - для игр, которые руль не понимают. Привязка делается так: щёлкнуть по полю ввода и подвигать то, что нужно привязать; программа сама узнаёт ось, кнопку или крестовину и догадывается, педаль ли это.
22 changes: 11 additions & 11 deletions docs/2026-09-19-qt-port-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## Зачем

Tk на Windows медленно перерисовывает окно при ресайзе (каждый виджет — отдельное системное окно без двойной буферизации). Тёмная тема в Tk держалась на перекраске каждого виджета и на самодельных выпадающих меню. В Qt тема, меню и заголовок окна красятся сами.
Tk на Windows медленно перерисовывает окно при ресайзе (каждый виджет - отдельное системное окно без двойной буферизации). Тёмная тема в Tk держалась на перекраске каждого виджета и на самодельных выпадающих меню. В Qt тема, меню и заголовок окна красятся сами.

## Что не меняется

Expand All @@ -14,27 +14,27 @@ Tk на Windows медленно перерисовывает окно при р

| Файл | Что делает |
|---|---|
| `qt/fields.py` | `Choice` — QComboBox «подпись ↔ ключ». `InputField` — клик, затем кнопка/ось/крестовина руля попадает в поле (опрос 15 мс, таймаут 15 с, Esc — отмена). `KeyField` — клик, затем клавиша или сочетание (собираются, пока хоть одна клавиша нажата), плюс выбор из списка, плюс «✕» для пустого значения. |
| `qt/fields.py` | `Choice` - QComboBox «подпись ↔ ключ». `InputField` - клик, затем кнопка/ось/крестовина руля попадает в поле (опрос 15 мс, таймаут 15 с, Esc - отмена). `KeyField` - клик, затем клавиша или сочетание (собираются, пока хоть одна клавиша нажата), плюс выбор из списка, плюс «✕» для пустого значения. |
| `qt/monitor.py` | `Monitor`: список устройств и живой вид осей, кнопок, крестовин, рисуется QPainter. Перерисовывается только при изменении состояния или ширины. |
| `qt/bindings_model.py` | `BindingsModel` (QAbstractTableModel): колонки Вкл, Название, Ввод с руля, Действие, Параметры. Роль подсветки «срабатывает сейчас». |
| `qt/binding_dialog.py` | `BindingDialog` (QDialog, модальный): название, ввод, режим оси/крестовины, действие, параметры действия, тонкая настройка (мёртвая зона, кривая, порог, инверсия, включена), полоска проверки. Пока открыт — `service.suspend()`, при любом закрытии ровно один `resume()`. |
| `qt/binding_dialog.py` | `BindingDialog` (QDialog, модальный): название, ввод, режим оси/крестовины, действие, параметры действия, тонкая настройка (мёртвая зона, кривая, порог, инверсия, включена), полоска проверки. Пока открыт - `service.suspend()`, при любом закрытии ровно один `resume()`. |
| `qt/main_window.py` | `MainWindow`: статус (точка + текст), кнопка вкл/выкл, горячая клавиша, профиль и меню «Действия с профилем ▾», таблица привязок и кнопки «+ Добавить ▾» (пресеты), Изменить, Копия, Удалить, ▲, ▼, монитор справа (QSplitter), нижние настройки (включать при запуске, частота опроса, тема, ярлык, папка настроек), строка геймпада и вибрации. Опрос сервиса QTimer 40 мс. |
| `theme.py` | `LABELS`, палитры `LIGHT`/`DARK` смысловых цветов (все hex), `P` — текущая, `apply(app, mode)` ставит `QStyleHints.setColorScheme` и выбирает палитру по фактической теме Qt. |
| `theme.py` | `LABELS`, палитры `LIGHT`/`DARK` смысловых цветов (все hex), `P` - текущая, `apply(app, mode)` ставит `QStyleHints.setColorScheme` и выбирает палитру по фактической теме Qt. |
| `app.py` | логирование, один экземпляр (сообщение через QMessageBox), `QApplication` со стилем windows11, шрифт, русские тексты Qt, иконка. |

`gui.py` удаляется.

## Клавиши

`keys.from_native(vk, scan, extended)` вместо `keys.from_tk`. Qt на Windows даёт `nativeVirtualKey()` (для Shift/Ctrl/Alt — общий код 0x10/0x11/0x12) и `nativeScanCode()`. Правые модификаторы: Shift по скан-коду 0x36, Ctrl и Alt по флагу extended (бит 24 lParam; Qt кладёт его в `nativeModifiers()` как 0x01000000, его читает `keys.is_extended`). PrintScreen приходит только отпусканием — сохраняем как в 2.x.
`keys.from_native(vk, scan, extended)` вместо `keys.from_tk`. Qt на Windows даёт `nativeVirtualKey()` (для Shift/Ctrl/Alt - общий код 0x10/0x11/0x12) и `nativeScanCode()`. Правые модификаторы: Shift по скан-коду 0x36, Ctrl и Alt по флагу extended (бит 24 lParam; Qt кладёт его в `nativeModifiers()` как 0x01000000, его читает `keys.is_extended`). PrintScreen приходит только отпусканием - сохраняем как в 2.x.

## Поведение (как в 2.2.1)

- Щелчок по колонке «Вкл» переключает привязку; второй быстрый щелчок (двойной) переключает ещё раз.
- Повторный щелчок по выделенной строке или щелчок по пустому месту снимает выделение. Двойной щелчок по строке открывает редактор, даже если первый щелчок снял выделение. Delete — удалить (с вопросом), Enter — изменить.
- Повторный щелчок по выделенной строке или щелчок по пустому месту снимает выделение. Двойной щелчок по строке открывает редактор, даже если первый щелчок снял выделение. Delete - удалить (с вопросом), Enter - изменить.
- Строки выключенных привязок серые, срабатывающие подсвечены голубым.
- Все изменения сразу сохраняются в `config.json` и передаются сервису.
- «Как в системе» — Qt сам следует за Windows.
- «Как в системе» - Qt сам следует за Windows.

## Сборка

Expand All @@ -58,13 +58,13 @@ Tk на Windows медленно перерисовывает окно при р

- **Выделение строки таблицы** рисует свой делегат: стиль windows11 рисует его едва заметной полоской в каждой ячейке, а в тёмной теме оно сливалось с голубой подсветкой срабатывающих привязок. Теперь это заливка цветом акцента и одна полоска слева, заметно отличная и от фона, и от подсветки.
- **Колонки таблицы** делят ширину окна (как в 2.x), горизонтальной прокрутки нет.
- **Esc в редакторе привязки** сначала отменяет захват ввода с руля, второй Esc закрывает окно — где бы ни был фокус.
- **Tab при захвате клавиши** — это клавиша, а не переход к следующему полю; сочетания окна во время захвата не срабатывают.
- **Светлая палитра** теперь целиком в hex (раньше — системные цвета Windows), поэтому контраст проверяется и для неё: 7 тестов, которые раньше пропускались, работают.
- **Esc в редакторе привязки** сначала отменяет захват ввода с руля, второй Esc закрывает окно - где бы ни был фокус.
- **Tab при захвате клавиши** - это клавиша, а не переход к следующему полю; сочетания окна во время захвата не срабатывают.
- **Светлая палитра** теперь целиком в hex (раньше - системные цвета Windows), поэтому контраст проверяется и для неё: 7 тестов, которые раньше пропускались, работают.
- **Установщик** при обновлении удаляет старую папку `_internal` (там были библиотеки Tk от 2.x).

## Результат

- 196 тестов (движок + 46 тестов интерфейса + разбор клавиш Qt), без пропусков.
- Проверка мутациями: 16 поломок ключевых мест интерфейса, все пойманы тестами.
- Сборка: portable 36 МБ, setup 28 МБ. Собранный exe запускается (лог: «3.0.0 starting»). Живая проверка окна — через computer use на демо с поддельным сервисом: тема, монитор, подсветка, редактор привязки.
- Сборка: portable 36 МБ, setup 28 МБ. Собранный exe запускается (лог: «3.0.0 starting»). Живая проверка окна - через computer use на демо с поддельным сервисом: тема, монитор, подсветка, редактор привязки.