Skip to content

release: 0.1.37 — VNC client + OSC 52 clipboard - #77

Merged
thangnm93 merged 50 commits into
masterfrom
develop
Jun 18, 2026
Merged

release: 0.1.37 — VNC client + OSC 52 clipboard#77
thangnm93 merged 50 commits into
masterfrom
develop

Conversation

@thangnm93

@thangnm93 thangnm93 commented Jun 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

Release 0.1.37. Ships the in-app VNC client (Linux VNC servers, milestones M1–M5) and OSC 52 clipboard. Merging to master triggers the release workflow (multi-platform build + GitHub Release + v0.1.37 tag).

Changes

  • In-app VNC client — Linux VNC servers (TigerVNC / x11vnc / TightVNC) as first-class tabs alongside SSH and RDP. New packages/yourssh_vnc Rust crate over vnc-rs (flutter_rust_bridge v2): RFB handshake + None/VNC-password (DES) auth, framebuffer render with latest-wins decode, mouse + keyboard (X11 keysym map + pointer transform), bidirectional clipboard (ServerCutText/ClientCutText), server-driven auto-resize, SSH tunneling via the shared loopback proxy, fullscreen with auto-hide hover pill, HostProtocol.vnc (port 5900) with a VNC mode in the host panel, ProtocolBadge (RDP + VNC), protocol-aware dashboard actions + vnc:// copy-url, tab parity (rename/color/pin/restore/audit/notification).
  • OSC 52 clipboard — remote apps (tmux, vim, …) write to the local system clipboard via the OSC 52 escape sequence; write-only, per-host opt-in (Host.osc52Clipboard).
  • RefactorRdpTunnelProxy generalized to protocol-neutral LoopbackTunnelProxy, shared by RDP and VNC SSH-tunneled connections.

Type of change

  • feat — new feature
  • fix — bug fix
  • refactor / polish — no behavior change
  • docs — documentation only
  • test — tests only
  • release — version release to master

How was this tested?

  • cd app && flutter analyze — no new warnings (2 remaining lints are pre-existing untracked probe files)
  • cd app && flutter test — all tests pass (1387)
  • Manually verified on: macOS — integration_test/vnc_screenshots_test.dart drives the real app against a local VNC container

Screenshots

n/a — release PR; VNC UI is covered by the screenshots integration test.

Checklist

  • PR title follows Conventional Commits
  • Code and comments are written in English
  • New/changed behavior is covered by tests
  • No secrets, credentials, or personal data in the diff

