Skip to content

v0.24.3

Choose a tag to compare

@github-actions github-actions released this 01 Nov 09:50
· 8 commits to main since this release

What's Changed

💜 The embedded Remote Desktop Connection features in this release — the
graphics pipeline and AVC444, the microphone, automatic reconnection,
connection broker support, Happy Eyeballs dialling and the wider .rdp
import/export — come from @pony-svg's
contribution in #402.
Thank you!

Added

  • Remote working directory on the tab tooltip — a terminal tab's tooltip now shows the session's current remote directory as its last line, updated live as you cd around. It reads VTE's OSC 7 current-directory report (emitted by the same vte.sh that drives shell integration), so it fills in on a host that sends OSC 7 and stays absent otherwise. The file://host/path URI is parsed directly for its path, so the directory shows for a genuinely remote host rather than only a local one. The line is maintained independently of the host, group and broadcast tooltip lines, so assigning a group, toggling broadcast or renaming the tab all leave it in place. (rustconn/src/terminal/tab_lifecycle.rs, rustconn/src/terminal/mod.rs)
  • OSC 133 shell integration — prompt navigation and a failed-command marker — when the remote shell emits the OSC 133 semantic-prompt sequences, RustConn now tracks where each prompt is and makes two things possible. Previous/Next Prompt (Ctrl+Shift+[ and Ctrl+Shift+], remappable in Settings → Keybindings) scroll the terminal to the prompt above or below the current view, so you can move between commands without hand-scrolling. A failed-command marker — a short red bar in the left margin — marks the prompt of any command that exited non-zero, so failures stand out while scrolling. Both build on the vte.shell.postexec termprop already read for the Command-finished monitoring mode: the prompt row is captured at command-end (vte4 0.10 binds only postexec) and the exit code attached to it. Like that mode, it needs RustConn built with VTE 0.78 or newer and shell integration sourced on the remote side (most modern distributions ship vte.sh for bash/zsh/fish); where either is missing the keys are no-ops and no markers appear, with no other change. On a build below VTE 0.78 the whole path compiles to a no-op. The prompt index is per session, lives only in memory, and is dropped with the tab; marks that scroll out of the buffer are discarded so a stale row is never a jump target. (rustconn/src/terminal/mark_registry.rs, rustconn/src/terminal/failed_marker.rs, rustconn/src/terminal/termprops.rs, rustconn/src/terminal/highlight_overlay.rs, rustconn/src/terminal/mod.rs, rustconn/src/terminal/tab_lifecycle.rs, rustconn/src/window/terminal_actions.rs, rustconn-core/src/config/keybindings.rs, rustconn/src/dialogs/shortcuts.rs, docs/USER_GUIDE.md, README.md, po/*.po)
  • Auto-capture keyboard shortcuts for remote desktop (Windows App parity) — automatically inhibits system shortcuts (such as Alt+Tab and Super key) and disables tab view shortcuts when an embedded RDP/VNC viewer gains focus, forwarding all hotkeys directly to the remote session like Windows App. Controlled by a new toggle in Preferences → Interface → Appearance. (rustconn-core/src/config/settings.rs, rustconn/src/terminal/mod.rs, rustconn/src/dialogs/settings/ui_tab.rs)
  • Responsive embedded RDP dynamic resizing and crisp rendering — lowered resize hysteresis and thresholds for responsive dynamic resolution adaptation without jitter, and enforced pixel-direct filtering for sharp text display. (rustconn/src/embedded_rdp/drawing.rs, rustconn/src/embedded_rdp/resize.rs)
  • RDP microphone, smart card and connection broker settings (Windows Remote Desktop parity) — the RDP connection editor gains Microphone and Smart Cards switches (Features) and a Load Balance Info field (Connection), the counterparts of Remote Desktop Connection's audio recording, smart card and RD Connection Broker settings. They reach FreeRDP as /microphone, /smartcard and /load-balance-info:, from the GUI launch and from rustconn-cli connect alike (freerdp::freerdp_device_and_broker_args). The embedded IronRDP client gained the microphone and broker redirection in this release (see the entries below), so only smart cards remain external-client-only. Smart cards stay external-client-only, like FIDO2, and do not force FreeRDP: Remote Desktop Connection writes redirectsmartcards:i:1 into every .rdp file it saves, so every imported Windows profile would otherwise have left the embedded viewer. Smart cards need a FreeRDP built with PC/SC; the Flatpak's bundled FreeRDP is not (-DWITH_PCSC=OFF). (rustconn-core/src/models/protocol.rs, rustconn-core/src/protocol/freerdp.rs, rustconn/src/dialogs/connection/rdp.rs, rustconn/src/embedded_rdp/connection.rs)
  • Embedded RDP sessions reconnect by themselves after a network drop (Windows Remote Desktop parity) — when the connection of an established embedded session breaks (a read or write on the transport fails), the session now reconnects automatically, as Remote Desktop Connection does: up to 20 attempts (rdp_client::AUTO_RECONNECT_MAX_ATTEMPTS), waiting 1, 2, 4 and 8 seconds and then 10 seconds between them (rdp_client::auto_reconnect_delay), with the banner counting the attempts. The client reports such a drop as the new structured RdpClientEvent::ConnectionLost instead of a generic error string, so a session the server ends (logoff, administrator disconnect) still just ends. An attempt that cannot reach the server waits and tries again; a refused sign-in or a server the embedded client cannot serve ends the attempts and is reported as before. Clicking Reconnect connects at once and stops the automatic attempts, and closing the tab cancels a pending one. On by default, like the Windows client; Reconnect Automatically (Features) turns it off per connection, and .rdp files carry it as autoreconnection enabled, which the exporter used to write as a fixed 1. (rustconn-core/src/rdp_client/failure.rs, rustconn-core/src/rdp_client/client/session.rs, rustconn/src/embedded_rdp/connection.rs)
  • Per-connection Windows key combinations — the RDP connection editor gains Windows Key Combinations, Remote Desktop Connection's Apply Windows key combinations: Follow the app setting (the default, which keeps the Settings → Interface auto-capture switch in charge), On this computer, On the remote computer, or Only in full screen, which also follows the window going in and out of full screen while the session has focus. .rdp import and export carry it as keyboardhook. (rustconn-core/src/models/protocol.rs, rustconn/src/terminal/mod.rs)
  • Leave Fullscreen button — in fullscreen the header that slides in at the top edge now ends with a Leave Fullscreen button, the counterpart of the Restore button on Remote Desktop Connection's connection bar. (rustconn/src/window/fullscreen_header.rs)
  • The .rdp importer reads the settings Remote Desktop Connection writes — use multimon and screen mode id now set the external window mode (all monitors, full screen, or a custom size when the file carries one), session bpp the colour depth, audiocapturemode the microphone, redirectsmartcards smart cards, redirectwebauthn FIDO2 redirection, enablecredsspsupport:i:0 turns NLA off and loadbalanceinfo the broker routing value. remoteapplicationmode:i:0 is honoured, so a desktop profile with leftover RemoteApp fields no longer imports as a RemoteApp. authentication level is deliberately not read: its 0 would let a file someone sent switch certificate checking off. The exporter writes audiocapturemode, redirectsmartcards, redirectwebauthn and loadbalanceinfo from the connection instead of fixed values. (rustconn-core/src/import/rdp_file.rs, rustconn-core/src/export/rdp_file.rs)
  • The embedded RDP client gets the graphics pipeline, AVC444 and the microphone (IronRDP October 2026 releases) — RustConn now depends on IronRDP crate by crate on the 27/28 October release train (ironrdp-connector 0.12, ironrdp-session 0.13, ironrdp-egfx 0.5, ironrdp-dvc 0.10, …) instead of the ironrdp 0.17 meta crate, which still pins the July stack. Three things follow. The connector announces the graphics pipeline in the early capability flags (support_dyn_vc_gfx_protocol, MS-RDPEGFX 1.5.1), which a Windows host needs before it opens the channel — without it such a host kept the session on bitmap updates, soft with RemoteFX and heavy without. ironrdp-egfx decodes AVC444, AVC444v2, ClearCodec, Planar and RFX Progressive and composites surfaces and caches itself, and ironrdp-session paints the result like any other update, so RustConn's own surface compositor in gfx_handler.rs — written when ironrdp-egfx decoded but did not composite (issue #262) — is gone, the AVC420-only capability override with it, and the pipeline no longer needs OpenH264 to be usable. And the microphone runs in the embedded viewer over the MS-RDPEAI AUDIO_INPUT channel (ironrdp-rdpeai): the core reports the format the server opened (RdpClientEvent::MicrophoneOpened), the GUI captures the default input device with cpal (audio::RdpMicrophone) and returns 16-bit PCM packets (RdpClientCommand::MicrophoneData), so switching the microphone on no longer moves the session into a FreeRDP window. A connection broker's Server Redirection now arrives as a structured outcome the embedded client follows to the session host (see the broker entry below). (rustconn-core/Cargo.toml, rustconn-core/src/rdp_client/, rustconn/src/audio.rs, rustconn/src/embedded_rdp/connection.rs)
  • Connection brokers, shared-folder refresh and bulk compression in the embedded RDP client — three things the October IronRDP releases made possible. A connection with Load Balance Info no longer moves into a FreeRDP window: the embedded client sends the value as the X.224 routing token and follows the broker's Server Redirection to the session host, with the session ID, routing token and password cookie the broker returns (connection::follow_redirection; the cookie is zeroized and never printed), up to two hops. The PDU parsing and the first-hop REDIRECTION_SUPPORTED advertisement are unit-tested and a normal connection is unaffected, but the full redirection has not been exercised against a live RD Connection Broker farm. Shared folders tell Windows when a file changes on this computer — the directory watcher already saw the changes, but the notify response it needed (ClientDriveNotifyChangeDirectoryResponse) only arrived in ironrdp-rdpdr 0.9, and nothing polled the watcher; the session loop now does, once a second — so Explorer refreshes by itself. And XCRUSH bulk compression is negotiated, which shrinks every PDU the server sends; it was off because a resize used to lose the decompressor's history (issue #200), which ironrdp-session 0.12 fixed. (rustconn-core/src/rdp_client/client/connection.rs, rustconn-core/src/rdp_client/client/session.rs, rustconn-core/src/rdp_client/rdpdr.rs)
  • CLI usability for headless provisioning — six improvements to rustconn-cli — found while scripting test connections. (1) add --group NAME and update --group NAME now report whether the group was created or already existing, with its resolved name and ID (Added connection '…' to group 'ops' (created, ID …)), so a typo no longer silently spawns a second group; the group ID is printed too, matching group create. (2) An explicit --format table is now honoured verbatim even when stdout is piped — the terminal-detection downgrade to JSON applies only when no --format was given, so … | grep on a table keeps working while a bare piped command still defaults to JSON (clig.dev). (3) add --password-stdin reads a password from stdin into a SecretString and stores it in the configured secret backend — the same vault the GUI uses — never in the connections file, argv, output or logs (requires the secret-management feature). (4) add --from-file PATH (or - for stdin) bulk-adds connection definitions from a YAML or JSON document (a connections/groups object or a bare array, parsed through the existing Connection/ConnectionGroup serde models), reporting how many were added and naming each skipped entry with its reason. (5) add --provider aws_ssm now validates at add time that --host is an EC2 instance ID (i- followed by hex) and rejects a plain hostname with a non-zero exit code, instead of failing deep inside the AWS CLI at connect time. (rustconn-cli/src/cli.rs, rustconn-cli/src/commands/add.rs, rustconn-cli/src/commands/secret.rs, rustconn-cli/src/commands/mod.rs, rustconn-cli/src/error.rs, docs/CLI_REFERENCE.md)

Fixed

  • Embedded RDP and VNC sessions timed out on hosts with an unreachable IPv6 address — the embedded clients connected with TcpStream::connect("host:port"), which tries the resolved addresses one after another. When a name resolves to both an AAAA and an A record and the IPv6 address never answers, as on a VPN that hands out IPv6 addresses it does not route, the first attempt used up the whole connect timeout and the session failed with Operation timed out without ever trying the IPv4 address that works. Connecting now races the addresses (RFC 8305, "Happy Eyeballs"): families alternate, each attempt gets a 250 ms head start, and a refused address hands over at once, so such a host connects over IPv4 in about a quarter of a second. The same dialler is used by the embedded RDP and VNC clients, by a broker's redirect to its session host, by Check if online, and by Test Connection. The MPTCP setting now also applies to direct embedded RDP connections in builds with RD Gateway support, which used plain TCP regardless. Connections through an RD Gateway are dialled by ironrdp-mstsgu and are unchanged. (rustconn-core/src/connection/dial.rs, rustconn-core/src/rdp_client/client/connection.rs, rustconn-core/src/vnc_client/client.rs, rustconn-core/src/host_check.rs, rustconn-core/src/testing/mod.rs)
  • Embedded RDP sessions played no sound unless a folder or printer was shared — with audio set to Play on this computer and nothing shared, the embedded client joined the sound channel (RDPSND) without the device redirection channel (RDPDR). A Windows host starts sound only once RDPDR is joined too, so the server never sent a format list or a single sample, and nothing reported a problem. FreeRDP registers RDPDR whenever sound is on for the same reason; the embedded client now does as well. (rustconn-core/src/rdp_client/client/connection.rs)
  • The Quality performance mode no longer offers the server a lossy codec — Quality asked for lossless bitmaps but also advertised the RemoteFX codec, which is lossy and which a server prefers when it is offered, so the request for lossless output was undone. That is what an embedded session shows whenever the server does not open the GFX pipeline, as some Windows hosts and policies never do, and text arrived soft and smeared. Quality now offers no codec, so the server sends lossless 32-bit bitmaps, which take noticeably more bandwidth; Balanced still offers RemoteFX for links where that matters, and Speed is unchanged. (rustconn-core/src/rdp_client/client/connection.rs)
  • Embedded RDP text was uneven on fractional-scaling displays — with Display Scale Auto the remote desktop is requested at the widget's logical size and stretched to the display, and on a 125% or 150% display that stretch used Nearest filtering, which repeats every fourth or every second row and column, so strokes came out with uneven widths. The framebuffer is now drawn with Nearest only when each remote pixel lands on a whole number of device pixels (Native, or Auto at 100% or 200%), and with bilinear filtering otherwise. For pixel-exact text on a fractional display, Display Scale Native (full HiDPI) still avoids the stretch altogether. (rustconn/src/embedded_rdp/drawing.rs)
  • .rdp files saved by Remote Desktop Connection could not be imported or opened — mstsc saves .rdp files as UTF-16LE with a byte-order mark, and the importer read them as UTF-8, so importing one, or double-clicking it, failed with an invalid-UTF-8 error. A UTF-8 file with a byte-order mark lost its first key the same way, which refused the file outright when that key was full address. The byte-order mark now decides the encoding (UTF-16LE, UTF-16BE or UTF-8), and a file without one is read as UTF-8. (rustconn-core/src/import/rdp_file.rs)
  • Touchpad smooth scroll and high-velocity mouse wheel no longer panic in RDP sessions — kinetic scrolling and high-resolution wheel events can emit large deltas that exceed RDP's 9-bit two's-complement limit [-256, 255]. Large deltas are now chunked into safe increments of at most 120 (standard Windows WHEEL_DELTA), and horizontal/touchpad scrolling is scaled smoothly, preventing connection drops from ironrdp-pdu panics. (rustconn-core/src/rdp_client/client/commands.rs, rustconn/src/embedded_rdp/input.rs)

Documentation

  • Microphone, smart card and connection broker settings documented — the user guide describes the new RDP switches and the Load Balance Info field, corrects the FIDO2 note that .rdp export did not carry it, and lists every .rdp field the importer now reads. (docs/USER_GUIDE.md)
  • Automatic reconnection, Windows key combinations and Leave Fullscreen documented — new user-guide sections under RDP, and the fullscreen notes mention the new button. (docs/USER_GUIDE.md)
  • Graphics pipeline and embedded microphone documented — a new user-guide section explains Automatic graphics mode, AVC444 and why a Windows host needs the pipeline announced, and the microphone notes no longer send the session to FreeRDP. (docs/USER_GUIDE.md)
  • Broker redirection and shared-folder refresh documented — the user guide's Load Balance Info section describes the embedded client following the broker, and the shared folders notes mention the automatic refresh. (docs/USER_GUIDE.md)
  • Translations for the new strings — the RDP microphone, smart card, broker, automatic-reconnection, Windows-key-combination and Leave Fullscreen strings, and the two remote-desktop shortcut-capture strings the POT already carried, are translated in all 17 catalogues. (po/*.po)

Groundwork

  • tmux control-mode parser and session model (core only, no UI) — the GUI-free foundation for a future tmux -CC integration: a streaming parser for the control-mode line protocol (%begin/%end/%error blocks, %output with octal un-escaping, and every %window-*/%session-*/%pane-*/flow-control notification) and an in-memory window/pane/session model that folds those events, keyed by tmux IDs. It lives in rustconn-core with no GTK/VTE dependency and is covered by golden-stream tests from the tmux wiki examples, including chunk-boundary robustness (every byte offset) and non-UTF-8 payloads. No tabs, splits, reconnect or UI yet — that is the 0.25 epic; this only de-risks the protocol layer. (rustconn-core/src/tmux_control/)

