#1809 held Steam's own UI to an even share of the refresh near 60 fps whenever it had focus. On 120 Hz and faster screens Big Picture then felt locked at 60 while games ran at the full rate, and players reported it as a regression. The compositor now releases Steam UI buffers unpaced again, like a game's. The larger swapchain stays limited to games, so the client UI still uses gamescope's default image count.
* fix(xbox): keep the game in its own folder on the short drive instead of at the drive root
* fix(xbox): SD card Xbox games can read their own package files
Xodus mounts a store library on the selected SD card at /mnt/droiddeck-stores/<card> and links the launch view to it, but game sessions only bound that library as /mnt/droiddeck-sd. The links were dangling inside the game, so MicrosoftGame.Config, appxmanifest.xml and XCurl.dll could not be read and GDK games stopped with "Failed to initialize GDK". Game sessions now bind the same store roots Xodus uses.
* fix(xbox): give the SD Steam library its own store path when another store root shares the card
externalRootsForXodus added the selected Steam library's Games folder with the card's guest path even when another store root on the same card already used it, so both bound to one destination. It now takes a path-derived suffix in that case, the same way externalRoots separates its own roots.
fix(runtime): ship libva-drm2 and libva-x11-2 so DroidDeck-Proton's video demuxer loads
DroidDeck-Proton's ffmpeg links libva-drm and libva-x11. The runtime only had libva2, so winedmo.so failed to load and Media Foundation video stopped: Resident Evil Revelations hung on its loading screen with "Failed to create demuxer, status 0xc000007a", and RE engine and Kingdom Hearts cutscenes broke. Installing the desktop hid it because Plasma pulls both in.
* perf(epic): keep the hidden launcher from loading its store and Fab pages, and compress it while games run
The hidden Epic Games Launcher that stays up for sign-in while a game runs pre-warmed its store and Fab pages on a display nobody sees. Under FEX each page used about one core and grew past a gigabyte, crashing and reloading in a loop. The hidden instance now skips the store pre-warm, gets a blank page in place of Fab, and is paged out to zRAM with the Steam client once a game has focus. The visible launcher is unchanged.
* test(zram): keep the scan fixture PIDs above the kernel PID range
Pill: battery level, temperature and watts share one "BAT" row, as on the
other sizes, and each part follows its own switch. Turning Memory off no
longer hides the battery temperature (reported by Keegan), and watts show
without the battery level.
Touch (part of #1752, reported by ZZCSK): a locked HUD lets a touch through
where an on-screen control under it takes it: controller buttons and sticks,
Steam touch controls, screen keys and the controls panel below the game.
Each layer answers takesTouchAt with its own touch checks. Everywhere else
the HUD keeps the touch, so a long press still locks or unlocks it. A new
HUD starts locked. The "Lock in place" hint says so in every language.
Tests: Pill battery row per switch combination; takesTouchAt agrees with a
real touch over a grid for the controller buttons, screen keys and both
controls panel layouts (Deck and gamepad, landscape and portrait); a locked
HUD passes touches to a control under it, keeps the rest, and unlocks on a
long press.
* Use the second screen on dual-screen handhelds
Detect built-in second screens such as the Retroid Pocket Duo and AYN Thor.
The sections move to a menu on the bottom screen, L2 and R2 switch sections,
and text fields type on the bottom screen so the top keeps the full view.
Sessions open the bottom-screen trackpad and keyboard when they start.
Setup gains a Dual screen choice (Automatic, On, Off) with toggles for the
bottom menu and the in-game controls. Closing the bottom menu no longer ends
a running session.
* Type into Steam from the bottom screen
While the bottom-screen trackpad and keyboard controls are open in a Steam
session, Steam's own on-screen keyboard no longer covers the top screen.
The agent keeps Steam's text target and asks the app instead, which opens
the Android keyboard on the bottom screen and hands focus back to the game
when it closes. Modal and VR keyboards, and sessions without the bottom
controls, keep Steam's keyboard. The Show keyboard button now follows the
keyboard when it is closed another way.
* Open the bottom controls after the first frame and tidy dual-screen translations
* Move the in-game menu to the bottom screen on dual-screen handhelds
Fix controller input and focus on the second screen: keys and sticks reach the game after touching the bottom controls, closing the bottom controls returns focus to the game, B closes bottom typing, and the typing panel keeps a focusable window until focus has left it.
* Let B close the open layer of the session menu first and focus the selected bottom-screen mode
* Let the Retroid Pocket Duo Home double press open its quick menu during sessions
* Open the keyboard on the bottom screen for Steam text fields and hide it on Enter or when the field loses focus
* Keep controller focus on the top screen when a section is picked on the bottom screen
* Keep LB and RB on the store tabs and let Back return from a store to its tab
* Show the Adreno 722 as supported on the Retroid Pocket Duo
* Label the Steam integration suggestion's close button Close and cover that closing it is permanent
* Close the docked menu with its presentation, keep a focus picked during the stop delay, and ignore panel picks on process-settings pages
* perf(fex): answer raw stat, readlink and statx syscalls through the proot fast path
FEX issues newfstatat, readlinkat and statx as raw syscall() calls, which skipped the libc wrappers the fast path hooks and fell through to ptrace. Route them through libblfastpath the same way raw openat already is, and keep the fast path's own /proc/self/exe lookup off the hooked syscall().
* test(fex): keep the raw lookup test passing on kernels without statx
* Warn when a drive used as a game library is linked at USB 2.0 speed
Reads the drive's USB link speed from sysfs through its mount, and shows a
dismissible warning with the USB generation, link speed and a tip for a
faster cable or drive. The warning returns after the drive is plugged in
again unless Don't show this again is switched on.
* Keep slow USB dismissals per plug-in across restarts and recheck after a dismiss
Dismissals are stored with the boot count and the USB bus and device number,
so they survive a process restart, end when that drive is plugged in again
even while the launcher is stopped, and never clear other drives. A dismiss
looks for the next slow drive, stale scans are dropped, and an unknown port
speed is no longer treated as a USB 2.0 port.
* Drop slow USB scans that a newer library or mount check has superseded
* Invalidate pending slow USB scans as soon as a media broadcast arrives
* Revalidate an open slow USB warning on every check and match raw mount library paths
Every check now rescans, so a warning that is already showing is replaced or
cleared when its drive is removed or the library changes. Library paths saved
under /mnt/media_rw are treated as their /storage volume.
* Keep the Don't show this again choice when a rescan closes the slow USB warning
* Save the slow USB opt-out before the launcher activity is torn down
* feat: art-first store cards that share the library display settings
* fix: keep price and installed state on store cards when size is hidden
* fix: darken the compact store badge for contrast on light artwork
* feat: art-first library cards with a display menu for size, title and storage
* build: use native arm64 docker on Apple Silicon and add a fast deploy loop
* fix: address review feedback on library cards and local build scripts
The session HUD is FusionHUD (Bannerlator's HUD) with every reading taken from
the same source, and worked out the same way, as the MangoHud build that runs
Steam's performance overlay in a DroidDeck session.
- gamescope patch 0125 (gamescope-3.16.29-p19) shares the frame times that
mangoapp reads (one per signalled commit of connector 0) in a ring named by
DROIDDECK_HUD_FRAMES; the app reads it once per display frame and counts the
compositor's frames when gamescope sends none.
- MangoHud's rules: FPS over periods of at least 500 ms, frame time = 1000/FPS,
200-frame graph on a fixed 0-50 ms scale; CPU, GPU, temperatures, RAM, swap,
VRAM and battery from MangoHud's sources. Zones 22/26/28 are typed as GPU and
DDR sensors, so Steam's overlay CPU temperature no longer includes them.
- Five sizes in a panel shaped like the DroidDeck mark, with a centred header,
one left edge, neon outline and FPS; Minimal is the default size. Settings on
a new "Performance HUD" drawer page, with Bannerlator's options.
- The HUD reads sensors and polls frames only while it is drawn (not while
hidden, in picture-in-picture or behind another app), keeps its place after
picture-in-picture, and the diagnostics export has its own reader.
Device-tested on the AYANEO Pocket FIT: same readings as Steam's overlay side
by side in Dead Cells; the HUD updates in a game, hides in picture-in-picture
and comes back in place, no crashes.