Tags: GlassHaven/Haven
Tags
Bump to v5.24.80: gate Desktop orientation on settled pager page User report: sliding the screen pager from Keys to Settings briefly flipped the device to landscape and back to portrait — even though the Desktop tab was never selected. Cause: DesktopScreen's orientation LaunchedEffect (v5.24.74) wrote requestedOrientation = desktopOrientation (LANDSCAPE default) the moment DesktopScreen entered composition, and the matching DisposableEffect.onDispose reset it to UNSPECIFIED when it left. HorizontalPager composes adjacent pages during a swipe gesture, so any swipe that grazed the Desktop page triggered the lock-and-unlock cycle without the user ever landing there. Fix: add isActive parameter and only apply desktopOrientation when the pager has settled on Desktop. Wired in HavenNavHost from pagerState.settledPage == pageOf(Screen.Desktop), same pattern TerminalScreen already uses. While inactive, the page now keeps the activity at SCREEN_ORIENTATION_UNSPECIFIED — passing through during a swipe is a no-op. The orientation toggle button still works while on the Desktop tab.
Bump to v5.24.79: opt-in keep-screen-on while in a terminal tab (#122) agevlakh (#122) asked for the display to stay awake while reading long-running output from a terminal session. New Settings toggle: "Keep screen on in terminal" (off by default). When enabled, TerminalScreen sets the host View's keepScreenOn flag in a DisposableEffect — so the flag is active only while the terminal is composed and is automatically cleared when the user navigates to any other surface (Connections, Files, VNC, RDP, Settings). Only the terminal screen burns battery, not the whole app. Default off because keepScreenOn drains battery when forgotten — opt-in matches the request ("when working in the terminal") and prevents accidental drain after a one-off use. The volume-keys-for-text-size half of #122 is intentionally not implemented: pinch-to-zoom already covers terminal text scaling and the maintainer rejects hijacking system buttons by default.
Bump to v5.24.78: tunnelled VNC/RDP/SMB auth + leaked sessions on fai… …lure (#121) KoriKraut (#121) reported VNC over SSH tunnel failing with "Auth cancel for methods public key,password" while plain SSH and plain VNC to the same host both worked, and each retry leaving another undismissable active session ("5 active sessions"). Two bugs in connectJumpHost. 1. Empty password on the auto-connect path. VNC/RDP/SMB tunnel call sites pass "" because the user clicked the VNC profile, not the SSH one — so there's no user-typed password to forward. connectJumpHost forwarded the "" through to resolveAuthMethod, which fell through to Password(""). For SSH profiles that auth with a saved password, JSch then exhausted both key and password attempts and bounced. Fix: fall back to jumpProfile.sshPassword ?: "" when the caller passes an empty password. User-typed passwords (the #116 jump-chain path) still take precedence. 2. Failed jump-host sessions leaked. The session was registered before auth was attempted; on any throw inside the connect block (auth failure, host-key rejection, network) it stayed in the session manager forever. Each retry added another. Fix: try/catch around the auth flow; on throw, set status ERROR, removeSession, rethrow. Mirrors connectSshSilent's existing pattern. Untested with a real password-auth jump host in this session — fix is small, mirrors a working pattern, but warrants reporter retest.
Bump to v5.24.77: explicit USB permission Intent for Android 14+ FIDO2 ( #15) olmari (#15) hit an immediate crash on a Pixel 9 Fold (Android 15) when selecting an SSH connection backed by an ED25519 SK key with their YubiKey plugged in: sh.haven.app: Targeting U+ (version 34 and above) disallows creating or retrieving a PendingIntent with FLAG_MUTABLE, an implicit Intent ... use FLAG_IMMUTABLE. Cause: FidoAuthenticator.performUsbAssertion built a PendingIntent around an implicit Intent (`Intent(ACTION_USB_PERMISSION)` with no package set) and Haven targets API 35. Android 14+ blocks that combination — UsbManager.requestPermission writes the EXTRA_PERMISSION_GRANTED flag back into the intent so we have to keep FLAG_MUTABLE, which means the Intent itself must be made explicit. Fix: setPackage(context.packageName) on the permission Intent before wrapping it in the PendingIntent. The broadcast still only reaches our own receiver (the IntentFilter on ACTION_USB_PERMISSION already constrained it); Android 14+'s safety check now sees an explicit target and allows the MUTABLE flag. Untested with a physical YubiKey on Android 14+ in this session — relies on olmari (or any FIDO2-key user) to confirm.
Bump to v5.24.76: VISIBLE_PASSWORD opts Gboard out of autocap+autospa… …ce (#115) agevlakh reported the v5.24.56 fix for #115 didn't help: Huawei Pura 70 video showed typed "cd" landing as "CD" and "ip" as "IP " — Gboard's autocapitalisation and auto-spacing still firing even with NO_SUGGESTIONS set. Cause: NO_SUGGESTIONS only hides the suggestion strip; Gboard's silent smart-typing heuristics fire independently. Fix in termlib: for non-Samsung IMEs, use TYPE_TEXT_VARIATION_VISIBLE_PASSWORD on top of TYPE_CLASS_TEXT in Secure mode. Visible-password is the standard Android opt-out from every IME smart behaviour. Samsung-gated IMEs keep their NO_SUGGESTIONS | AUTO_CORRECT combo to preserve the #110 fix. Tradeoff: VISIBLE_PASSWORD disables IME composition, so default Secure mode no longer supports CJK. CJK users should switch to Compose mode (Settings → Keyboard); voice and swipe similarly belong in Standard mode.
Bump to v5.24.75: use LocalActivity instead of casting LocalContext
CI lint on v5.24.73 + v5.24.74 failed with:
LocalContext should not be cast to Activity, use LocalActivity instead
The orientation code in RdpScreen, VncScreen, and DesktopScreen
fetched the activity via LocalContext.current as? Activity. Compose
lint flags this as fragile because the cast fails on test/preview
hosts where the LocalContext is not an Activity. Replaced with
androidx.activity.compose.LocalActivity.current, which returns the
ComponentActivity directly.
activity-compose 1.10.1 (already in libs.versions.toml) supplies
LocalActivity. No behavioural change.
`./gradlew :app:lintArm64Release` now passes locally.
Bump to v5.24.74: orientation toggle actually sticks
The button shipped in v5.24.73 cycled the icon but the activity
snapped back to landscape every time. Two underlying bugs:
1. MainActivity had no `configChanges` declared, so each rotation
destroyed + recreated the activity. The DisposableEffect's
onDispose ran during destruction, reset requestedOrientation to
UNSPECIFIED, the new activity rotated, repeat. Added the standard
Compose-app `configChanges` list to the manifest.
2. The multi-session DesktopScreen has a conditional tab bar
(`if (tabs.size > 1 || !isConnected) DesktopTabBar(...)`) above
the session content. When isConnected briefly flipped during a
rotation recomposition the bar appeared/disappeared, shifting
the session content's slot position in the parent Column and
triggering Compose to dispose+recreate RdpViewer/VncViewer. Their
local `remember { mutableStateOf(Landscape) }` reset, and the
LaunchedEffect immediately wrote Landscape back to the activity.
Source of truth lifted out of the inner composables:
- DesktopViewModel owns desktopOrientation: StateFlow<Int> and
exposes cycleDesktopOrientation(). DesktopScreen applies it to
the activity from a stable parent (above the conditional bar).
- RdpScreen / VncScreen (standalone wrappers) own a local remember
and apply via LaunchedEffect from their own outer scope.
- RdpViewer / VncViewer now take currentOrientation: Int +
onCycleOrientation: () -> Unit; the toolbar button just renders
the icon and forwards taps. Removed the local-state and
LaunchedEffect/DisposableEffect inside the inner composables.
The OrientationMode enum stays per-feature (private) and gains a
`fromActivityValue(Int)` + a top-level `cycleRdpOrientation` /
`cycleVncOrientation` helper exposed for callers that own the state
elsewhere.
Cycle order unchanged: Landscape -> Portrait -> Auto. Default
unchanged: Landscape on session entry. Activity restored to
UNSPECIFIED when the owning composable disposes.
Add replay-egfx-pdu triage tool for EGFX_PDU_DUMP_DIR captures Companion to the dumper added in bd2e52d. Reads a captured .bin (or batches a whole directory) and prints a one-line summary per file: ServerPdu variant, surface ids, codec ids, payload sizes — plus, for WireToSurface1, both the inclusive and the exclusive interpretation of width/height from the destination_rectangle. That dual print makes attached fixtures self-document what Devolutions/IronRDP#1238 is fixing: spec-correct bytes have right=W (exclusive), but today's ironrdp parses them as InclusiveRectangle and the trait method's width() returns W+1. Auto-detects mode from filename (slow_path_bitmap_update_*.bin → BitmapUpdateData, else ServerPdu); --egfx and --slow-path force a mode. Exit codes: 0 = all decoded, 1 = none decoded, 2 = mixed. Useful as a CI gate before sending captures upstream. Build with `cargo build --features host-cli --bin replay-egfx-pdu`. Codec1Type / Codec2Type matches are exhaustive so a future ironrdp codec addition fails the build here and forces an update.
Bump to v5.24.73: orientation toggle on RDP + VNC session toolbars A rotate-icon button on the session toolbar (and fullscreen overlay menu) cycles Landscape -> Portrait -> Auto. Default stays Landscape, matching the prior #109/surf5726 forced-landscape behaviour the DesktopScreen had been applying globally; that DisposableEffect is removed since the per-session composable now manages it (and restores UNSPECIFIED on dispose). Choice persists across config changes via rememberSaveable but isn't yet persisted per profile — closing and reopening a tab resets to landscape. Per-profile preference can come later. Implementation: a tiny private OrientationMode enum lives in each of feature/rdp/RdpScreen.kt and feature/vnc/VncScreen.kt (mirrors, not shared) with three entries mapping to ActivityInfo's SCREEN_ORIENTATION_USER_LANDSCAPE / USER_PORTRAIT / UNSPECIFIED. Feature modules don't depend on each other, so duplicating ~25 LOC beats inventing a shared module for it. Rust unchanged, no .so rebuild.
Bump to v5.24.72: typing works in Windows RDP across both viewer paths ASCII chars typed into a Windows RDP session were being sent as TS_FP_UNICODE_KEYBOARD_EVENT, which the Windows console host (cmd, PowerShell) silently drops — only Enter and other scancode-mapped keys made it through. Two viewer paths needed the fix because the Desktop multi-session view (DesktopScreen) bypassed the standalone RdpScreen wrapper. New shared helper `typeRdpChar(ch, sendKey, sendUnicode)` in feature/rdp/RdpKeyMapping.kt maps US-layout ASCII to AT Set 1 scancodes (with shift handling for capitals + shifted symbols), and falls back to the Unicode path for non-ASCII. Both RdpScreen.kt:259 and DesktopScreen.kt:170 onTypeChar handlers now call it. Rust unchanged, so no librdp_transport.so rebuild needed for this release.
PreviousNext