Dependencies

  • IronRDP moved to the October 2026 per-crate releases — the embedded RDP client now depends on ironrdp-connector 0.12, ironrdp-session 0.13, ironrdp-egfx 0.5, ironrdp-pdu 0.11, ironrdp-rdpdr 0.9, ironrdp-rdpeai 0.2 and the rest of the 27/28 October train, crate by crate, instead of the ironrdp 0.17 meta crate that still pinned the July stack. This is what unlocks the graphics pipeline, AVC444 and the microphone (see Added). (rustconn-core/Cargo.toml)
  • Updated (semver-compatible, transitive): js-sys 0.3.106→0.3.107, log 0.4.34→0.4.35, wasm-bindgen 0.2.129→0.2.130 (with js-sys/web-sys/futures/macro), yuv 0.8.19→0.8.20, zip 9.1.3→9.2.0. A cargo update refresh for the release; cargo deny check advisories clean. cargo-sources.json regenerated for the Flatpak/Flathub manifests.

Installation

Flatpak (Recommended)

flatpak install flathub io.github.totoshko88.RustConn

Snap

sudo snap install rustconn

Debian/Ubuntu (.deb from this release)

sudo dpkg -i rustconn_0.24.3_amd64.deb
sudo apt-get install -f  # Install dependencies if needed

