Commit Graph
511 Commits
Author SHA1 Message Date
Kurt Himebauch 73daaf7adc fix(gamescope): keep Fill scaling and magnification visible (#1634)
* fix(gamescope): preserve signed plane positions

* fix(gamescope): pin validated scaling component
2026-10-26 16:06:40 -04:00
The412Banner 830c753312 fix: turn off D3DGear's capture hook when it sits beside a game (#1627)
The Crew 2 loads D3DGear64.dll from its folder. Its DXGI Present hook
faults over a thousand times within seconds under Wine and the game
never presents again: black screen while the sound keeps playing.
droiddeck-game-env now disables the DLL when it finds it beside the
game, and DLL overrides from several engine fixes are kept together
instead of the last one replacing the others.
2026-10-26 18:07:15 +00:00
Kurt Himebauch a0a68f7280 feat(steam): sync QAM controls and pass held Back shortcuts (#1621)
Steam's native QAM sliders now control Android brightness and media
volume, with device changes reflected back in Steam. Holding Android
Back for 700 ms sends a real held QAM button for Steam shortcuts. Single
and double taps keep the existing menu/QAM order and swap setting; the
double-tap window remains 500 ms.

- Discover native brightness through a guest backlight descriptor and
use Android's Modify system settings permission. Retain the latest
pending request until permission is granted or the session stops, with a
notification action for hidden sessions.
- Give DirectAudio and fallback AAudio sinks Android media volume/mute
callbacks, keeping software gain at unity. Recover when initial volume
state is absent or invalid, brightness acknowledgements differ or never
arrive, or the Display bridge is not ready yet.
- Forward other buttons while QAM is held in Steam Deck and Steam
Controller modes. Consume release after a hold and clear pending input
on overlays, focus loss, pause, disconnect, and teardown. The session
menu retains its compact Back choice without an explanatory paragraph.

Validation:
- Local ARM64 release build passed. The latest timing change passed 20
targeted input tests, including release at 600 ms remaining a tap. The
preceding full feature check passed 61 Android input/device-control
tests, with permission cases on API 28 and 33.
- 66 Linux Python/Node/C tests passed for device controls, audio
recovery, Steam compatibility, and file dialogs. Both audio sink modules
rebuilt with Android NDK 27.2.
- Release-signed integration build 14d12cf0 is installed on the unrooted
AYN Thor, carrying the Android/input changes through 749ade4a plus the
existing portrait changes. Device checks confirmed the configured
QAM/menu tap order, Back dismissal, removal of the inline menu
description, and held QAM overlapping X with clean release. Hands-on
testing confirmed this installed build works.
- Earlier Thor testing covered brightness permission and pending
requests, brightness synchronization in both directions, native volume
changes, hardware volume key readback, and both sink backends. Failure
recovery is covered by the automated tests above.

The subsequent queued-notification fix in 4d7ceb23 is covered by the
Linux regression suite and has not replaced the Thor install.

Bluetooth/wired output switching and other device models remain
untested. CI and CodeRabbit monitoring continue against the pushed head.
2026-10-26 13:46:14 -04:00
maxjivi05 455bf0fba9 fix(fex): install DroidDeck's FEX build again when it no longer loads
A tag that matches no longer vouches for the build: FEX and FEXServer must
also load (ld.so --list), otherwise the session reinstalls it and x86
programs use the Steam or system FEX meanwhile.
2026-10-26 13:40:36 -04:00
maxjivi05 4de4c65c2a fix: wait before retrying a FEX build that did not install
A failed catalog install is retried after an hour or when the session names
another build, a missing updater falls back to the FEX already here, and the
archive download gives up on a stalled connection.
2026-10-26 13:40:36 -04:00
maxjivi05 7e2d13b641 fix(fex): x86 programs use DroidDeck's own FEX build, kept to the catalog's version 2026-10-26 13:40:36 -04:00
maxjivi05 5bdf0d6b04 fix(fex): report the x86 platform under AT_PLATFORM 2026-10-26 13:40:36 -04:00
maxjivi05 13493d44c3 fix: keep Sentry for Godot games that are not .NET
The Sentry GDExtension was turned off for every Godot game that ships it,
because its crash handler takes the .NET runtime down under FEX. GDScript
games such as Pathogenic call SentrySDK from their scripts, so without the
extension their autoloads fail to parse and the game quits. Only Godot .NET
builds have it turned off now.
2026-10-26 13:27:59 -04:00
Kurt Himebauch 4d7ceb2325 fix(steam): drain queued control notifications 2026-10-26 13:27:03 -04:00
maxjivi05 a984d11742 fix: run Xbox games from a short drive letter
The launch view lives under the app's files folder, so games saw an
install path like Z:\data\user\0\com.droiddeck.launcher\files\xbox-runtime
\views\launch-<n>\droiddeck-xbox-<id>. Forza Horizon checks that length and
quits with "Installation path is too long". The view is now mapped to a
free drive letter in the prefix (X: first) for the length of the launch.
2026-10-26 13:21:31 -04:00
Kurt Himebauch fa5506df35 fix(steam): preserve Back taps and recover QAM controls 2026-10-26 13:13:08 -04:00
maxjivi05 c446566f42 fix: hold a setup lock instead of guessing from running processes 2026-10-26 12:47:00 -04:00
maxjivi05 2e2b950964 fix: Flatpak setup clears a package lock left by an interrupted run 2026-10-26 12:47:00 -04:00
Kurt Himebauch 53d643dd00 fix(audio): clear volume bridge during sink teardown 2026-10-26 12:34:31 -04:00
Kurt Himebauch 6a5dfe1486 feat(steam): sync QAM brightness and volume with Android 2026-10-26 12:32:36 -04:00
Kurt Himebauch d08afbd878 fix: restart compression delay for new games 2026-10-26 11:55:01 -04:00
Kurt Himebauch 36135327f5 fix: resolve zram focus conflicts 2026-10-26 11:45:17 -04:00
0x1Nawaf d65912f0c5 fix: stop starting a session on the slow proot (#1395) 2026-10-26 11:41:18 -04:00
Kurt Himebauch 5d945d7784 refactor: remove duplicate session frame limiter (#1616) 2026-10-26 11:25:31 -04:00
The412Banner 1b3814a587 Hold games to the frame limit in Performance mode (#1609)
A frame limit only paced what reached the screen: a game without vsync
kept drawing hundreds of frames a second that were thrown away (AIO at
a 60 fps limit drew 155 to 2,446 fps), so the limit saved no power.

With Performance mode on and a frame limit set, the session now sets
gamescope's per-game limit over gamescope_control (gamescopectl
debug_set_fps_limit). gamescope's limiter then has its WSI layer hold
Vulkan games, DXVK and VKD3D included, to the limit. gamescope's own
--framerate-limit option is reset on its first frame in 3.16.29, and
Steam resets the per-game limit while it starts, so the session watches
gamescope's limiter state file and sets the limit again whenever it is
off (a once-a-second check with shell builtins, no process started).
With Performance mode off, a limit paces the screen only, as before.

The session also gives gamescope a fixed limiter state file path, so
gamescope stops leaving a new one behind on every start, and removes
the old ones.

Device-proven on the AYANEO Pocket FIT (Turnip, AIO D3D11, 45 s runs on
battery, three runs each): at a 60 fps limit the game held exactly
60.0 fps and the device drew 7.08 W instead of 9.45 W, with 1.3 instead
of 2.6 busy cores and 5 instead of 11 % GPU load. No limit: unchanged.
2026-10-26 09:16:05 -04:00
maxjivi05 24f0b97c08 fix: report a gamescope that cannot start and ignore Agent answers that are not objects 2026-10-26 09:01:02 -04:00
maxjivi05 3b6b304f55 fix: take the Agent's empty answer for an uninstalled game as gone
Once Blizzard's Agent has removed a game it answers GET /game/<uid> with
an empty object, not installed false, so a finished uninstall read as a
failure and opened Battle.net.
2026-10-26 09:01:02 -04:00
maxjivi05 c48297e0d1 fix: wait for a cancelled Battle.net job before removing it, and bound uninstall waits
A cancelled install now waits for its Agent job to end before the
uninstall runs, and removes the folder only once the Agent no longer
lists the game or the folder is empty. Uninstall gives up when Battle.net
or a game keeps the prefix busy for a minute, so the page falls back to
opening Battle.net. An uninstall only counts when the Agent reports the
game as not installed.
2026-10-26 09:01:02 -04:00
maxjivi05 b887e8653d feat: install Battle.net games from Stores with downloads, updates and uninstall
Battle.net games now install like Epic, Xbox and itch games: Install,
pick a location, and the download runs in the Downloads tab while the
Stores page stays open. droiddeck-battlenet starts Blizzard's own Agent
on its own under a headless gamescope and drives its local API, so no
window opens and nothing waits on the Battle.net client.

- Progress, speed and time left come from the Agent, with pause, resume
  (the Agent keeps what it downloaded) and cancel, which uninstalls the
  partial game and removes its folder.
- A job only finishes once the Agent has really run it and the game is
  playable; the first status after a request can still describe the
  previous operation.
- Installed games check Blizzard's version service and show Update when
  the build on disk is behind; the update repairs missing files too.
- Battle.net games can be uninstalled from their page through the Agent.
- Games land in the chosen location: internal storage, other storage or
  a Games folder.
- The hero keeps its action row clear of the playtime column.
2026-10-26 09:01:02 -04:00
MaxsTechReview c71ba6da96 Run desktop games on the GPU in a window (#1584)
Steam games and Battle.net started from the KDE desktop run on the GPU in gamescope, opened as a KDE window, and Plasma no longer leaves programs with a zero realtime CPU limit that got games killed.
2026-10-25 21:09:24 -04:00
Thomas Lee 4922d309c8 perf: allocate only solved DD-FG flow levels (#1556)
The flow solver starts at flowFinest_, but its images, uniform buffers and descriptor sets were allocated for every pyramid level. Keep the seven-level indices and allocate flow resources only where the solver reads and writes them.

The default preset avoids three unused RGBA16F images, saving 38,707,200 bytes of pixel payload at 2560x1440 without changing the shaders or recorded GPU work. Add native allocation/dispatch regressions and document the resource budgets.
2026-10-25 19:21:40 -04:00
Kurt Himebauch 8cf2ffe2ad fix: say why Flatpak setup failed instead of blaming the mirrors (#1580) 2026-10-25 18:05:41 -04:00
Kurt Himebauch 65bacc067b fix: extract GOG installer fallback natively on ARM (#1174) 2026-10-25 17:56:35 -04:00
b4b7883648 fix: Reuse the prefix the client made for a shortcut id (#1107)
* fix: Reuse the prefix the client made for a shortcut id

droiddeck-proton-run builds the prefix path as steamapps/compatdata/<appid>,
but the client names that folder with the signed 32-bit form of the shortcut
id. A shortcut whose id has the top bit set therefore got a second, empty
prefix, and the first launch after that ran wineboot from scratch: the
session sat on a black screen for the length of a full prefix init, and the
old prefix was never reused.

Match the folder by its unsigned value instead, the way the client does:
int(name) % 2 ** 32 == appid % 2 ** 32. prefix_of() also accepts a negative
folder name now, and reports its unsigned id so the Steam environment it sets
up stays valid.

* fix: Reject folder names int() cannot read, and skip files

lstrip("-").isdigit() accepts "--1" and superscript digits, which int() then
raises on, and one such entry in compatdata would stop shortcut resolution.
Match r"-?[0-9]+" instead. A matching name is also only used when it is a
directory, so a stray file cannot take STEAM_COMPAT_DATA_PATH.

* fix: reuse signed shortcut compatdata prefix

* fix: prefer initialized Proton shortcut prefixes

---------

Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com>
Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
2026-10-25 17:49:58 -04:00
Kurt Himebauch 815b93db5f feat: profile PRoot costs and test fast-path libraries without an APK rebuild (#1528) 2026-10-25 16:49:35 -04:00
MaxsTechReview aca4b5dd3e Start World of Warcraft on DirectX 11 by default (#1576) 2026-10-25 16:41:41 -04:00
Kurt Himebauch 8d858b4334 feat: pick a game's CPU cores in its game profile (#1566)
* feat: pick a game's CPU cores in its game profile

* fix: match per-game cores against the online CPU list
2026-10-25 16:38:11 -04:00
The412Banner 38926b3157 feat: Performance mode puts frame pacing and per-frame window-check fixes behind one switch (#1563)
Adds a Performance mode switch under Mode settings > Frame rate, off by default and stored per mode like the frame limit. Off keeps today's behaviour. On:

- with no frame limit, the compositor hands buffers back to the game as soon as they are replaced instead of once per refresh, and gamescope's WSI layer is asked for at least 8 swapchain images; a chosen frame limit still paces
- DROIDDECK_WSI_BYPASS_CHECK_MS=100 lets gamescope's WSI layer reuse its present-time Xwayland bypass check (patch 0117, gamescope-3.16.29-p13); WINE_OFFSCREEN_CHECK_MS=100 does the same for winex11 once a DroidDeck-Proton release carries that fix. Off sets both to 0.

The gamescope pack now ships the patched WSI layer and SessionFiles stages it over the runtime's stock copy. Two per-game options, off by default: PROTON_DXVK_D3D8 and WINE_D3D_CONFIG renderer=vulkan|gl.

AIO Graphics Test on an AYANEO Pocket FIT (Adreno 750), off -> on: Vulkan 204 -> 1787, OpenGL 296 -> 2169, D3D12 308 -> 3563, D3D11 1133 -> 2874, D3D9 1253 -> 3098 fps; DiRT Showdown 92.2 -> 93.4 (GPU-bound).
2026-10-25 20:29:26 +00:00
Kurt Himebauch 9593529197 feat: a setting to keep Steam uncompressed while games run (#1565)
* feat: a setting to keep Steam uncompressed while games run

* fix: say that the RAM cap still compresses Steam when this is off
2026-10-25 13:20:33 -04:00
MaxsTechReview 27e390a846 fix: StarCraft starts its 32-bit client from Battle.net (#1564) 2026-10-25 13:10:28 -04:00
Charles DuBose c4df7e9b3d feat: Battle.net on the desktop with its games and store, plus memory options (#979) 2026-10-25 12:49:27 -04:00
597402107d [FIX] statx call on old kernels < 4.11 (#947)
* [FIX]
Fix git statx call on old kernels < 4.11 for correct using of "Fast proot path"

Issue
https://github.com/Droid-Deck/DroidDeck/issues/770

* [FIX]
fix: don't call major() from the proot fast path

* fix: preserve statx fallback request semantics

* fix statx fallback argument handling

* fix: silence statx null check warning

---------

Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com>
Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
2026-10-25 12:42:51 -04:00
Kurt Himebauch 10fe5c5f77 feat: stretch 16:9 games to screens wider than 16:9 too (#1558)
* feat: stretch 16:9 games to screens wider than 16:9 too

* fix: don't offer 16:9 game fit while the session follows the screen
2026-10-25 12:37:47 -04:00
Kurt Himebauch 7d99a24ad5 fix: find the arm64 reaper under XDG_DATA_HOME and serve queued file dialog requests at once (#1560) 2026-10-25 12:27:42 -04:00
Kurt Himebauch 8658ffff90 fix: Steam's Browse buttons open the file chooser with the x86-64 client too (#1557) 2026-10-25 12:08:12 -04:00
angelrenefm 86ecb716eb fix(build): build the local image when Podman reports it missing (#1527) 2026-10-25 12:08:08 -04:00
Jamison Prineandjazzyjames 2be08bc67d feat: adjustable RAM and VRAM caps for the container (#1537)
* feat: adjustable RAM and VRAM caps for the container

Performance > Memory gets two sliders:

- RAM cap (soft, Steam sessions): when the session is resident above the
  cap, the session watcher compresses the Steam client into zRAM, waits for
  its page-out acknowledgment, then compresses the rest of the session
  (processes that loaded libblsession) if still over. Nothing is closed.
  Measured at most every 30 s; the client is read back once usage drops
  below the cap. Invalid values leave the cap off. Needs zRAM swap.
- VRAM cap: sets dxgi.maxDeviceMemory ahead of the game's own DXVK_CONFIG,
  so Direct3D games budget for less video memory. A game profile still
  wins. Applies from the next session.

* fix: back off the RAM cap when paging out cannot get under it

A cap below the game's working set was never met, so the watcher paged out
the client and the whole session every 30 s for the rest of the session.
Usage is still measured every 30 s, but after a page-out that leaves the
session over the cap the next one waits twice as long (60 s up to 10 min),
resetting once usage is under the cap. The client step is skipped while the
client is already under 512 MB resident.

* fix: RAM cap covers desktop Steam, signals each group once, no idle churn

- Steam opened from the desktop runs the same session watcher, so the cap
  is exported whenever the Steam client runs, not only in Steam mode.
- The second page-out goes to the rest of the session only; Steam was
  signalled again even when its own step had been skipped as already small.
- A cap page-out while no game runs stays paged out. Reading the client back
  right away pushed it over the cap again and repeated every minute; only a
  game closing while over the cap still defers a read-back.

* fix: RAM cap marks the client packed only when it compressed it

When the cap skipped the client as already small during a game, it still
recorded the client as packed, so the regular in-game client page-out
waited up to 300 s for a page-out that never happened.

---------

Co-authored-by: jazzyjames <182448902+jazzyjamesgames@users.noreply.github.com>
2026-10-25 12:06:45 -04:00
Kurt Himebauch dfe8227f49 fix: run RoboCop: Rogue City at D3D12 feature level 12_1 (#1553) 2026-10-25 11:58:38 -04:00
Kurt Himebauch 9cecd528e8 fix: Start without Steam uses the launch options set in Steam's Properties (#1552)
* fix: Start without Steam uses the launch options set in Steam's Properties

* fix: treat a malformed shortcuts.vdf as having no launch options
2026-10-25 11:50:44 -04:00
MaxsTechReview c9565bc0b9 Skip umu-protonfixes for Black Ops III and Dark Souls Remastered (#1508)
GE-based Protons, the default with the x86-64 Steam client, run umu-protonfixes. Its Black Ops III fix switches the prefix to Wine's ALSA driver, which has no device here and replaces DirectAudio, and its Dark Souls Remastered fix runs the VC++ 2017 installer, which fails under ARM64 Proton.
2026-10-25 11:28:28 -04:00
MaxsTechReview 3fdc74051c feat: DroidDeck-Proton is downloaded, kept up to date and used by default (#1540) 2026-10-25 10:09:22 -04:00
Kurt Himebauch 0cf5b42788 Add an in-session microphone toggle (#1506) 2026-10-25 08:37:49 -04:00
0x1Nawaf aa1a8da39a merge: with main branch 2026-10-25 10:38:42 +00:00
0x1Nawaf 73e158ab3b fix: compress only while the running game is focused 2026-10-25 10:38:37 +00:00
The412Banner c5d7cdc058 Xbox Cloud Gaming: stream from the store and Games tab, native player with DroidDeck frame generation (#1531)
Xbox Cloud Gaming: stream from the store and Games tab, native player with DroidDeck frame generation

Stream Xbox games with Xbox Cloud Gaming (Game Pass) from DroidDeck, outside
the Linux session.

- Backend: `xodus-cli cloud-token` (tools/xbox/droiddeck-cloud-token.patch)
  gets the streaming tokens; they stay in memory.
- Web player (default): the Greenlight player page (tools/xcloud-player, MIT)
  in a WebView, plus Microsoft's own xbox.com/play player. In-stream menu with
  screen effects (sharpen, colour, deband, FXAA, CRT, NTSC, Toon, fps cap),
  stream quality, performance overlay (level, layout, top right / top left)
  and rumble.
- Native player (opt-in, Android 10+, Player engine: Native): Google's WebRTC
  (io.github.webrtc-sdk 125.6422.07, BSD) with the Greenlight protocol ported
  to Kotlin, in its own process (:xcloudnative) with its own instance of
  DroidDeck's compositor. Decoded frames reach the compositor as
  AHardwareBuffers (new stream mode, VK_ANDROID_external_memory_android_
  hardware_buffer import), so DDFG 2x and LSFG 2x/3x/4x run on them. Live
  frame generation, frame-rate target (presets and a 10-165 fps slider, even
  pacing), zero-copy picture, small network buffer, fast decoder, instant
  controller input, overlay with engine and on-screen fps, background end,
  restart and web fallback. It takes the main process's tokens through
  XboxCloudTokenService; they are fetched ahead while a cloud game is shown.
- The compositor requests the dma-buf import extensions only where the driver
  has them (the system driver has none).
- Catalog: cloud availability, Game Pass plan CFQ7TTC0K6L8 counted, library
  filter All / Owned / Game Pass / Cloud, Stream and Add to Games on the store
  page, stream-only Games-tab entries (Stream + Download / Play + Stream).
- Xbox games get VC++ 2015-2022 and the ARM64 runtime registry entries
  (vcredist2022_arm64, built in until the catalog has it) before each launch.
- Controller focus reaches pickers opened from a game page (install location,
  uninstall); Add / Remove from Games keep the focus.

Credits: Greenlight by UnknownSKL (Jim Kroon), MIT, player and protocol;
Better xCloud for the resolution / OS mapping; MGamer404's Bannerlator #627
for the ARM64 runtime approach. Ported from the412banner's Bannerlator.
2026-10-24 23:17:57 -04:00