Both docs still described VNC as unimplemented and required usernames
up front for SSH/RDP -- neither has been true for a while. Brings them
in line with the actual current feature set: VNC's encodings/clipboard/
cursor sync/display modes and honest Apple Screen Sharing auth status,
blank-username connect-time prompting across all three protocols,
profile Import/Export and mRemoteNG import, and the new prompt
visibility behavior (issue #22). docs/USER_GUIDE.md also drives the
in-app Help -> User Guide dialog and the PDF shipped with releases.
Bump version to v2026.9.16.7.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Implements RFB (RFC 6143) directly against QTcpSocket. No permissively
licensed VNC client library exists to vendor the way FreeRDP was for RDP:
LibVNCClient is GPLv2, gtk-vnc is LGPL but GTK-tied, and vendoring either
would force a licensing decision on the whole (MIT) project. This is
from-scratch protocol code instead, threaded like SshSessionBackend (a
QObject on its own QThread driven by Qt's own async socket signals)
rather than RdpSessionBackend's manual worker-thread/blocking-loop
pattern, since QTcpSocket is already async.
Scope, matching SessionTab's existing SSH/RDP dispatch pattern
(session_backend_factory.cpp, session_tab.cpp's widget construction and
signal wiring) and VncDisplayWidget mirroring RdpDisplayWidget's
scale-to-fit rendering:
- Protocol handshake: RFB 3.3/3.7/3.8 negotiated explicitly (the
SecurityResult message only exists in 3.8; pre-3.8 servers signal auth
failure by closing the socket, which the disconnect handler accounts
for)
- VNC Authentication (DES challenge-response, via OpenSSL's classic DES
API) and no-auth security types
- Raw + CopyRect framebuffer decoding into a persistent QImage, requesting
a fixed 32bpp format whose byte layout matches QImage::Format_RGB32
directly (same zero-conversion trick RdpSessionBackend uses for
FreeRDP's GDI buffer)
- Keyboard (Qt key -> X11 keysym, including the Unicode-beyond-Latin-1
keysym convention) and mouse/wheel input forwarding
Explicit non-goals for this pass (see docs/PROGRESS.md for the full
list): Apple's Screen Sharing auth (so this can't yet reach macOS's
built-in VNC server), compression encodings beyond Raw/CopyRect, dynamic
resize, remote cursor shape sync, clipboard sync.
19 unit tests (tests/test_vnc_session_backend.cpp): pure-function
coverage (DES key prep verified against an independently documented test
vector for password "COW", X11 keysym mapping, socket-error mapping) plus
state-machine coverage against a scripted in-process fake RFB server
covering all three protocol-version handshake shapes, auth success/
failure, unsupported security types, and pixel-accurate Raw decoding.
That harness caught a real re-entrancy bug: QAbstractSocket::abort()
synchronously re-emits disconnected() before returning, so
failConnection() calling it was silently letting a second, generic
disconnected-socket handler overwrite an already-correct, specific error
message.
Also verified live against a real, independently implemented VNC server
(TightVNC on Windows): connect with VNC Authentication, correct
framebuffer dimensions and pixel data, clean disconnect, reconnect.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds docs/USER_GUIDE.md, a 10-section end-user guide (getting
started, managing/organizing profiles, SSH and RDP connections,
session management, settings, troubleshooting). It's embedded into
the app binary via a Qt resource file and rendered by a new
Help -> User Guide window: a topic sidebar plus content pane, not a
single scrolling document, with cross-reference links between
sections routed to sidebar selection rather than relying on Qt's
Markdown importer's lack of heading anchors.
A separate, non-shipped tool (tools/user-guide-pdf/) renders the
same source to a standalone PDF via QTextDocument + QPrinter,
wrapped by packaging/docs/build-user-guide-pdf.sh. Kept fully
outside the main CMake target so Qt6::PrintSupport never becomes a
runtime dependency of the shipped app (confirmed via ldd). The PDF
itself isn't committed -- generated per release like the platform
installers.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds a production manifest (packaging/flatpak/flathub/) using a
pinned git source instead of the local-dir source the dev manifest
uses, so Flathub's build infrastructure can reproduce the build
independently.
Narrows the dev and production manifests' filesystem permission from
--filesystem=home to --filesystem=~/.ssh (read-write, needed for SSH
known_hosts/config) after confirming in the actual sandbox that: SSH
already works there (provided by the KDE runtime base, no extra
packaging needed), RDP needs no filesystem access at all (its
certificate trust never touched disk even before today's fix), and
QFileDialog's private-key/export pickers route through the desktop
portal rather than needing static filesystem access.
Expands AppStream metainfo with bugtracker/vcs-browser URLs, a
developer block, a releases entry, an OARS content rating, and three
screenshots (profiles view, an active SSH session, an active RDP
session) using real test-system profiles.
Adds docs/FLATHUB.md tracking overall submission readiness.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Linux, macOS, and Windows have all been validated against the current
feature set (SSH, RDP display/keyboard/clipboard/cursor, Tab forwarding,
key repeat, profile dialog, single-window UI), with the platform-specific
bugs found along the way fixed and tracked individually on the issue
tracker (#8-#16). VNC validation remains out of scope while Milestone 6
stays deferred.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>