Commit Graph
1614 Commits
Author SHA1 Message Date
FX192 29e8b2f679 Never delete the install record while replacing it and clean the staging folder if marking fails 2026-10-28 01:10:47 +03:00
FX192 e7907d0c74 Check itch updates per game from the game page instead of from the Library header 2026-10-28 01:08:33 +03:00
FX192 2cce33d6f8 Keep the install record out of update merges and drop update results that went stale mid-check 2026-10-27 14:53:06 +03:00
FX192 efaf5bf9b7 Make staging cleanup symlink-safe and drop update checks that outlive a sign-out 2026-10-27 14:43:13 +03:00
FX192 e34db5adcb Count an itch install without a game id as unanswered in the update pass 2026-10-27 14:41:38 +03:00
FX192 0a7397cd0e Fix the itch update cache reader for Kotlin 2.1 and keep symlinked staged entries out of the merge recursion 2026-10-27 14:25:42 +03:00
FX192 c90ad997b1 Unpack itch updates into a staging folder before touching the game 2026-10-27 14:00:29 +03:00
FX192 8a16bd3b3b Detect itch.io updates and offer to install them
Installed itch games are compared with the uploads itch lists for them. A game with a newer upload shows an Update label in the Library and an Update button on its page, a replaced build asks first, and a Check for updates button in the itch Library header runs the check on demand.
2026-10-27 13:53:35 +03:00
The412Banner 43a0ce93f9 fix: Frame Limit sync and refresh follow on a still screen (review follow-ups) (#1663)
The Steam helper checked the Frame Limit only when the offered frame
rates changed. With the limit off during a refresh change, turning it
back on left a value the new rate does not offer, and a failed write was
not tried again. It now checks on every state change and every 5 s, and
waits for Steam's settings write so a rejected write is caught and tried
again on the next check.

gamescope 3.16.29-p16 (0120 changed): gamescope took a new host refresh
only from the presentation feedback of a frame it drew, so with nothing
moving on screen it kept the old rate. It now presents once when the
host's wl_output mode changes and keeps presenting while a new rate is
pending, so the 300 ms check runs on a still screen too.

Found by CodeRabbit in the reviews of #1650 and #1663.
2026-10-27 05:08:21 -04:00
Kurt Himebauch 07a0a7e344 fix: show gesture settings only in gesture mode (#1654) 2026-10-27 00:23:44 -04:00
maxjivi05 c25d54aced fix: leave published component choices alone when state.json cannot be read 2026-10-27 00:07:45 -04:00
maxjivi05 c781cfd525 fix: publish component choices again when a new Proton build appears
Game and global component choices were written to desired.tsv only when a
selection changed, so a Proton build installed later (DroidDeck-Proton
11-11.8) had no rows and kept its bundled FEX. Battle.net's d2rfix FEX never
reached it and StarCraft died in ClientSdk.dll's DllMain. The choices are now
republished at session start and on Battle.net's FEX request whenever the
installed tools no longer match what was published.
2026-10-27 00:07:45 -04:00
The412Banner 4c7e59ed8b feat: Steam's Frame Limit decides; gamescope and the limit follow the refresh rate (#1650)
Remove the Performance mode switch. The session always runs the way
Performance mode did: replaced buffers go back to the game at once
(except while mirroring to glasses), gamescope's WSI layer and winex11
reuse their per-present window checks, and games get eight swapchain
images while uncapped. Steam's Frame Limit in the Quick Access menu is
the only limit.

gamescope 3.16.29-p15 (p14 plus two patches):
- 0119: with the Frame Limit on, gamescope forces FIFO while the WSI
  layer hands the driver MAILBOX, so a game with eight images could
  queue up to seven frames ahead of the screen. While the limiter forces
  FIFO the layer uses its default of 3 images; DXVK and VKD3D-Proton
  recreate their swapchain when the limiter changes, other apps are asked
  to with VK_SUBOPTIMAL_KHR.
- 0120: -r fixed gamescope's pacing and limiter rate for the whole
  session. With GAMESCOPE_NESTED_REFRESH_FOLLOWS_HOST=1 a rate the host
  has reported for 300 ms replaces it (a switch from 144 to 120 Hz passes
  through 72 Hz for a few frames), and Steam gets the display information
  again. The session sets it whenever it passes -r.

Steam keeps its Frame Limit as the client setting
gamescope_app_target_framerate and offers the values gamescope's display
state lists. After a refresh change, a limit the new rate does not offer
(72 at 120 Hz) left the slider on its first value while the game kept the
old limit. The Steam helper watches the offered values and, once they
settle, keeps the limit when it is still offered and moves it to the
highest value otherwise, through Steam's own setting so the slider shows
it. Steam's webpack does not expose its module cache, so the gamescope
service is found by the calls its module makes, and the helper retries
the install every 10 s until Steam is ready.

The session window asks for the fastest mode the peak refresh setting
allows and chose again only when the display changed, so after it had
asked for 60 Hz, raising Android's refresh setting left the display,
gamescope and the limit at 60. It now also chooses again when
peak_refresh_rate or min_refresh_rate changes.
2026-10-26 23:17:35 -04:00
Kurt Himebauch 0e9a31ccfe feat: trust contributors for test builds (#1646)
* feat: trust contributors for test builds

* fix: restrict trusted list changes

* fix: retain same-repository test signing

* fix: publish completed fork builds

* feat: trust K11MCH1 test builds

* fix: recognize maintain collaborator role
2026-10-26 22:54:57 -04:00
Kurt Himebauch 8749154cbf fix(input): keep AYN system key out of Home shortcuts (#1643) 2026-10-26 21:11:46 -04:00
maxjivi05 bb9a64fa5f Reconfigure the app decoder when the capture layout changes
A capture format or buffer change now closes the app's decoder so the
next packet reopens it with the new stride and height, and a capture
slot whose remap fails no longer keeps its old mapping.
2026-10-26 20:36:24 -04:00
maxjivi05 916a39585f Decode Remote Play streams on the arm64 Steam client
Steam's arm64 streaming_client only decodes through a V4L2 stateful
decoder and libdrm dumb buffers, neither of which exist on Android, so
streams from a PC never showed a picture. The preload now offers it a
/dev/video-dec0 and a libdrm stand-in backed by dma-heap buffers, and
each frame is decoded by the app's MediaCodec (Qualcomm low-latency
mode) over the encoder socket, falling back to the FFmpeg in Steam's
runtime.
2026-10-26 20:36:24 -04:00
maxjivi05 9555cb9f65 fix(skate.): run ReSkate at D3D12 feature level 12_1
skate. under ReSkate crashed with an access violation in Skate.exe 12 to
60 seconds after it started at the default feature level 12_2; at 12_1
it loads San Vansterdam and plays. The rule matches Skate.exe with
ReSkate.dll beside it, so it covers ReSkate started from skate.'s own
Steam entry and as a non-Steam game, and a game profile can still set
another level.
2026-10-26 20:35:59 -04:00
maxjivi05 70d8fc6559 Hand a profile's WINE_CPU_TOPOLOGY to Proton as well 2026-10-26 18:31:11 -04:00
maxjivi05 70c512693a Set PROTON_CPU_TOPOLOGY too so Proton's per-game CPU list doesn't replace it
Proton sets WINE_CPU_TOPOLOGY from its own default_cpu_limit for games
like Prototype (8 cores) unless PROTON_CPU_TOPOLOGY is set, so the
pinned topology never reached the game the issue was about.
2026-10-26 18:31:11 -04:00
maxjivi05 43266b2923 Keep an empty WINE_CPU_TOPOLOGY from a game profile 2026-10-26 18:31:11 -04:00
maxjivi05 9d85af7558 fix(proton): Windows games see only the cores they are pinned to
Game cores pinned the game with taskset, but Wine counts the online
CPUs, so a game held to two cores still saw eight processors and sized
its thread pools for them. Prototype freezes at its splash screen that
way. When the session or a game profile limits the game cores, Wine now
gets WINE_CPU_TOPOLOGY for exactly those cores unless the profile sets
its own.
2026-10-26 18:31:11 -04:00
FX1922andmaxjivi05 d905f03bf7 feat(itch): collections filter in the Library (#1597)
* Add itch.io collections to the Library

A Collections button on the Library's itch tab filters the library to one collection of the signed-in account. Its games that are not installed show in the Not installed section.

* Keep itch collections complete across failures, sign-out and empty libraries

A failed later page no longer publishes a partial collection, selecting a collection refreshes it, pagination runs until an empty page, signing out clears collection state, and the itch chip shows for a signed-in account with no owned games.

* Tie itch collection requests to the account that started them

Requests capture the account generation before reading the key and dedupe per generation, sign-out clears collections after the token is removed, and the collections load follows the itch sign-in state.

* Keep paging itch collections past a page of already seen games

* Run the itch collections tests under Robolectric like the other itch tests

* Let the Installed filter apply inside a collection and keep the grid for an empty itch account

* fix(itch): stop paging a collection when a page adds no new games

* Keep the collections icon on the itch collections tab when it opens

---------

Co-authored-by: maxjivi05 <maxjividen@gmail.com>
2026-10-26 18:15:24 -04:00
Kurt Himebauch f13916ee25 feat(steam): optional Steam integration setup (#1637)
* feat(steam): add optional device integration setup

* feat(steam): show integration setup as inline settings rows

* fix(steam): offer App info when shortcuts stay blocked
2026-10-26 17:51:44 -04:00
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
maxjivi05 aa17b0553d fix(input): end the forwarded touchpad finger when the Steam menu opens 2026-10-26 15:52:02 -04:00
maxjivi05 46076e165b fix(input): let on-screen controls work while the touchpad finger is down
The game surface only took touches in gestures mode, so in touchpad and
direct mode a finger on the game left the window with no touch target and
Android sent every later finger to the touchpad, even over a stick or
button. The surface now owns those fingers in every mode, and the
on-screen and Steam touch controls hand fingers that miss a control back
to the touchpad instead of dropping them.
2026-10-26 15:52:02 -04:00
Kurt Himebauch 2d8957a401 feat(launch): show compatibility install progress (#1629) 2026-10-26 15:41:46 -04:00
Kurt Himebauch b3561bf658 fix(input): discard queued chords on disconnect (#1632) 2026-10-26 15:31:51 -04:00
Kurt Himebauch 13eb291ba8 fix(input): handle immediate Back chords and tap timing (#1628)
* feat(input): support instant Back chords and tap timing

* fix(input): send QAM before shortcut inputs

* fix(input): stop delayed stick input on Back release
2026-10-26 15:04:55 -04:00
Kurt Himebauch c8f650e167 feat(ui): add game resource links (#1630) 2026-10-26 14:53:21 -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 8df90c30dd fix(fex): read the fallback FEX version from droiddeck-fex-update
The pin moved there from droiddeck-steam-x64, so the client settings sheet
and its test read it from the new script. The x86-64 client notes now name
the updater and Components' FEX watcher.
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 bb1cbf95c0 docs: credit sharun and userland-execve 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 749ade4a45 fix(input): delay held QAM to 700 ms 2026-10-26 13:20:51 -04:00
Kurt Himebauch fa5506df35 fix(steam): preserve Back taps and recover QAM controls 2026-10-26 13:13:08 -04:00
Kurt Himebauch dde1a55d00 feat(input): pass held Back through as Steam QAM 2026-10-26 12:49:51 -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 da127d1b4c fix: delay client compression until game focus (#1406) 2026-10-26 12:12:04 -04:00