Required when targeting master (release PRs)

  • CHANGELOG.md updated — [0.1.37] versioned section added, comparison link updated (this repo's CHANGELOG uses versioned sections directly, no [Unreleased] block)
  • Version bumped in app/pubspec.yaml (0.1.36+10.1.37+1)
  • README.md / CLAUDE.md updated if architecture or features changed — not done: CLAUDE.md does not yet describe packages/yourssh_vnc; worth a follow-up
  • docs/roadmap.md updated (VNC + OSC 52 moved to Shipped, version → 0.1.37)
  • Wiki release notes prepared (docs/wiki/User-Guide-VNC.md + Home.md row)

thangnm93 added 30 commits June 16, 2026 16:21
- Clone sender before releasing SESSIONS lock in `send` to prevent
  future re-entrant deadlock if drop handlers acquire the registry
- Replace unwrap() with expect() on all three lock sites for
  meaningful crash messages on lock poisoning
- Add #[derive(Debug)] to SessionCmd
- Use #[tokio::test] / async fn on the registry test for correctness
  and future-proofing
… arms

- Add `biased;` to the select! loop with cmd_rx first so Disconnect
  commands are never starved by a high-frequency server frame stream
- Replace the generic Ok(_) catch-all with explicit arms for
  SetPixelFormat / Copy / JpegImage / SetCursor (encodings not
  negotiated) with explanatory comments; retain a final Ok(_) wildcard
  for future #[non_exhaustive] variants
- Add comments on let _ = vnc.close().await and let _ = vnc.input()
  explaining why silently discarding those results is correct
…sconnect

- _finish: cancel _sub before closing _eventCtrl so no trailing events
  reach a closed controller; close _eventCtrl so stream subscribers see done
- onError: same teardown (cancel _sub, close _eventCtrl) before completing
  _done/_connectedCompleter — prevents orphaned sub and open controller on
  Rust bridge errors
- disconnect(): guard the id==null early-return against the post-finish path
  (where _done is already complete) so callers that call disconnect() on an
  already-closed session don't accidentally set _disconnectRequested=true
- dispose(): guard _eventCtrl.close() against double-close since _finish/
  onError may have already closed it
_finish/onError closed _eventCtrl, making VncClient single-use and risking
add()-on-closed-controller for any event delivered after teardown. RDP only
closes in dispose(); mirror that so the controller's lifetime is owned solely
by dispose().
… sender-drop

- disconnect_reason: drop the dead IoError arm. In vnc-rs 0.5.3 recv_event only
  fails with ClientNotRunning; mid-stream IO/decode errors arrive as
  Ok(VncEvent::Error). Doc comment corrected to match.
- refresh interval: MissedTickBehavior::Skip so a frame-decode burst doesn't
  replay a backlog of incremental-update requests on resume.
- cmd loop: distinguish a dropped sender ("session closed") from an explicit
  Disconnect ("disconnected by user") instead of labelling both as user intent.
vnc-rs has no unix-only deps, so the crate builds on Windows like yourssh_rdp;
add build.ps1 producing yourssh_vnc.dll. Run the VNC Rust unit tests, build the
native lib, and run the Dart FRB roundtrip test in pr-test alongside RDP.
yourssh_rdp commits its Cargo.lock; do the same for yourssh_vnc so the binary
crate's dependency graph is pinned across clones and CI.
Add a third SegmentedButton segment for VNC, introduce _isGraphical
(protocol != ssh) to gate SSH-only sections, and keep _isRdp for the
RDP-only domain/security fields so VNC shows neither.
CONNECT ALL counted live SSH and RDP sessions when building the
already-connected set but missed VNC, so an open VNC host got a
duplicate tab on every press. Mirror the RDP dedup branch for
VncSession.
thangnm93 added 20 commits June 17, 2026 21:24
…then input test

Code review of the M3 input work surfaced three issues:
- VncWorkspace forwarded every hover/move to the unbounded session command
  channel; a fast mouse could flood it and starve frame decode behind the
  biased run-loop. Dedup identical (x,y,mask) events like the RDP path.
- The M2->M3 connected-branch rewrite dropped the "Waiting for first frame"
  affordance. Restore it as an overlay over the now-interactive surface.
- The input widget test asserted find.byType(Listener) which matched
  MaterialApp/Scaffold ancestor Listeners (false confidence). Scope it to a
  Listener owned by VncWorkspace, plus the connecting->connected swap and the
  waiting cue.
The M3 FFI codegen regenerated rust/src/frb_generated.rs (the wire glue
dispatching vnc_send_pointer/vnc_send_key) but only the Dart bindings + api.rs
were committed. Tests passed against the working tree, so a fresh checkout/CI
build would have lacked the glue. Commit it.
…s, fullscreen parity

Code review of M4/M5 surfaced:
- _restorableHostId dropped VncSession (returned null) → VNC tabs silently
  vanished from the workspace snapshot on relaunch. Add the VncSession arm.
- VncWorkspace rebuilt its whole tree on every decoded frame (no status
  guard); mirror RDP's _builtStatus guard so the tree only rebuilds on a
  status change or the first-frame transition (frames repaint via the
  painter's repaint: listenable). Also exit fullscreen synchronously in the
  session listener (like RDP) instead of deferring to didUpdateWidget.
- The fullscreen exit pill gains a 'push clipboard' button (RDP parity).
- Host-panel bottom spacer broadened from _isRdp to _isGraphical.
- Clipboard cut-text test now asserts no repaint fired.
@thangnm93 thangnm93 changed the title Release 0.1.37 — VNC client + OSC 52 clipboard release: 0.1.37 — VNC client + OSC 52 clipboard Jun 18, 2026
@thangnm93
thangnm93 merged commit 2de5e7d into master Jun 18, 2026
1 check passed
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.

[Feature] Thêm tính năng VNC, export và import danh sách thiết bị

1 participant