v0.20.1
What's Changed
Added
- Settings ▸ Interface ▸ Window — show connection name in split panes (issue #277) — a new toggle adds a compact colored header at the top of each split-view pane displaying the connection name and protocol. Off by default; useful when 3+ panes are open side by side and the color indicator alone is not enough to identify which pane belongs to which connection at a glance. The header background matches the panel's color (15% opacity), shrinks in compact mode, and updates live when a session is moved between panes via drag-and-drop or Select Tab.
Fixed
-
Group names are now unique per parent folder, not globally (issue #291) — RustConn rejected creating a group whose name existed anywhere in the tree, even under a different parent. Hierarchies like
Site A/RDP+Site B/RDPwere impossible, and CSV imports silently merged unrelated branches. Uniqueness is now enforced only among siblings sharing the same parent. Moving or renaming a group into a parent that already contains a child with the same name is still rejected. -
A split pane could not be closed at all when its connection had the floating toolbar switched off (issue #260 follow-up) — 0.20.0 gave RDP, VNC and the embedded browser a switch that removes the session toolbar, and marked the viewer with a
no-floating-overlaysCSS class so the split view would leave it alone too. The split view read that marker before adding its own corner-button overlay, so Remove from Split and Close session disappeared along with the toolbar. Those two buttons are the split view's, not the viewer's, and they are the only discoverable way to dismantle a pane: the right-click menu still carried the actions, but a pane the user cannot see a way out of is a pane they cannot close. The corner buttons are unconditional now, and the marker — which had exactly one reader — is gone with the gate rather than left behind as state nothing consumes. What #260 asked for is unaffected: the viewer's own toolbar and its 44×44 reveal handle are still switched off inside the viewer, before it ever reaches the split view. -
RDP: xrdp hosts no longer stop at their own greeter after a successful NLA exchange (#290) — the connector hardcoded
autologon: false, soINFO_AUTOLOGONwas never set in the Client Info PDU. Windows ignored this (session established via CredSSP/NLA), but xrdp only skips its login screen when the flag is present. Connecting to a Linux host got past authentication and then paused at the xrdp greeter asking for the same credentials again. FreeRDP sets the flag whenever credentials are supplied, which is why the same host logged straight in from Remmina. The flag is now set when both a username and a non-empty password are available. -
Opening the connection dialog crashed the application if an SSH agent key had a non-ASCII comment (#278) —
format_agent_key_shortsliced the comment at byte offsets, but agent key comments are free text fromssh-keygen -C. An accented letter or emoji at the 10-byte boundary panicked inside a GTK signal handler, aborting the entire process and taking every open session with it. The function now measures and cuts in characters. -
Vault credentials were not found for connections inside a group (#289) — saving stored the credential under the hierarchical key
RustConn/{group}/{name} ({protocol}), but resolving searched only the flat{name} ({protocol}). Any connection in a folder prompted for a password on every connect attempt despite the secret sitting in the keyring. The hierarchical key is now tried first, with a fallback to the flat key for credentials written by older releases. -
Minimizing to tray silently destroyed port forwards, recordings and external viewers (#279) — the close handler ran
flush_active_recordings(),tunnel_manager.stop_all()andexternal_session_registry().shutdown()unconditionally, before the minimize-to-tray decision was reached. Closing the window with tray enabled hid it and then tore down everything behind it. The tray decision now fires first, and the session snapshot is saved on that path so a subsequent force-kill does not lose session state. -
A post-disconnect automation task froze the entire application for up to 60 seconds (#281) — the task ran via
block_on()directly in thechild-exitedhandler on the GTK main thread. An arbitrary user command (script, ssh, curl to an unreachable host) blocked every other terminal, RDP and VNC tab until it finished or the 60-second ceiling fired. The work now runs on a background thread viaspawn_blocking_with_callback. -
Remote session recordings were lost when quitting the application (#282) —
flush_active_recordingsusedspawn_blocking_with_callback, whose 16 ms poll callback is never reached once the main loop stops on the quit path. The SCP result was dropped, the.meta.jsonsidecar was never written, and the recording disappeared. A newstop_recording_blockingvariant runs the retrieval inline on shutdown, bounded byConnectTimeout=5so an unreachable host cannot hang the window. -
Web embedded: links requesting a new view (target="_blank", window.open) did nothing (#288) — nothing was connected to WebKit's
createsignal, so every request for a second web view was silently dropped. On SAPUI5-like pages whose links usewindow.open(), every link appeared broken. The requested URI is now loaded in the same view, preserving the authenticated session. -
Network monitor reported a false outage on every Flatpak launch (#284) —
GNetworkMonitorPortalemits an initialnetwork-changedsignal ~6 ms after creation as it learns the host's real state. This was treated as a real transition, showing "reconnecting affected sessions" with nothing wrong. Additionally, the debounce erased a down→up flap shorter than 3 s, preventing the recovery sweep from running. The first signal is now treated as a baseline, and debounce only collapses signals that classify the same way. -
A session closed with
exitwas silently reconnected on the next Wi-Fi roam (#285) — the reconnect sweep picked victims by asking whether the reconnect banner was visible, but a banner is not consent: it is also shown for a shell the user closed withexit, for a failed login and for a rapid crash. The disconnect path now records its verdict, and the sweep requires explicit eligibility alongside the visible banner. -
Web embedded: the toolbar's reveal handle was unreachable in a split pane, buried under the split view's own panel arrow — 0.20.0 moved the Web handle to the top trailing corner, reasoning that a web page keeps its logo, primary navigation and search across the top centre, where a 44×44 button swallows clicks meant for the page. That corner was already taken:
SplitViewAdapteroverlays the panel's reveal arrow at exactly the same spot, so in a split layout the two stacked and the page's toolbar could not be summoned at all. Neither widget could notice the other — they are added to different overlays by different modules, one keyed to the viewer and one to the pane. The handle is back at the top centre for every viewer, which is what the centre position's own documentation had given as its reason all along: it "keeps the handle clear of the window controls and split-view buttons that live in the corners". The page-content cost is real but recoverable — a connection that wants an unobstructed page switches Navigation Toolbar off (issue #260) and gets no handle at all — whereas a handle underneath another widget is not recoverable. With all three viewers agreeing again, theRevealHandleenum and theattachparameter that carried it are gone.
Improved
scripts/release.shnow runstypos, the last CI gate it did not — the CIHygienejob spell-checks the tree and fails the build on it, and the release script did not, so this release reached a pushed tag and a published GitHub release with a red CI over one word:cliente, Spanish for "client", in the SSH agent key commentbackup-señor-cliente-finalthat the #278 regression tests use. The fixture has to be text a real person would type, because that is the entire bug — the comment is free text fromssh-keygen -Cand slicing it at a byte offset panicked inside a GTK signal handler — so the word is allowed intypos.tomlrather than anglicised, which would have cost the test its point. Exactly the gap 0.20.0 closed for the three i18n checks, in the one place it was not closed; the gate resolves~/.cargo/bin/typosexplicitly when it is not onPATH, because a gate that silently skips reports nothing and is believed.
Localisation
- Three strings added this release reached only Ukrainian — the two "Show connection name in split panes" labels were translated in
ukalone, so the other 15 locales rendered them in English; the resume toast "Reconnecting sessions after sleep" was worse off still, never having been extracted intopo/rustconn.potat all. Now in the POT and translated in all 16 locales. This is the third release in a row to find strings that shipped untranslated whilescripts/check-po-complete.shreported every catalogue at 100%, because that gate reads the committed.pofiles and never regenerates the POT to compare against — the gap 0.20.0's changelog recorded as "real and outliving this fix", and it still is.
Dependencies
- Updated: cc 1.4.2 → 1.4.3, find-msvc-tools 0.1.10 → 0.1.11, inotify 0.11.4 → 0.11.5, libredox 0.1.19 → 0.1.20, pkg-config 0.3.33 → 0.3.34, safe_arch 1.1.0 → 1.2.0
- ICU / zerovec family: icu_collections, icu_locale_core, icu_normalizer, icu_normalizer_data, icu_properties, icu_properties_data and icu_provider 2.2.0 → 2.3.0, alongside litemap 0.8.2 → 0.8.3, potential_utf 0.1.5 → 0.1.6, tinystr 0.8.3 → 0.8.4, writeable 0.6.3 → 0.6.4, zerotrie 0.2.4 → 0.2.5, zerovec 0.11.6 → 0.11.7 and zerovec-derive 0.11.3 → 0.11.4. All transitive, reached through
idna→url; no direct dependency changed.
Installation
Flatpak (Recommended)
flatpak install flathub io.github.totoshko88.RustConnSnap
sudo snap install rustconnDebian/Ubuntu (.deb from this release)
sudo dpkg -i rustconn_0.20.1_amd64.deb
sudo apt-get install -f # Install dependencies if neededFedora (.rpm from this release)
sudo dnf install rustconn-0.20.1-1.fc44.x86_64.rpmAppImage
chmod +x RustConn-0.20.1-x86_64.AppImage
./RustConn-0.20.1-x86_64.AppImagemacOS (Homebrew)
brew tap totoshko88/rustconn
brew install rustconn
open $(brew --prefix)/opt/rustconn/RustConn.appAll 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 rustconnArch Linux (AUR)
yay -S rustconnFreeBSD (Ports)
pkg install rustconnFull installation guide: https://github.com/totoshko88/RustConn/blob/main/docs/INSTALL.md