Fedora (.rpm from this release)

sudo dnf install rustconn-0.24.3-1.fc44.x86_64.rpm

AppImage

chmod +x RustConn-0.24.3-x86_64.AppImage
./RustConn-0.24.3-x86_64.AppImage

macOS (Homebrew)

brew tap totoshko88/rustconn
brew install rustconn
open $(brew --prefix)/opt/rustconn/RustConn.app

All dependencies (GTK4, libadwaita, VTE, Adwaita icons) are installed automatically.
Requires macOS 13 (Ventura) or later.

OBS Repositories

Packages available at: https://build.opensuse.org/package/show/home:totoshko88:rustconn/rustconn

# Debian 13 (Trixie)
echo 'deb http://download.opensuse.org/repositories/home:/totoshko88:/rustconn/Debian_13/ /' \
  | sudo tee /etc/apt/sources.list.d/rustconn.list
curl -fsSL https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/Debian_13/Release.key \
  | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/rustconn.gpg > /dev/null
sudo apt update && sudo apt install rustconn

# Ubuntu 24.04 LTS (Noble)
echo 'deb http://download.opensuse.org/repositories/home:/totoshko88:/rustconn/xUbuntu_24.04/ /' \
  | sudo tee /etc/apt/sources.list.d/rustconn.list
