Skip to content

feat(desktop): move to new native vnc render pipeline#18

Merged
0xHexE merged 9 commits into
mainfrom
feat/new-vnc
Mar 27, 2026
Merged

feat(desktop): move to new native vnc render pipeline#18
0xHexE merged 9 commits into
mainfrom
feat/new-vnc

Conversation

@0xHexE

@0xHexE 0xHexE commented Mar 26, 2026

Copy link
Copy Markdown
Member

No description provided.

0xHexE added 9 commits March 27, 2026 05:25
- Add @pi-ui/client/vnc package with full RFB protocol implementation:
  - protocol.ts: type definitions (PixelFormat, Rect, Event, Adapter)
  - rfb-protocol.ts: RFB state machine + all encoding decoders
    (Raw, CopyRect, RRE, Hextile, ZRLE, DesktopSize)
  - vnc-auth.ts: pure-JS DES cipher for VNC password auth
  - vnc-input.ts: pointer/keyboard event encoders + keysym table
  - vnc-transport.ts: WebSocket boundary with message classification
  - wasm-pipeline.ts: WASM decoder loader (web-only, JS fallback on native)

- Add WASM pipeline infrastructure:
  - AssemblyScript source for framebuffer-owning decoder
  - Pre-built WASM binary at public/wasm/
  - Build script for recompilation

- Add useVncSession hook:
  - Orchestrates WebSocket transport + RFB protocol
  - Auto-loads WASM on web, JS fallback on native
  - Encoding fallback (timeout -> Raw-only reconnect)
  - Exposes sendPointerEvent/sendKeyEvent/sendWheelEvent

- Rewrite web viewer (vnc-viewer.web.tsx):
  - HTML canvas with WASM pipeline (single putImageData per frame)
  - JS fallback with per-rect putImageData
  - ResizeObserver aspect-ratio scaling
  - Full pointer/keyboard/wheel input handling

- Rewrite native viewer (vnc-viewer.native.tsx):
  - Skia Canvas + Skia.Image.MakeImage from RGBA pixels
  - JS-side framebuffer with rect blitting
  - Trackpad-style drag-to-move with visible cursor overlay
  - Tap=click, long-press=right-click, two-finger=scroll
  - Hidden TextInput keyboard bridge

- Dependencies: @shopify/react-native-skia, fflate, @assemblyscript/loader
Replace useRef with useSharedValue for all values accessed inside
gesture callbacks (pan, tap, long-press, two-finger scroll).
Use runOnJS to bridge worklet -> JS thread for setState and
session.sendPointerEvent/sendWheelEvent calls.

Fixes Reanimated crash: 'Tried to modify key current of an object
which has been already passed to a worklet'
- Back press while keyboard is open → dismiss keyboard
- Back press while fullscreen/immersive → exit fullscreen
- Otherwise → default back navigation
- Slide-out panel on left edge with Keyboard, Fullscreen, Reconnect
- Small arrow tab toggle (▶/◀) at left center
- Animated slide in/out with spring animation
- Back button closes menu before exiting fullscreen
- Shows resolution info at bottom of panel
- Same pattern as the original noVNC slide-out menu
- Remove KeyboardAvoidingView wrapping (was resizing canvas container
  on keyboard open causing layout recalc + image scale jump)
- Remove declarative StatusBar (was causing layout shift on toggle)
- Use imperative StatusBar.setHidden with 'fade' animation instead
- Canvas container now stays full size regardless of keyboard state
Use KeyboardAvoidingView with behavior='position' on iOS (translates
content up without resizing container) and no behavior on Android
(system handles it). This shifts the canvas up when keyboard opens
so VNC content remains visible, without triggering layout recalc.
Switch KeyboardAvoidingView back to padding/height behavior so the
canvas area shrinks when keyboard opens. Debounce onLayout (150ms)
to prevent rapid setCanvasSize calls during keyboard animation,
eliminating the flicker while still updating the scale after the
keyboard settles.
@0xHexE 0xHexE changed the title Feat/new vnc feat(desktop): move to new native vnc render pipeline Mar 27, 2026
@0xHexE
0xHexE merged commit 5f4cc68 into main Mar 27, 2026
1 check passed
@mrlubos

mrlubos commented Apr 5, 2026

Copy link
Copy Markdown

@0xHexE how long have you been using @hey-api and do you find it useful so far?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants