Commit Graph
1495 Commits
Author SHA1 Message Date
0de672f94e fix: a Linux runtime update keeps imported apps and catalog AppImages (#1062)
* fix: a Linux runtime update keeps imported apps and catalog AppImages

The update carried only /root into the new tree and then discarded the
old one, so every imported AppImage, script app, Flatpak override and
catalog emulator AppImage was deleted. User-owned paths are now moved
across as a list, moved back if the carry or swap fails partway, and
recovered after an interrupted update.

* fix(runtime): retain user data when carry and recovery fail

* fix(runtime): mark staging carry start so interrupted extraction is discardable

* test: mark interrupted runtime data for recovery

* fix: make runtime data carry recoverable

* fix: the runtime update with carried user data builds again

carryUserData passed the de-duplicated Set of user paths where a List is expected after the two carry changes met; copy it into a List.

* fix: a runtime update stops instead of dropping app markers it cannot inspect, and keeps app names with line breaks

userPaths now uses the throwing exists() helper for the AppImage, menu entry and marker checks. The carry marker stores each path URL-encoded on its own line, so a name containing a newline cannot split into two paths. The symlink test now links a parent directory, which is what safePath rejects.

* fix: retain conflicting runtime recovery data on every retry

Stop on unreadable carry markers and keep rollback tests independent of add-on downloads.

---------

Co-authored-by: ovurrsl <ovurrsl@users.noreply.github.com>
Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com>
Co-authored-by: Kurt Himebauch <136133082+xXJSONDeruloXx@users.noreply.github.com>
2026-10-25 12:57:04 -04:00
Kurt Himebauch 0ad4b7cc14 feat: Back in the file manager returns to the folder you came from (#1562)
* feat: Back in the file manager returns to the folder you came from

* fix: the file manager's up arrow closes favorites first, as before
2026-10-25 12:55:11 -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
Kurt Himebauch 6918fd9308 feat: install the redists a Steam game's install script runs on Windows (#1561)
* feat: install the redists a Steam game's install script runs on Windows

* fix: rescan a game's components when its install script changes
2026-10-25 12:44:35 -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
FX1922 411fda343a itch.io: version picker and installing free games (#1503)
* itch.io: temporary Test itch.io button that logs what the API answers (not for merge)

* itch.io: show Test itch.io only while Debugging tools is on

* itch.io: version picker and installing free games

* itch.io: build the platform names outside joinToString so the composable call compiles

* itch.io: ask for the version before resuming an unfinished install

* itch.io: keep the chosen upload, save free games in the queue, don't auto-install a closed picker

* itch.io: install straight away when exactly one build is installable

* itch.io: show the picker again unless the game has exactly one build

* itch.io: ignore a second build tap while the picker is closing

* itch.io: empty a partial install before extracting so builds never mix

* stores: deleteTree removes a symlink without following it

* stores: skip symlinked folders in the uninstall walk, and only empty a partial install that is this game's own
2026-10-25 12:37:04 -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
informalTechCode b1c70f5f81 Add Rokid Max 2 support using its verified USB identity (#1535)
Add Rokid Max 2 USB recognition and validated Max support
2026-10-25 12:07:47 -04:00
VIIII4andVIIII4 c6bc8aef04 Add an optional HTTP proxy for downloads (#1474)
* Add an optional HTTP proxy for downloads

Downloads only reached GitHub directly or through URL-rewrite
mirrors, which does not help where a local proxy is the workable
route. Setup now takes a host:port HTTP proxy that every Downloader
connection uses, independently of the download source mode.

* Reference the Kotlin object instance from Java

Java cannot call a Kotlin object member on the class name without
@JvmStatic; the surrounding code already uses INSTANCE.

* Assert the proxy host literal without a reverse lookup

InetSocketAddress.getHostName reverse-resolves on some JVMs
(127.0.0.1 became localhost on CI); hostString is the literal.

* Pass the app proxy into the guest environment

The Steam client installer and the guest package tools fetch with
plain curl against their own CDNs, outside Downloader. Export the
usual proxy variables for them when the app proxy is set; proot
shares the host network, so a localhost proxy is reachable as-is.

---------

Co-authored-by: VIIII4 <VIIII4@users.noreply.github.com>
2026-10-25 12:07:26 -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 3995fe3829 fix: install XACT audio with Skyrim so its voice lines play (#1554)
* fix: install XACT audio with Skyrim so its voice lines play

* fix: rescan cached component findings when the detectors change
2026-10-25 11:50:47 -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
Kurt Himebauch 709c041b24 perf: pause the home page's ambient motion after 20 s without input (#1550)
* perf: pause the home page's ambient motion after 20 s without input

* fix: restart the idle timer when a touch gesture ends
2026-10-25 11:41:39 -04:00
Kurt Himebauch e62698e395 fix: show when non-Steam games were last played, from Steam's shortcuts (#1551) 2026-10-25 11:33:24 -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 a7753a667c fix: Flatpak apps see the device's network, so WebRTC streams connect (#1548) 2026-10-25 11:28:25 -04:00
maxjivi05 6ef2bcc9c5 docs: Star History rank badge above the awards 2026-10-25 10:24:48 -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 2a69505199 feat: merge Games and store libraries into one Library and one game page (#1460) 2026-10-25 08:39:56 -04:00
Kurt Himebauch 0cf5b42788 Add an in-session microphone toggle (#1506) 2026-10-25 08:37:49 -04:00
diegodru 1f42f512e2 fix: GOG sign-in pages use the browser's own user agent (#1500)
The GOG sign-in WebView sent GOG Galaxy's Windows user agent while the page's scripts and client hints report an Android WebView, so Cloudflare's check on gog.com never passed (#1486). The sign-in flow now uses the WebView's own Chrome user agent, like the Epic, Google, Facebook and Apple sign-ins. API calls outside the WebView keep the Galaxy user agent.

Fixes #1486
2026-10-25 00:06:54 -04: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
The412BannerandKeegantheVeganat0r 5ca1f610ab Xbox: fix sign-in on phones with a slow StrongBox Keystore (#1521)
On some phones (tester: Honor BKQ-N49, Android 17) Xbox sign-in stopped with
"the Xbox helper stopped with exit code 1" before Microsoft's page opened.
The backend asks the app to read and save credentials over a socket and waits
10 s for each reply. The app sealed credentials with a StrongBox-backed
Keystore key, and each StrongBox operation took 7-15 s on that phone, so the
backend gave up. The app still finished those saves afterwards, leaving a
record without a username that every later attempt had to read back slowly.

- Seal new store credentials with a TEE Keystore key (v2 envelopes); v1
  envelopes still open with the old key and move to v2 on their next write.
- A sign-in discards an Xbox record without a username (an unfinished
  sign-in) before starting the backend.
- The backend waits 30 s for the app's credential reply.
- The backend names the failing step instead of only credential-io (socket
  connect/exchange, session lock, missing socket name/port/key), and falls
  back to a keyed 127.0.0.1 port when the abstract socket is refused.
- The app's credential listener logs and retries accept errors, serves each
  connection on its own thread, and logs slow requests with per-stage times.

Refs #1337, #1300


Co-authored-by: KeegantheVeganat0r <58369898+KeegantheVeganat0r@users.noreply.github.com>
2026-10-25 01:39:09 +00:00
maxjivi05 82d8eb3b79 Keep a Proton choice unless the shared build needs the other platform 2026-10-24 21:13:58 -04:00
maxjivi05 5f0e6a8b7e Match Proton tools across clients by their arm64 and a64 names 2026-10-24 21:13:58 -04:00
maxjivi05 c866bb90db Share installed games between the arm64 and x86-64 Steam clients 2026-10-24 21:13:58 -04:00
MaxsTechReview 8d407aa1e8 Focus flatpak and other sandboxed shortcuts in gaming mode (#1524) 2026-10-24 20:04:54 -04:00
Kurt Himebauch aca7fca19f fix: keep cancellation polling from ending session teardown early 2026-10-24 19:50:10 -04:00
Kurt Himebauch 96ba915378 fix: publish session stopping before clearing the running flag 2026-10-24 19:50:10 -04:00
Kurt Himebauch 71f84f0593 fix: defer automatic Proton updates until session teardown ends 2026-10-24 19:50:10 -04:00
Kurt Himebauch b56ea6122a fix: exclude pending launches and retain Proton update cooldowns 2026-10-24 19:50:10 -04:00
Kurt Himebauch 8a948fbe45 feat: automatically update installed Proton builds on app open 2026-10-24 19:50:10 -04:00
maxjivi05 74a6a88df8 fix(desktop): keep the Desktop actions and Settings handle on small phones 2026-10-24 18:58:45 -04:00
maxjivi05 c9493993af fix(desktop): keep the Desktop page from overlapping on phones 2026-10-24 18:58:45 -04:00
MaxsTechReview dc08385411 Stop the library helper when the KDE Steam client exits (#1519) 2026-10-24 17:57:59 -04:00
MaxsTechReview 49b6a0739d Present games from the KDE Steam client through software WSI (#1518) 2026-10-24 17:56:40 -04:00
MaxsTechReview 8471682b1c Collect only the Steam log lines a session wrote (#1505) 2026-10-24 14:47:21 -04:00
MaxsTechReview 4dda1c1e52 fix(epic): a paused install keeps what it downloaded (#1504) 2026-10-24 14:47:18 -04:00
Thomas Lee 8156a9649d perf: reuse Steam artwork directory scans (#1466) 2026-10-24 14:35:14 -04:00
FX1922 7b518d7e6a itch.io: platform and tag filters (#1497) 2026-10-24 13:39:57 -04:00
maxjivi05 8d66570d33 Steam file dialog: keep spaces in the chosen path, cancel when GTK 3 is missing or the bridge reconnects 2026-10-24 13:18:04 -04:00
maxjivi05 5a56d9f785 fix(steam): Browse buttons open a file chooser on the ARM64 client
Steam's ARM64 client has no desktop-portal file chooser, so
SteamClient.System.OpenFileDialog failed at once and every Browse button
(Add a Non-Steam Game, shortcut target, library folder) did nothing.
The Steam UI bridge now answers it with a GTK file chooser run under
Steam's reaper, so gamescope shows it over Steam.
2026-10-24 13:18:04 -04:00
MaxsTechReview 77e23cb397 itch.io: browse the Store tab by sort and price, with paging and a disk cache (#1473)
## What this does

The itch.io Store tab used to show only four fixed shelves. This is the
first of a series of PRs that rework it. It adds real browsing: pick an
order and a price filter, and the tab loads itch's own listing for that
choice and keeps loading as you scroll. Login, the library, downloads
and installs are unchanged.

Platform and tag filters, the game page with the install picker, updates
and collections are not in this PR. They come in the following ones.

## How it works

itch serves every listing page as an RSS feed if you add `.xml` to the
address. The app already reads those feeds for the shelves, so browsing
reuses the same parser (`ItchShelves.parse`). Nothing here needs the API
key.

The address is built the way itch builds its own links: sort, then
price, then `platform-<name>`, then `tag-<slug>`.

| Choice | Address |
|---|---|
| Popular (default) | `https://itch.io/games` |
| New & popular | `/games/new-and-popular` |
| Top sellers | `/games/top-sellers` |
| Top rated | `/games/top-rated` |
| Most recent | `/games/newest` |
| Free | `/games/free` |
| On sale | `/games/on-sale` |
| Paid | `/games/store` |
| $5 or less | `/games/5-dollars-or-less` |
| $15 or less | `/games/15-dollars-or-less` |

Choices combine, for example `/games/top-rated/free`, then `.xml` for
the feed. Page 2 and later add `?page=N`.

## Changes

**`stores/itch/ItchBrowse.kt` (new)**
- `BrowseQuery` holds sort, price, platforms and tags. The default query
is the front page, which keeps the existing shelves.
- `ItchBrowse.path` and `url` build the addresses above. Only the
spellings listed above are used. Platforms and tags are already accepted
by the builder, ready for the next PR.
- `ItchBrowse.page` loads one page of results:
- Disk cache under `cacheDir/itch-browse`, keyed by the SHA-1 of the
address, fresh for 3 hours.
  - Requests are made one at a time, at least 1.2 s apart.
  - A 429 answer waits 8 s and tries once more.
- Each request is written to the store log (address, status, number of
games).
- `ItchBrowseState` is the Compose state for the tab: the query, the
games loaded so far, and the loading, ended and failed flags. A
generation counter discards answers that arrive after the user has
changed the query. Paging skips games it has already shown.

**`ui/ItchBrowseBar.kt` (new)**
- A sort chip row and a price chip row, plus a load-more trigger at the
end of the grid.
- Chips are selectable, work with the controller (`controllerConfirm`)
and use the same glide border as the rest of the app.

**`ui/StoresPage.kt`**
- The storefront shows the chip bar for itch.io and, when a non-default
choice is active, the browse results in the existing grid instead of the
shelves.
- Games you already own are marked as owned in the results.
- Empty and failed states have their own messages.

**`stores/itch/ItchShelves.kt`**
- `open(url)` is now `internal` so browsing can reuse it.

**`stores/StoresState.kt`**
- `detailItem` also looks in the browse results for itch.io, so tapping
a result opens its detail page.

**Strings**
- 13 new strings (sort names, price names, "Load more", "Couldn't load
games"), translated in all 33 locales.

**Docs and tests**
- `docs/development/itch-browse.md` explains the address scheme, the
cache and the paging.
- `ItchBrowseTest` checks the addresses the code builds against the ones
listed above.

## Testing

I checked every address with `.xml` added, and all of them load without
errors:
- Every sort, every price filter and every platform on its own.
- Combinations: `top-rated/free`, `top-rated/on-sale`,
`top-rated/store`, `top-rated/5-dollars-or-less`,
`top-rated/free/platform-windows` and
`top-rated/free/platform-windows/tag-pixel-art`.
- Paging: `?page=2` and `top-rated.xml?page=2`.

The unit test locks those addresses in.

## Not in this PR

- Platform and tag filters in the UI, and search.
- The game page, the version picker and install for free games.
- Updates for installed games and itch collections.
- Android builds will link out to the itch.io page. Butler patching
comes last, as an add-on pack.
2026-10-24 11:33:47 -04:00
maxjivi05 1883a8c7cf itch.io browse: drop code comments 2026-10-24 11:15:35 -04:00
maxjivi05 aefd8a3b60 fix(xbox): report a failed class registration in the launch log 2026-10-24 11:14:20 -04:00
maxjivi05 fee8ce91f3 fix(xbox): register the runtime's WinRT classes and load its wintypes so Minecraft starts 2026-10-24 11:14:20 -04:00