Releases: 2extndd/OpenParsec
Trackpad fix v9 — scroll inertia + monitor switch
Nightly-style build off `fix/trackpad-input` (commit d861222). Fake-signed `.ipa` for AltStore/sideload.
What changed since v8
- Scroll inertia restored (S03) — rewritten glide. The trackpad scroll path is a raw UIPanGestureRecognizer (no UIScrollView), which has no post-lift inertia, so the previous "let iPadOS provide the tail" approach removed inertia entirely. Now the glide decays from the peak velocity sampled during the gesture, driven by CADisplayLink with frame-rate-independent step/decay (consistent on 60 and 120 Hz). Cancelled on new scroll, zoom, and view dismissal.
- Monitor switch — confirm-and-retry (S10) — display switch is now a closed loop: the target output is re-sent on a backing-off schedule (0.35/0.8/1.5/2.5 s) until the host echoes it back (case 11), then stops. Fixes "needs 2–3 taps / pick current then the second one" and should also make the remembered display stick on reconnect. Degrades gracefully to spaced multi-resend if the host doesn't echo.
Known / still on you to verify on device
- Keyboard language switch (Mac host): the Cmd+Space capability already shipped in v8. In Settings, set the layout-sync dropdown to "⌘ + Space" (NOT "⌃ + ⇧" — Ctrl+Shift alone does not switch input on modern macOS). If language still won't switch even on Cmd+Space, the iPad-side auto-detect isn't firing on your device — report back and the next build will force Cmd+Space onto the manual "⌃⇧ → ⌘Space" toggle instead.
Build: GitHub Actions run 26509902878 (green).
v8 — trackpad dead-zone, Ctrl+Shift→Cmd+Space, crash/leak hardening (437ce38)
First green CI build of the full M001 remediation milestone. Fake-signed .ipa attached (sideload via AltStore/SideStore).
New in v8 (since v7):
- Trackpad dead-zone fixed (S09): defer system edge gestures under pointer lock — bottom-edge trackpad motion now reaches the app instead of the iPadOS swipe strip.
- Ctrl+Shift → Cmd+Space (S05): opt-in chord (Settings → Keyboard) that fires Cmd+Space on the host when you tap Ctrl+Shift alone; Ctrl+Shift+X host shortcuts still work. Also forwards cancelled key-ups so modifiers can't get stuck.
- Poor-network low-latency profile (S08): Low Latency Mode now also turns off decoder compatibility and caps bitrate to a 5 Mbps poor-network ceiling so a weak uplink stays responsive.
- Monitor-switch hardening (S10): no more false "Disconnected" alert when switching the host display, and the surface repaints after the switch instead of going black.
- Crash/leak hardening (S07): network response/JSON paths no longer crash on flaky connections or malformed replies; VC-patch storage made weak to stop a per-reconnect leak of the stream view; version-string force-unwrap fixed.
- Build fix: `EAGLContext.setCurrentContext` → `setCurrent` for Xcode 26.2.
Built from `fix/trackpad-input` @ `437ce38`. Device tests (M4 iPad) and the constrained-link UAT for S08 are still pending.
Nightly Release @ 20260527
This is a nightly release created automatically with GitHub Actions workflow.
v7 — crash reporter w/ Settings button (5f07b87)
Build @ 5f07b87. CFBundleVersion 1.2.7. CI green.
👉 Качай
- Scarlet/eSign (обновить): OpenParsec-v7-unsigned.ipa
- Scarlet/eSign (рядом): OpenParsec-v7-trackpadfix-unsigned.ipa
- AltStore/SideStore: OpenParsec-v7-trackpadfix.ipa
Новое в v7
Кнопка крэш-лога в Settings → Misc → "Last Crash Log → Copy" — забрать стек последнего краша в любой момент, не только на старте. Лог больше не удаляется при чтении (доступен пока не перезапишется новым крэшем).
3 способа достать краш:
- Авто-копирование в буфер при старте после краша (→ Mac через Universal Clipboard)
- Settings → Misc → Last Crash Log → Copy
- Files → На моём iPad → OpenParsec → last_crash.log
Всё из v6
Фикс GCMouse off-main крэша (вероятная причина твоих вылетов при мышке), CADisplayLink deinit, + весь стек v5 (resolution menu crash, scroll inertia, display persistence, language sync, natural scroll, local cursor, mouse acceleration, Ctrl+Shift, Windows remap).
Инженерный отчёт всех изменений
https://github.com/2extndd/OpenParsec/blob/fix/trackpad-input/HANDOFF.md
v6 — crash fixes + crash reporter (fc6776c)
Build @ fc6776c. CFBundleVersion 1.2.6.
👉 Качай
- Scarlet/eSign (обновить): OpenParsec-v6-unsigned.ipa
- Scarlet/eSign (рядом): OpenParsec-v6-trackpadfix-unsigned.ipa
- AltStore/SideStore: OpenParsec-v6-trackpadfix.ipa
Главное в v6 — фикс крэшей
- Crash при подключённой мышке — я в прошлой версии (v5/e924473) трогал UIView (локальный курсор) из GCMouse-колбэка, который выполняется на фоновом потоке → UIKit крэшит. Теперь обновление курсора уходит на main thread. Это, вероятно, и был твой "вылетает при скролле/в общем".
- Crash-репортер встроен. Если приложение всё-таки крэшнется:
- На следующем запуске лог автоматически копируется в буфер обмена (если iPad и Mac на одном Apple ID — через Universal Clipboard лог сразу появится в буфере Mac, можешь вставить мне)
- Файл
last_crash.logлежит в Files → На моём iPad → OpenParsec - Пришли мне его содержимое → починю по стеку
- CADisplayLink инвалидируется в deinit (backstop против висящего таймера).
Всё из v5 тоже здесь
Resolution-menu crash (iOS 14.0-14.4), scroll inertia (threshold/decay), display persistence, display-switch debounce, language sync gates, natural scroll, local cursor, mouse acceleration, Ctrl+Shift hotkey, Windows remap.
Инженерный отчёт
Полный handoff-документ всех изменений: https://github.com/2extndd/OpenParsec/blob/fix/trackpad-input/HANDOFF.md
CI: green at fc6776c.
v4 — real bugfixes from user testing (af5261b)
Build @ af5261b. CFBundleVersion bumped to 1.2.4 для cache-bust.
👉 Качай
| Sideloader | Файл |
|---|---|
| Scarlet / eSign (обновить текущий) | OpenParsec-v4-unsigned.ipa |
| Scarlet / eSign (поставить рядом) | OpenParsec-v4-trackpadfix-unsigned.ipa |
| AltStore / SideStore | OpenParsec-v4-trackpadfix.ipa |
Что починил по жалобам на v3
Скролл
- Natural Scrolling переключатель был backwards. ON теперь = natural feel (без client-side инверсии, Mac сам делает natural в своей default config).
- Sub-pixel ticks больше не теряются —
Int32truncation →.toNearestOrAwayFromZerorounding в scroll accumulator (та же фикса что делал в mouse path, забыл применить к scroll). - Inertia реально работает теперь. Было две проблемы:
minSeedSpeed = 80 pts/s— отвергал почти все натуральные скроллы. Снижен до 20.- 200ms peak-velocity reset срабатывал во время iPadOS deceleration tail и затирал peak до того как
.endedfire'нул. Поднят до 1.0s.
Локальный курсор
- Был SF Symbol cursorarrow (Mac-стрелка) → программно нарисованный iPadOS-style dot (UIView, 13pt круг, светло-серый с тонкой обводкой и тенью).
- Не двигался из-за seed бага:
contentView.bounds.midX/YвviewDidLoad= 0. Теперь seed вviewDidLayoutSubviewsчерезhasSeededLocalCursorflag — после реального layout. - Sub-pixel плавность движения: теперь
moveLocalCursorобновляется на каждом ивенте при полной CGFloat точности, даже когда rounded host-delta = 0.
Language sync
- Не срабатывал — мои защитные gates (
hasSeenInitialLanguage+ 150ms debounce) проглатывали legitimate уведомления. Loosened: любое изменение языка fires hotkey, debounce только 50ms против OS-level double-fire.
Смена разрешения
- "Disconnected 20" — 100ms reconnect gap не хватало SDK. Бамп до 600ms.
Сохранение дисплея
- Не работало — Parsec может перегенерировать display id'ы между сессиями. Теперь сохраняется И
id, И"name + adapterName"строка. На restore сначала пробуем id, потом name match.
Что я не починил (объясняю честно)
-
Resolution 1920x1080 в Settings не применяется на хосте
На macOS Parsec захватывает физический дисплей и игнорирует запрошенное разрешение вparsecClientCfg.video.0.resolutionX/Y. Это поведение хоста, не клиента.Что реально снижает bandwidth:
- Bitrate в in-stream overlay (работает 100% — host реально кодирует с меньшим bitrate)
- H.265 decoder в Settings → Graphics
- Поставить BetterDummy на Mac (free) — создаёт виртуальный дисплей в нужном разрешении, выбираешь его через "Switch Display" → реально получаешь 1920x1080
-
Скрыть курсор на самом физическом Mac
Parsec SDK не имеет client→host cursor сообщения. macOS рисует курсор до Parsec capture.
Source
CI: https://github.com/2extndd/OpenParsec/actions/runs/26461049686
v3 — Windows host remap, 4 audit bugfixes (0bc675d)
Build @ 0bc675d на ветке fix/trackpad-input.
🟢 Качай — как раньше
| Sideloader | Файл | Bundle ID |
|---|---|---|
| Scarlet / eSign (обновить текущий) | OpenParsec-unsigned.ipa | com.aigch.OpenParsec |
| Scarlet / eSign (поставить рядом) | OpenParsec-trackpadfix-unsigned.ipa | com.2extndd.openparsec.trackpadfix |
| AltStore / SideStore | OpenParsec-trackpadfix.ipa | com.2extndd.openparsec.trackpadfix |
Что нового по сравнению с v2 (trackpad-fix.2)
Твой реквест — Windows host key remap
- Settings → Keyboard → "Windows Host Remap" (default off)
- Когда вкл: на уровне scan-кодов в bridge свопится
- Cmd ↔ Ctrl
- правые модификаторы аналогично
- Opt остаётся Alt (один и тот же физический ключ)
- Shift / printable keys — не трогаются
- Работает для всех путей ввода (hardware Magic Keyboard, виртуальная клава, captured Cmd+letter)
4 бага исправлены (из аудита v2)
- H1 — смена разрешения теперь корректно ловит ошибку connect() и показывает "Reconnect failed" alert вместо frozen frame
- H2 — спам-тап двух разрешений в 600ms окне больше не ломает SDK state machine (guard на повторный вход)
- H3 — async keyup в
sendVirtualKeyboardInputтеперь re-check'ает connection status — не сольёт сообщение в disconnected SDK - M3 — локальный курсор стартует в центре экрана а не в (1,1) — больше не прыгает с левого верхнего угла при первом движении
Про скрытие курсора на самом Mac
Заглянул в SDK — технически невозможно через клиент. Parsec API не имеет ни одного клиент→хост сообщения про курсор, и сам курсор рисуется macOS до того как Parsec захватывает экран. Решение — на стороне Mac: поставить Hammerspoon, забиндить хоткей на CGDisplayHideCursor, и дёргать его из iPad через обычный keyboard message. Деталь объяснил в чате с пользователем.
Курсор в стриме на iPad — уже скрыт когда Local Cursor Overlay вкл (с v2 / 4ad1d42), это работает.
CI
Run: https://github.com/2extndd/OpenParsec/actions/runs/26452367768
Trackpad fix v2 — UX polish, latency reductions, local cursor (4ad1d42)
Build of branch fix/trackpad-input @ 4ad1d42 — все P0/P1/P2/P3 правки из глубокого аудита + локальный курсор оверлей.
🟢 Качай по тому же принципу как в trackpad-fix.1
Если ты на Scarlet / eSign
⬇️ OpenParsec-unsigned.ipa — оригинальный bundle id com.aigch.OpenParsec, без подписи. Scarlet/eSign re-sign'ят сами.
⬇️ Или OpenParsec-trackpadfix-unsigned.ipa — уникальный bundle id com.2extndd.openparsec.trackpadfix, тоже без подписи. Ставится рядом с оригинальным nightly OpenParsec как отдельное приложение.
Если ты на AltStore / SideStore
⬇️ OpenParsec-trackpadfix.ipa — уникальный bundle id + macOS ad-hoc подпись.
Что нового по сравнению с trackpad-fix.1
Критичные багфиксы (мог бы сломать твой стрим)
- Audio + cursor не отваливаются после смены разрешения — был race condition с
backgroundTaskRunningпосле reconnect - Гейтинг всех send'ов на статус — во время 100ms gap при смене разрешения теперь ничего не уходит в disconnected SDK
keyCommandsреально кэшируется — раньше пересоздавалось 286 объектов на каждое нажатие → jank в наборе текста
UX смены разрешения
- Overlay "Switching resolution…" во время gap
- Никакого чёрного экрана — последний кадр замораживается через
glkViewController.isPaused - Никакого ложного "Disconnected" alert —
ParsecStatusBar.poll()теперь молчит во время gap - Gap сокращён 300ms → 100ms
Сетевая задержка
Frame Ratedefault = "Auto (Device Max)" — на iPad с ProMotion (120 Hz) срезает render latency вдвое- "Low Latency Mode" umbrella toggle в
Settings → Graphics— одной галочкой включает max FPS + H.265 + no overlay + убирает 80ms holds на Cmd-shortcut'ах - Mouse accumulator теперь round-half-away-from-zero — slow drags больше не лагают на стикинесс
- QoS .userInteractive для poll threads
- PiP captureFrame только когда PiP реально активен (раньше жрал GPU readback каждый frame)
Локальный курсор (твой реквест)
- Settings → Interactivity → "Local Cursor Overlay" — рисуем белый SF Symbol cursorarrow на iPad локально, поверх стрима. Host cursor скрывается. Position трекается из input deltas — никакого RTT.
- В direct режиме 1:1 совпадает с хостом.
- В touchpad (delta) режиме — pure client-side prediction. Caveat: если кликнешь до того как хост догонит, клик прилетит в хостовую позицию, не на локальную метку. Для медленного клика — норм; для быстрых Cmd-shortcuts в стрелочных играх — лучше выключить.
Языковая синхронизация
- Не шлёт спурьюсный Ctrl+Space на старте сессии (раньше шёл на каждое подключение)
- Debounce 150ms — rapid Caps Lock toggles больше не interleave модификаторы
- Hotkey labels на macOS-стиле (⌃ ⌘ ⌥ с пометками)
Display persistence
- Выбранный дисплей запоминается и восстанавливается на следующем коннекте
- Restore только 1 раз/сессию — host hot-plug / sleep-wake больше не фликает re-encode
Полировка
- Inertia скролла: peak velocity сбрасывается после паузы >200ms между жестами
- Scroll skip при зуме > 1.0 (не дублирует pan локально и на хост)
- accumulator reset в touchesEnded — drift gone
Полный коммит history
| SHA | Что |
|---|---|
| 8277e0d | Trackpad cursor lag + 2-finger scroll fixes (бaseline из v1) |
| c6f9eb2 | Language sync hidden field + hotkey send (baseline из v1) |
| 96ae81e | Scroll polish + UIKeyCommand registry (baseline из v1) |
| 5d2bf2d | Keyboard regress fix + peak velocity + Mac labels |
| 5464629 | Display persistence + resolution reconnect |
| de86645 | Аудит P0/P1/P2/P3 — backgroundTaskRunning fix, gates, cache, low-latency mode |
| 4ad1d42 | Local cursor overlay + init fix |
Source
PR upstream: hugeBlack#70
CI: https://github.com/2extndd/OpenParsec/actions/runs/26451220276
Trackpad fixes + keyboard layout sync (build 96ae81e)
Build of branch fix/trackpad-input @ 96ae81e — все три коммита, последняя ревизия.
🟢 Если ты на Scarlet / eSign
⬇️ OpenParsec-unsigned.ipa — оригинальный bundle id com.aigch.OpenParsec, полностью без подписи (signature stripped). Scarlet / eSign re-sign'ят своим enterprise certom — им нужен чистый исходник без чужой подписи на binary. Поставится поверх существующего nightly OpenParsec как обновление.
Если хочешь рядом со старым (как отдельное приложение) — качай OpenParsec-trackpadfix-unsigned.ipa: unique bundle id com.2extndd.openparsec.trackpadfix, тоже без подписи.
🟢 Если ты на AltStore / SideStore
⬇️ OpenParsec-trackpadfix.ipa — unique bundle id, macOS codesign --sign - ad-hoc подпись. AltStore любит правильно структурированную подпись на входе.
🟡 Если "не уверен"
Попробуй сначала OpenParsec-trackpadfix-unsigned.ipa — без подписи, уникальный id. Работает в большинстве sideloader'ов, не конфликтует с уже установленным OpenParsec.
| Файл | Bundle ID | Signature | Для кого |
|---|---|---|---|
| OpenParsec-unsigned.ipa | com.aigch.OpenParsec | Нет | Scarlet/eSign, обновляет существующий |
| OpenParsec-trackpadfix-unsigned.ipa | com.2extndd.openparsec.trackpadfix | Нет | Scarlet/eSign/универсал, ставится рядом |
| OpenParsec-trackpadfix.ipa | com.2extndd.openparsec.trackpadfix | macOS ad-hoc | AltStore/SideStore |
| OpenParsec.ipa | com.aigch.OpenParsec | Linux ldid | Оригинальный CI билд |
Что внутри
- Cursor lag / sticky trackpad на Magic Keyboard (issue hugeBlack#47) — исправлено
- Choppy 2-finger scroll — исправлено + настраиваемая инерция
- Natural Scrolling toggle, Scroll Sensitivity slider, Inertia Strength slider
- Mac ↔ iPad keyboard layout sync (по умолчанию Ctrl+Space)
- Best-effort capture системных Cmd+letter через UIKeyCommand registry
Что не работает (ограничения iPadOS)
Cmd+Space, Cmd+H, Cmd+Tab, Globe key, swipe-up — захватываются SpringBoard ниже responder chain, никакое приложение не может перехватить через публичные API.
Source
PR upstream: hugeBlack#70
CI: https://github.com/2extndd/OpenParsec/actions/runs/26423432019