curl -fsSL https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/xUbuntu_24.04/Release.key \
  | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/rustconn.gpg > /dev/null
sudo apt update && sudo apt install rustconn

# Ubuntu 26.04 LTS (Resolute)
echo 'deb http://download.opensuse.org/repositories/home:/totoshko88:/rustconn/xUbuntu_26.04/ /' \
  | sudo tee /etc/apt/sources.list.d/rustconn.list
curl -fsSL https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/xUbuntu_26.04/Release.key \
  | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/rustconn.gpg > /dev/null
sudo apt update && sudo apt install rustconn

# Fedora 44
sudo dnf config-manager addrepo --from-repofile=https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/Fedora_44/home:totoshko88:rustconn.repo
sudo dnf install rustconn

# Fedora 43
sudo dnf config-manager addrepo --from-repofile=https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/Fedora_43/home:totoshko88:rustconn.repo
sudo dnf install rustconn

# openSUSE Tumbleweed
sudo zypper ar https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/openSUSE_Tumbleweed/ rustconn
sudo zypper ref && sudo zypper in rustconn

# openSUSE Leap 16.0
sudo zypper ar https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/openSUSE_Leap_16.0/ rustconn
sudo zypper ref && sudo zypper in rustconn

Arch Linux (AUR)

yay -S rustconn

FreeBSD (Ports)

pkg install rustconn

Full installation guide: https://github.com/totoshko88/RustConn/blob/main/docs/INSTALL.md

Verifying your download

Every binary on this release (deb, rpm, AppImage, Flatpak) is covered two ways.

Plain checksums — download SHA256SUMS alongside the asset, then:

sha256sum -c SHA256SUMS

Signed build provenance (SLSA, via Sigstore) — proves the file was built by this
workflow from this commit:

gh attestation verify RustConn-0.24.3-x86_64.AppImage --repo totoshko88/RustConn

(The snap is signed by the Snap Store; the macOS build is delivered via the Homebrew tap.)