980 Commits
Author SHA1 Message Date
Kurt Himebauch 10ef8c4bd6 chore: bump version to 0.4.0 (13) (#627) 0.4.0 2026-10-12 10:56:11 -04:00
Kurt Himebauch 8e01cfb2ef docs: draft DroidDeck 0.4.0 release notes (#619)
* docs: draft 0.4.0 release notes

* docs: add Thor store and launcher media for 0.4.0

* docs: show Steam switching to KDE on Thor

* docs: show Castle Crashers touch layouts and controller choices

* docs: add Amazon game install view

* docs: add trimmed user recording of store downloads

* docs: smoother touch controller recording, GOG sign-in and per-game profile screenshots

* docs: clean desktop round-trip recording replaces the KDE gif and file explorer still

* docs: add multi-controller and Steam Controller media, rebuild desktop gif without glitch frames

* docs: add foldable touch gamepad screenshots from its PR

* docs: add the Discord badge to the 0.4.0 notes and tidy contributor lines

* docs: fold fixes to new 0.4.0 features into their entries, add Follow screen shots, point the changelog at the 0.4.0 tag

* docs: add the Add a game dialog to the non-Steam games entry

* docs: add a TL;DR for Mr. Sujano to the 0.4.0 notes
2026-10-12 10:49:14 -04:00
Neolyum b25c4ea26b Fix multiple controller discovery (#614) 2026-10-12 11:45:00 +00:00
Kurt Himebauch cebad5692d feat: store uninstall confirms in a step-out, shows progress, and lands on Install (#609)
feat: store uninstall confirms in a step-out, shows its progress in place, and the game reads Install the moment it is gone
2026-10-12 11:03:03 +00:00
Kurt Himebauch 6b2c8ace09 fix: keep the Steam desktop client in KDE (#610) 2026-10-12 06:56:56 -04:00
Kurt Himebauch 4d1b8421fb feat: store game pages flood onto their hero art, and downloads survive a restart (#608)
* feat: a store game's page floods out of its card onto its own hero art, and draws back from it

* fix: installs interrupted by the app closing show in Downloads with Resume and Clear

* feat: finished and interrupted downloads share the running card's art look, and the queue sits under what is running

* fix: the download queue outlives the app: queued, running and paused downloads come back after a restart
2026-10-12 03:58:07 +00:00
Kurt Himebauch ced4ac5db8 fix: a step-out out of a wide control draws its box again (#607) 2026-10-12 03:31:48 +00:00
Kurt Himebauch e190f57b53 feat: components newest first, Steam settings open on Steam with offline mode, smoother chip selection (#606)
* feat: components list newest first, Steam's sheet opens on its Steam tab with offline mode, and Setup's overview drops the account group

* fix: chip selections stretch across on every move, drawn over the chips instead of behind them
2026-10-12 03:25:55 +00:00
Kurt Himebauch 22f02fb6bf feat: the focus ring is the only fill and keeps up with focus (#605)
* feat: with a pad the focus ring fills what it holds and is the only fill; chip rows mark their pick with a bar

* fix: the focus ring chases focus on a continuous spring per edge instead of restarting on every move
2026-10-12 03:16:07 +00:00
Kurt Himebauch 52c67df4c7 fix: store chips mark the shown store without faking focus, and step-outs open and fold cleanly (#604)
* fix: a chip selection hopping past a chip fades across instead of crawling over as a drop

* fix: the store chips' fill only shows where a pad's focus is, not on the shown store

* feat: the shown store's chip carries a bar on its foot, every chip pulses when picked, and the queue's settings live only in the cog

* fix: step-outs grow and fold in one move with no tail, keep the ring out while moving, and hand focus back to their control
2026-10-12 03:04:33 +00:00
Kurt Himebauch de1a734fb5 fix: settings sheet focus ring, Left to fold, chips pick on focus (#600) 2026-10-12 02:11:53 +00:00
Kurt Himebauch be9939d82c Fix black Steam output with FSR 1 (#597) 2026-10-11 21:03:07 -04:00
Kurt Himebauch e4c375ad0d Fix Discord launcher layout and controller navigation (#596) 2026-10-11 20:08:59 -04:00
Gustash 0cafa83ea7 fix: Epic games with a JSON manifest download (#578) 2026-10-11 17:37:47 -04:00
Juan MartíandKurt Himebauch 435beb7f19 feat: add persistent per-game compatibility profiles (#449)
* feat(profiles): add persistent per-game compatibility profiles

* fix(profiles): show Windows component overrides

Include per-game Windows component selections in the resolved profile summary so the session overlay marks those games as custom and shows the selected components.

* fix(session): detect Proton games across runtime paths

* fix(profiles): select the active Gamescope game

* fix(profiles): improve per-game reset feedback

* fix(profiles): align session components with game overrides

* fix(session): prefer selected Steam game during refresh

* fix(session): resume profile following when reopening games

* chore: keep local dev testing outside the repository

* test(session): remove local dev package path

* fix(session): preserve profiles when refresh fails

* fix(session): reject empty game profile reset scope

* perf(session): cache drawer inventory by refresh revision

* fix(profiles): align game presets and profile reset behavior

* fix(profiles): preserve originals and normalize shortcut ids

* fix(profiles): keep editor scope stable after rebase

* fix(tests): host Compose tests in both build variants

* fix(profiles): recover interrupted component selection saves

---------

Co-authored-by: Kurt Himebauch <[email protected]>
2026-10-11 17:00:28 -04:00
The412Banner 78fcb60fd5 DroidDeck-Proton as a Proton source, and update checks for every source (#588) 2026-10-11 16:07:44 -04:00
The412Banner 4995b3553b Merge remote-tracking branch 'org/main' into feat/droiddeck-proton-source 2026-10-11 15:56:18 -04:00
MaxsTechReview 3c2878cc52 Red Dead Redemption 2: launches again, no screensaver over games, hidden launcher held to one core, /tmp cleaned (#585)
* fix: Red Dead Redemption 2 launches again, its Vulkan runtime installer is left to run

droiddeck-seed-redists marked every process in every game's install script
as already run, Red Dead Redemption 2's VulkanRT-1.1.108.0 installer
included. Steam's compat config for the game says nativevulkanloader, so
Proton loads vulkan-1.dll native only, and Khronos' loader is in the prefix
only once that installer has run. Without it the Rockstar launcher starts
RDR2.exe and it exits with STATUS_DLL_NOT_FOUND (0xc0000135) before it
opens a window.

A Vulkan runtime installer is now left out of the seeding, and a marker an
earlier seeding wrote for one comes out of each prefix and Proton template
once (dates kept), so the client runs the installer on the next launch.
The installer finishes in a few seconds under FEX.

* fix: Steam's screensaver no longer covers a running game

The client's defaults show screensavers while a game runs, after 300 s on
AC power without a button press - and a held stick or trigger is no press.
Red Dead Redemption 2's intro runs longer than that: the slideshow covered
the game, and the button that woke it reached the game too (B asked to
quit to the desktop). Customization/Screensaver/WhileInGame is seeded "0"
in config.vdf once, like the UI scale and native resolution, so turning it
back on in Settings stays the user's choice.

On the RedMagic: 18 minutes from the last button press through the intro
and riding, focus never left the game and no screensaver was created.

* fix: Rockstar's hidden launcher no longer takes cores from its game

The Rockstar Games Launcher keeps drawing its Chromium interface
(SocialClubHelper.exe: renderers, and a GPU process compositing through
DXVK) for as long as the game runs, hidden behind it - and Wine passes
Chromium's priorities on, so those threads ran above the game's (the GPU
process at nice -10), across every core. With Red Dead Redemption 2 in
front that was 1.3 to 2.5 cores under FEX for a page nobody sees.

droiddeck-launcher-cores follows gamescope's focus from the agent's
focus.json: while a game window has it, every SocialClubHelper thread runs
on the last core of the slowest cluster at nice 19; when the launcher's own
window has focus again each thread gets its own mask and priority back
(also on exit). Stopping the helpers would not hold - proot resumes a
stopped tracee. Started for Steam sessions; BL_LAUNCHER_CORES=0 turns it off.

RedMagic, RDR2 all Low, riding at the thermal limit, same spot and session:
released 46.5 fps, 1% low 27.5, p99 31.8 ms, CPU 89%, 2200 MHz;
held 48.7 fps, 1% low 32.6, p99 27.6 ms, CPU 79%, 2638 MHz.

* fix: sessions clean up what earlier ones left in /tmp

The guest's /tmp is a directory in the rootfs that no boot ever empties,
and Android ends sessions by killing them. Every session left a
/tmp/mangohud.XXXXXXXX (mktemp, never removed), and the Steam client, its
web helper, Chromium apps, dbus-run-session, AppImage runs and KDE their
own temporary files and sockets: 1,422 entries on the RedMagic.

mangoapp's config is now one fixed file rewritten each session, and the
session's first pass sweeps each kind of leftover while nothing that could
own one is running, with a single find. On the device that cleared 1,391
entries over two sessions, leaving 38.
2026-10-11 15:53:01 -04:00
The412Banner 715032062d feat: DroidDeck-Proton as a Proton source, and update checks for every source
Setup > Proton versions lists DroidDeck-Proton (The412Banner/DroidDeck-Proton) beside
GE-Proton and proton-cachyos: same aarch64 tarball pattern as GE, verified against its
sha512 file, installed by droiddeck-proton-extra (also as "droiddeck" in the session queue)
and adopted by steam-compatibility like any other extra, so it shows as
"DroidDeck-Proton <ver> (Compatible)". Its folder has a space; nothing in the install,
adopt, esync or components paths splits on it.

Update checks: each source's newest full release is looked up at app start and when the
page opens, at most every 6 h (offline keeps the last answer). A newer release shows
"Update available -> <tag>" with Update; it installs beside the old build, which stays
until removed ("Remove old ... versions"), since games are mapped to it by name.
Installed builds are ordered by their version numbers (11-9 before 11-10), not by name,
and the tag each was installed from is recorded. Prereleases and drafts are skipped.
2026-10-11 15:32:07 -04:00
Kurt Himebauch dde08414fc feat: big ass redesign: Carry the stores' motion and layout into Steam settings, Components, Setup, Flathub and Desktop (#548) 2026-10-11 19:05:21 +00:00
Kurt Himebauch ec24b3a472 feat: the built-in pad can be a DualShock 4 or DualSense, its touchpad fed by the trackpads (#559) 2026-10-11 04:21:31 +00:00
Kurt Himebauch 6455b1dade feat: the built-in pad's controller type switches from the session menu while Steam runs (#558) 2026-10-11 00:12:53 -04:00
Kurt Himebauch 542ad3e060 feat: the built-in pad can be a Steam Controller to Steam (#545) 2026-10-11 03:24:22 +00:00
Kurt Himebauch 910fb47692 fix: the Steam Controller's hidraw node reaches the input shim again (#557) 2026-10-10 23:20:09 -04:00
Kurt Himebauch 3dd14dd625 refactor: Steam always runs in Deck mode on the Deck beta branch (#546) 2026-10-10 22:15:42 -04:00
The412Banner d1b0ac4df1 Windows components: picked automatically by each game's source (#554)
Each game's Windows components now come from the list its own source
trusts, and the ones that list names turn on by themselves. The user's own
on/off switches always win; each automatic row says why it is on.

- Steam games: the Steamworks Shared redistributables Steam installs with
  the game (appmanifest SharedDepots, else the client's appinfo.vdf).
  Steam keeps its install scripts marked as already run.
- GOG: the build manifest's dependencies. Epic: the manifest's
  prerequisite (Unreal's maps to VC++ and DirectX). Amazon: fuel.json
  PostInstall. Older GOG/Epic installs get their list fetched once with the
  saved sign-in; game files are never downloaded again.
- Custom games (the + button, Add all, migrated folders): one shared Steam
  match per game, also used for artwork. An appid from the game's files
  turns components on; a name-only match stays Recommended; no match falls
  back to the folder scan.
- Steam app info for apps the client never saw comes from an anonymous
  Steam PICS lookup (CM websocket, anonymous logon, product info), cached
  per appid; the user's Steam sign-in is never used.
- Missing components download in the background on one low-priority
  worker that pauses during sessions and waits on battery saver, heat or a
  metered network unless the user asked. A game Steam installs during a
  session is readied right away so it can be played without ending the
  session; the launch waits up to 10 s only for a component still on its
  way.
- Page: "On for this game" with reasons, a quiet "Checking what this game
  needs..." only for games never worked out, rows that ease in, pieces that
  need a download greyed out while offline. The intro names no other app.
- The folder scan skips Unity's *_Data/Managed (Mono, not .NET Framework).
2026-10-10 21:15:56 -04:00
MaxsTechReview 0e225d0c6e FEX: preload the fault report only where x86 loaders look (#551)
Preload the FEX fault report only where x86 loaders look

droiddeck-fex put the x86 libfaultreport.so in LD_PRELOAD, which FEX's own
arm64 loader reads too - and FEXServer's, and every child FEX's - so each
x86 start printed "ERROR: ld.so: object '.../libfaultreport.so' from
LD_PRELOAD cannot be preloaded", and an i386 child added "wrong ELF class".
It is now listed in the x86 runtime's own /etc/ld.so.preload, which only
the loaders inside FEX read, as /usr/$LIB/droiddeck/libfaultreport.so.

faultreport.c builds for i386 too, so 32-bit programs get the report as
well instead of an error.
2026-10-10 19:12:51 -04:00
MaxsTechReview d9cd0d2cc8 Desktop: run programs, scripts and AppImages; Switch to Desktop without Deck mode (#549)
* Run programs, scripts and AppImages from the desktop

Windows programs open with the Proton Steam has chosen, and a Steam game's own
launch program is handed to Steam. x86-64 Linux programs and game scripts run
under FEX, and an exec the kernel refuses goes to droiddeck-open through
libblsession's binfmt.c. Programs on noexec shared storage pass KIO's checks; a
folder of Linux programs there, and sharun AppImages, are added by the app once
and run from the copy. Executable scripts run without KIO's prompt, mpv plays
on the software desktop, FEXServer's socket moves under XDG_RUNTIME_DIR, and
Proton runtimes no longer show up as games.

* Switch to Desktop from Big Picture without Deck mode

Big Picture's Switch to Desktop asks the client's SteamOS manager, which the
client only has when started as SteamOS (Deck mode). Without it the request
failed and the screen stayed on "Switching to Desktop..." for good. The live
compat helper now sees the request on its way to the client and hands it to
steamos-session-select, which opens the KDE desktop as Deck mode already did.

* Run x86 programs from shared storage where they lie

FEX asks for the guest's PROT_EXEC when it maps a program or library, which
the kernel refuses on noexec shared storage; FEX never runs those pages
itself, so libblsession maps them without it in FEX's processes. An x86
game, its libraries and its start script now run in place instead of being
copied in; only native code on noexec storage is still copied.

A Steam library's games are never copied, and a Linux game's launch program
opened from the desktop goes to Steam like a Windows one.
2026-10-10 19:12:20 -04:00
MaxsTechReview eadebc46d5 Performance: idle front end, proot stops, launch-time passes and log collection (#529)
* Front end: draw the capsule wall without clipping it every frame

The tilted wall clipped each capsule to a rounded rect and recomposed its columns on every drift
step, and a rotated rounded clip is rasterised in software on the render threads: the idle main
page held about 1.7 cores. The art is now loaded at the capsule's size with its corners already
rounded, each column draws its capsules itself in one layer moved by the drift, and the drift
advances at most every 15 ms. The idle page takes about a third of a core.

* libfakeinput: let calls on descriptors it does not serve skip its lock

Every read, write, ioctl, close and poll of every process in a Proton session went through the
controller lock and the three map lookups, Wine's wineserver pipes and the game's files alike.
A bitmap of the descriptors the maps hold, set before one is handed out and cleared when it is
closed, lets everything else go straight to the kernel.

* Pad motion: ask the display for its rotation four times a second

The rotation was looked up for every sensor reading, every 2 ms, and cost more than the rest of
the reading; it is now refreshed every 250 ms, and the readings no longer allocate pairs.

* Session: keep the library passes out of a game's launch

The redist seeder stamped each prefix with the checksum of the whole set of names, which differs
between the session's pass and the game launch's (the game's own names are added), so every
launch re-appended the markers to every prefix in the library while the game loaded. Each
prefix's marker now lists the names it was given and only the missing ones are added.

The beat's seed and compatibility passes, and the Lossless Scaling ownership probe (which loads
steamclient.so), also wait while a wineserver runs: a launch rewrites the manifest and made them
due at exactly that moment. The game's own launch seeds its prefix regardless.

* Agent: keep the focus watcher's X connection open while nothing changes

The connect timeout stayed on the socket, so with no property change the read timed out, and the
watcher dropped the connection, reconnected and took a fresh snapshot every few seconds.

* Game environment: start Cyberpunk 2077 without REDlauncher

The prelauncher opens REDlauncher, a Qt WebEngine window that hands over to the game half a
minute later and then stays up beside it, well over a core busy for as long as the game runs; its
own --launcher-skip started the game twice. The game's executable is started directly instead.

* netif: answer Wine's network driver from a reading of the link

Mortal Kombat X has Wine's network driver enumerate every interface, address and route table
hundreds of times a second. Each enumeration read /etc/droiddeck-net several times, asked the
kernel for its interface dump again (a netlink socket bound under proot, refused each time) and
looked the real functions up with dlsym. The link file is now read at most once a second, a
refused dump is not asked for again within that second, and the real functions are looked up
once.

* Fast path: create memfds without a stop in proot

proot looks at a memfd's name only to refuse the few that are then executed or locked; every other
memfd_create is now issued from the trampoline. The session's /proc/net and status copies made
one per read, a stop each. Without memfd in the kernel the call still goes to proot's ashmem.

* Logs: run each redaction rule only on a line that could match it

A session's end copies some 70 MB of the Steam client's logs and puts every line through all
twenty-odd rules, most of a minute of a core on the phone after every session. Each rule now runs
only on a line holding what it cannot match without: its keyword, the five separators of a MAC,
the four dashes of a GUID, a long enough hex or token run, the learned account or address text.
Lines with non-ASCII text still meet every case-insensitive rule. Over 895,000 lines of real
client logs, with the device's accounts and addresses learned, the output is identical and the
pass takes a twentieth of the time.
2026-10-10 19:00:33 -04:00
SG3xHERO 96d7c66535 Add Steam Controller support over Bluetooth LE (#404) 2026-10-10 20:53:07 +00:00
The412Banner 90690d1c5c Read the package catalogs from Droid-Deck/DroidDeck-Components (#544)
The Windows components catalog, the desktop and emulator packages, the Linux runtime and the
Steam seed now live on the organisation's components repository, mirrored and built there by
CI; the app reads the catalogs from its main and the files from its releases. The personal
winlator-contents mirror keeps serving older app versions and Bannerlator.
2026-10-10 16:52:33 -04:00
The412Banner abbcb8e3ad Games: old Games folders become entries, not Steam libraries (#542)
Games folders saved before the settings section went away were still
registered as Steam libraries on Automatic, with no way left to remove
them. Once, at app start and before any scan, each game such a folder
listed becomes an entry of its own, keeping everything keyed by its folder
(chosen exe, shortcut appid, name, Start in, launch options, art,
removal); store installs and steamapps are skipped. The folders stay bound
at their old guest paths, so no shortcut changes, and the saved roots are
cleared. A Games folder stays a library only when Steam installed a game
into it; the others leave the library list, and the runtime forgets them.
2026-10-10 16:19:17 -04:00
David Kubeša fe60b3c279 Add global manual landscape orientation setting (#441) 2026-10-10 16:07:12 -04:00
Kurt Himebauch c7455b74ff Merge rules (#540) 2026-10-10 19:13:01 +00:00
Ashish Ajin c875ceda4d Hide the touchpad cursor when switching to direct touch (#424) 2026-10-10 15:02:38 -04:00
The412Banner 666abd134f Windows components: a recommended component is listed once, not again under All (#537)
The full list left out only the 'installed for this game' rows, never the recommendations, so
every recommended component appeared twice (DirectX 9 on Final Fantasy Resonance, both rows
switched on).
2026-10-10 14:54:28 -04:00
Muaz Kadan c115916962 Read the phone's motion sensors only while Steam asks for them (#534)
perf: only read the phone's motion sensors when Steam wants them

The gyro and accelerometer ran at 4 ms for the whole session, even in games without gyro, costing about 6% of a core. Steam already tells the Deck pad when it wants motion (setting 48), so libfakeinput now passes that on and PadMotion follows it, with a short delay to ride out Steam's brief toggles.
2026-10-10 14:44:05 -04:00
0579e688ba fix: preserve keyboard input on composite devices (#435)
* fix: preserve keyboard input on composite devices

* Fix composite input merge noteDevice call

---------

Co-authored-by: Jammo <[email protected]>
Co-authored-by: xXJsonDeruloXx <[email protected]>
2026-10-10 14:40:53 -04:00
Muaz Kadan bc50de3b55 Fix CPU temperature showing 0°C in the performance overlay (#516)
Since the proot speed-up in #494, the overlay couldn't find the CPU sensor and showed 0°C. It shows the real temperature again.
2026-10-10 14:39:30 -04:00
ArthurandJames Yeung 6489232598 Fix NativeAOT GC region range defaults (#385)
Use the bare hex value accepted by older NativeAOT runtimes and CoreCLR. Cover the default and shared and per-game overrides.

Co-authored-by: James Yeung <[email protected]>
2026-10-10 14:38:47 -04:00
0x142857andxXJsonDeruloXx c23c436502 Controller: optional Select button that opens the Steam menu (#384)
* Controller: optional Select button that opens the Steam menu

* Controller: translate the Select-opens-Steam-menu option

* Controller: clearer wording for the Select-opens-Steam-menu option

* docs: evidence for the Select-opens-Steam-menu option

---------

Co-authored-by: xXJsonDeruloXx <[email protected]>
2026-10-10 14:38:07 -04:00
abduznik fad52ec125 Terminal: release createSubprocess's JNI local references, and the cwd chars against cwd (#527)
Fix JNI local reference leak in createSubprocess

The argv and envp loops took one local reference per element from
GetObjectArrayElement and never released it, so the references piled up
until the native call returned. ART aborts the process at 512 local
references ("local reference table overflow"), and both loops share the
table, so a long argument list plus a large environment could hit it.

Delete each element's local reference once its chars are copied and
released, after ReleaseStringUTFChars since the chars depend on the string.

Also release the cwd chars against cwd rather than cmd; the call passed
the wrong jstring.

Adds a host-side test that runs termux.c against a mock JNIEnv that counts
local references and checks release pairing. It needs a jni.h (JNI_INCLUDE,
JAVA_HOME or the NDK) and skips without one.

Fixes #507
2026-10-10 14:29:51 -04:00
Nicolás Gómez Solano d22e458d64 fix(audio): avoid InputStream.readAllBytes() for Android 12 compatibility (#531) 2026-10-10 14:29:46 -04:00
The412Banner 1b7cb4179d Windows components: leave out WebView2, which only Microsoft's installer can lay out (#532)
Its files sit in a container no extractor opens and may not be hosted, so a recording cannot
source them; installing it means running the installer in the prefix, which no runtime here
does. With it gone the waiting section is empty.
2026-10-10 14:03:04 -04:00
MaxsTechReviewandxXJsonDeruloXx c1c22dfd37 Launch the executable a Store package declares (#400)
Store and GDK folders name their game in MicrosoftGame.config or
appxmanifest.xml. Picking the top-level Unreal bootstrap instead failed
with "CreateProcess() returned 2" when the Store had renamed the
shipping exe.

Co-authored-by: xXJsonDeruloXx <[email protected]>
2026-10-10 13:46:03 -04:00
kmnkv1 0043cefab5 Rumble: don't restart the vibrator on every force-feedback packet (#514)
fix: stop restarting the vibrator on every force-feedback packet
2026-10-10 13:34:19 -04:00
kaosjammoandJammo 41f68ef1a1 Fix launcher fullscreen around display cutouts (#432)
Co-authored-by: Jammo <[email protected]>
2026-10-10 13:33:59 -04:00
The412Banner 9743ac3abc Windows components: leave out the OpenAL setup program, a twin of the DLL copy that installs here (#528) 2026-10-10 13:32:12 -04:00
SG3xHERO ca6cfcd193 Unfolded deck controls (#407) 2026-10-10 17:24:23 +00:00
Willie Yao d41424170a Controller editor: snap controls into line while dragging (#490) 2026-10-10 15:11:50 +00:00