Commit Graph
135 Commits
Author SHA1 Message Date
Kurt Himebauch a8b18947a1 perf: cache the Steam client's repeated path lookups to cut startup from 31s to 6s (#69) 2026-09-28 23:18:48 -04:00
Kurt Himebauch 7c422577b6 fix: let the Steam client shut down cleanly when a session stops (#68) 2026-09-28 22:12:19 -04:00
MaxsTechReviewandMaxsTechReview d8d375cb9a Steam Owned Games Importing (#62)
* Add ownership-aware Steam game folder imports

* Fix Steam title lookup and installed game manifests

---------

Co-authored-by: MaxsTechReview <6025299+maxjivi05@users.noreply.github.com>
2026-09-28 18:13:08 -04:00
MaxsTechReviewandMaxsTechReview 240f1194c0 Fix/variables (#60)
* Add editable per-game environment settings below FEX presets

* Add typed preset variable pickers and default D3D12 capability levels

---------

Co-authored-by: MaxsTechReview <6025299+maxjivi05@users.noreply.github.com>
2026-09-28 15:17:57 -04:00
Kurt Himebauch 626adb62af Merge branch 'main' into fix/desktop-hardware-cursor 2026-09-28 14:39:52 -04:00
xXJSONDeruloXx 68002f3fa7 build_local: sign with DroidDeck's key when a local .signing.env has it
A local build was signed with the testkey alone, which a release refuses
as an update ("signatures do not match"): testing on a device with a CI
build meant uninstalling it and losing its data first.

With an untracked .signing.env (RELEASE_KEYSTORE, RELEASE_STORE_PASSWORD,
RELEASE_KEY_ALIAS) in the checkout, or in the main checkout for a
worktree, build_local.sh finishes with tools/release/sign-apk.sh as CI's
main builds do, and the apk installs over a release. Without the file
nothing changes. DROIDDECK_SIGNING_ENV points at the file explicitly.
2026-09-28 14:33:15 -04:00
xXJSONDeruloXx dae7592788 Desktop: hand labwc's cursor to the app, so full-screen games scan out
The desktop forced a software cursor (WLR_NO_HARDWARE_CURSORS=1) because
labwc's cursor never showed when handed to the app's compositor. With a
software cursor wlroots never scans out: every frame of a full-screen game
was composited by labwc first ("Direct scan-out disabled by software
cursor", 2284 times in one Adreno 825 report).

Why the cursor never showed: wlroots' Wayland backend attaches and commits
its cursor surface before wl_pointer.set_cursor gives it the cursor role,
and sets it again with nothing new committed each time the pointer enters.
The compositor released a role-less surface's buffer on commit, so the
cursor surface had no image by the time it became the cursor.

- A role-less surface's last buffer (cursor-sized only) is held until the
  next commit; set_cursor publishes it, and a repeat set_cursor of the
  surface already shown unhides its last image.
- A dma-buf cursor is read back after the client's implicit render fence,
  as the zero-copy path waits for it.
- The desktop no longer forces a software cursor.

Device-tested on the AYN Thor (Adreno 740, 1920x1080): labwc's own cursor
is drawn, with its shapes (I-beam over a terminal); wlroots logs "Direct
scan-out enabled" for a full-screen glxgears. At the same 60 fps on screen
the GPU is 3.0 % busy against 4.6 % with the software cursor, both at
550 MHz.
2026-09-28 14:33:08 -04:00
xXJsonDeruloXx 614b4d4de4 chore(release): set version 0.2.0 and remove code comments 2026-09-28 10:32:12 -04:00
Kurt Himebauch 67cb005e6c fix(session): stop the session script's own loops when steam exits 2026-09-28 11:52:03 +00:00
Kurt Himebauch 7185b775d4 0.2.0 release notes with screenshots, plus launch transition and UI fixes (#46)
* docs(release): draft 0.2.0 beta notes

* docs(release): credit prs and authors in 0.2.0 notes

* docs(release): add #39 and #45 to 0.2.0 notes

* chore: update readme

* fix(ui): cover the whole screen with the capsule wall

The wall was shifted right and then tilted around its own centre, which
left the bottom-left of the home and loading screens bare. Centre it and
size it to the tilted page's bounding box so every corner stays covered.

* feat(ui): flood from the play button into the throbber

Starting a session from a blue button no longer slides the session up
over the front end. The button stretches out on staggered springs until
the page is the ball's blue, the session opens on that same blue with no
window animation, and the blue gathers into the throbber's ball before
the throbber starts. Re-joining a running session, tiles and reduced
motion keep the old rise.

* docs(release): cover everything since 0.1 in the 0.2.0 notes

0.2.0 is the first release from the org, so list what DroidDeck does
as a whole, grouped by area: org pull requests as #N, pull requests
from before the move as The412Banner/DroidDeck#N, and the early work
that predates pull requests by author. CI and build work gets one
short section instead of a line each.

* docs(release): add screenshots and animations to the 0.2.0 notes

Lead with a game running and a few visual highlights, fold the full
list into collapsible sections by area, and shorten every line to the
feature and its credit. Pre-move pull requests read as legacy#N.

* fix(session): give the desktop its own loading hints

The loading screen's hints were written for Steam, so starting the
desktop or an emulator said the first run downloads Steam and that
leaving the app pauses Steam. Desktop and program sessions now rotate
through hints about the desktop instead.

* fix(build): skip incomplete NDKs when picking one locally

An interrupted sdkmanager install leaves a directory like
28.2.13676358.failed under ndk/, which sorted last and was picked
without a toolchain in it. Only consider directories that carry
source.properties.

* docs(release): show launching straight into Big Picture

* docs(release): credit the launch transition to #46
2026-09-27 22:14:23 -04:00
The412Banner be6c875277 Session stop: kill guest processes proot lost, and cap the session log
Twice today a session's Xwayland aborted from one thread ("The futex
facility returned an unexpected error code"), proot lost the tracee, and
the process lived on reparented to init: proot's seccomp filter, with no
tracer left, answers ENOSYS, so Xwayland's main loop logged
"WaitForSomething(): poll: Function not implemented" until something killed
it - 9 GB after Dolphin, 13 GB after PPSSPP. --kill-on-exit and the tree
sweep only reach what proot still traces, and the straggler sweep ran only
at the next session's start.

Now a session stop also kills every process of ours whose executable lives
in the Linux runtime, and bannerlator-session keeps only the first
BL_LOG_CAP bytes (256 MB) of session.log, draining the rest so a writer
that filled it is not killed by SIGPIPE.
2026-09-27 16:52:51 -04:00
The412Banner 65fc2a38a3 Cemu (Wii U) from the front end and the desktop, and two session fixes
Cemu never showed a frame on DroidDeck: its Getting Started dialog blocked
every first launch (the folder picker cannot reach ROMs), the session's
controller helper aborted it, and the desktop's Vulkan renderer drew no
cursor. With the Turnip KGSL fix in the driver and the haptic-optional
Cemu in the catalog, this makes the app side complete:

- bannerlator-pad-defaults seeds Cemu's settings.xml once: the Wii U games
  folder, Vulkan, and Cubeb audio on the default device for both the TV
  and the GamePad speaker at full volume (Wipeout 3 plays through the
  GamePad; Cemu's own default is 20 %).
- The Cemu tile launches full screen (-f).
- libfakeinput.so is preloaded into every session process and exported its
  static C++ runtime (~7000 symbols); programs unwound through it and
  aborted (shadPS4 in pthread_exit, Cemu's controller thread). Link with
  --exclude-libs,ALL, and fail the build if the runtime leaks out again.
- On the Vulkan and GLES desktops the pointer worked but no cursor was
  drawn: wlroots hands the cursor to the app's compositor, which draws
  none. WLR_NO_HARDWARE_CURSORS=1 makes labwc composite it itself.

Device-tested on the FIT: Super Mario 3D World in-game at 35-37 fps with
sound, Deus Ex HR DC and Wipeout 3 launch with sound; RPCS3, Dolphin and a
Steam session (FlatOut) unchanged on the same driver.
2026-09-27 16:30:49 -04:00
Kurt Himebauch e186c9bc4c Merge branch 'main' into fix/performance-enhancements 2026-09-27 11:31:48 -04:00
xXJsonDeruloXx 59cde93821 Add optional Steam startup 2026-09-27 09:27:30 -04:00
maxjivi05 c104e1c276 proot: port WinNative's seccomp and tracee performance fixes
Brings the proot patch set up to WinNative 53836ca9 on top of the #772 port:

- trace prctl, setrlimit and prlimit64 in the seccomp filter only for the
  arguments proot acts on, and uname only where the core rewrites it
- answer a seccomp stop's filter flags from the registers fetched for its
  translation, reuse those registers, and skip the sysexit stop of wait4 left
  to the kernel and accept without a sockaddr; the flags come from proot's list
  merged with the enabled extensions, and a syscall an extension replaced
  keeps its exit stop
- take a clone3 child's flags and exit signal from struct clone_args
- name a thread's /proc/self by its thread group and resolve /proc/thread-self
- translate fchmodat2, send openat2 callers to openat, and bound sysnum lookups
  by the table length
- sweep relatives only for tracees that have children or ptracees, and empty
  the per-stop memory collector instead of reallocating it
2026-09-27 08:10:58 -04:00
The412Banner ecbce4c8d3 Steam updates: the client is not uid 0 in the session - drop that test
The session's proot runs with -i <app uid>, and the rootfs names that uid
root, so the client calls itself root while geteuid() returns the app's
uid. The read-only retry required geteuid() == 0 and never ran: the
Proton Experimental (ARM64) update still failed with Missing file
permissions on wineopenxr.dll (2026-09-26 16:07, 2,471 read-only files).

Also recognise the client by the path it was started by: the kernel's
/proc/self/exe names proot's loader for every process in the session.
2026-09-26 16:10:11 -04:00
The412Banner a10e2e1fe8 Merge remote-tracking branch 'org/fix/first-login-proton-timing' into fix/steam-readonly-files 2026-09-26 15:33:01 -04:00
The412Banner 277dcd174c Steam updates: rewrite read-only content files the way root could
The client runs as proot's root, which the kernel does not see, and
leaves many content files read-only; an update that rewrites one was
refused (EACCES) and cancelled with "Missing file permissions"
(Proton Experimental (ARM64), wineopenxr.dll). For the client's own
processes, a refused write-open of a file the app owns now gets the
owner's write bit - on the file, or on the directory a new file goes
into - and one more try. Games and Wine keep ordinary permissions.
2026-09-26 10:41:06 -04:00
The412Banner 8cb13d40b5 First sign-in: ask for the ARM64 Proton after the client's post-logon compat phase, and retry
With Steam publicbeta 1790380355 the client spent 27 s in its post-logon
compat phase and dropped the install request the session sent 15 s after
sign-in, so a clean install never offered Proton Experimental (ARM64).
Wait for the console log's "Waiting for compat in post-logon took" (90 s
at most), then ask, up to three times a minute apart until the install
starts.
2026-09-26 08:21:14 -04:00
The412Banner 0fd1dc4fce Proton wrappers: run the components check for non-Steam shortcuts too - decide by the game's own prefix rather than the app id, which is 0 for a shortcut 2026-09-26 05:15:36 -04:00
The412Banner bb5e1ae63d Proton wrappers: run the components check only for a real game launch (waitforexitandrun, non-zero app id)
With the check reached from the client's own runs right after login, the Steam client segfaulted
within seconds, four sessions out of four; the same build without the check (test/bisect-no-launch-check)
and the last build before it both reach Big Picture. Now every run that is not a game launch -
the client's probes, app id 0 - is left exactly as before. Each check logs one line.
2026-09-26 00:28:49 -04:00
The412Banner d7ff92106a Remove a stray __pycache__ from the overlay scripts and ignore it 2026-09-26 00:20:41 -04:00
The412Banner 110aec0b6f Proton wrappers: drop the per-tool prefix for Steam's tool-0 runs - the client segfaulted right after its probe started (first in 25 sessions); keep the launch-time component check 2026-09-26 00:03:45 -04:00
The412Banner 06502bb49b Components: choices enforced at every game launch; Steam's tool-0 probes get their own prefix per Proton
Steam runs its graphics probe through every registered Proton at once after login, all in
compatdata/0. Prefix system32 links point into the Proton that set it up last, and the other
Protons' Wines, running outside Proton's pfx.lock, wrote their builtin DLLs through them into that
Proton's tree (device: GE's FEX DLLs became Proton Experimental's at session start).

- bannerlator-steam-compat: both wrappers (Valve's depot launcher and the third-party
  bannerlator-proton-wrap) give a tool-0 run STEAM_COMPAT_DATA_PATH=.../compatdata/0-<tool>, and
  before every other launch check the Proton's files against the app's desired.tsv and put back
  anything that differs (same Proton build only), logging to reapplied.log.
- ComponentsManager writes desired.tsv plus unpacked copies of the packages in use into the
  runtime after every change; the page and the drawer show 're-applied at launch'.
2026-09-25 23:54:10 -04:00
The412Banner 0f39d71f95 Merge remote-tracking branch 'org/main' into feat/steam-touch 2026-09-25 16:58:18 -04:00
The412Banner 1dc49b527b gamescope: stage 3.16.29-p3 (0111, pointer warps in Passthrough) 2026-09-25 16:38:50 -04:00
The412Banner cc3fec0768 gamescope: the nested pointer moves Steam's pointer in Passthrough too
In touchpad mode the cursor moved but Big Picture highlighted nothing and a tap-to-click
selected nothing: the nested pointer's motion reaches wlserver as touch 0, and in Passthrough
(the touch mode Big Picture sets) a motion for a touch that is not down moves nothing, so the X
pointer stayed where it was. 0111 passes bAlwaysWarpCursor, as the other touch modes already warp.
2026-09-25 16:34:22 -04:00
Kurt Himebauch 5270574e5a Add native Decky Loader support (#16)
* Add native Decky Loader management

* Enable Decky Steam frontend injection

* Disable unavailable stable Decky channel

* Decky: tie CEF debugging to session setting

* Decky: simplify Steam settings controls
2026-09-25 16:26:29 -04:00
The412Banner a8af973726 gamescope: stage 3.16.29-p2 (0110, touch from the host) 2026-09-25 16:06:31 -04:00
The412Banner ed1f8dd2b6 gamescope: take the host's touch in the nested Wayland backend
3.16.29's Wayland backend bound only wl_pointer and wl_keyboard; touch from DroidDeck's
compositor was never read, so Steam could not be touched. 0110 binds wl_touch in the input
thread and feeds each finger to wlserver_touchdown/touchmotion/touchup, the Steam Deck
touchscreen's path, so Big Picture's Passthrough touch mode gets real touches.
2026-09-25 15:55:26 -04:00
Kurt Himebauch 036317f371 Build local APK with CI payload parity (#20) 2026-09-25 13:20:51 -04:00
The412Banner e3ceae412b Revert the Steam session's D-Bus session bus
Tried on device: with a session bus the client still sat on "Switching to Desktop..." and
never reached its legacy path (no "No SteamOSManager support" line, steamos-session-select not
called), so the bus was not what it waited on. Sign-in was unaffected.

This reverts commit 40fc5463f3.
2026-09-25 09:55:59 -04:00
The412Banner 40fc5463f3 Steam session: a D-Bus session bus, so Switch to Desktop reaches steamos-session-select
Big Picture's Switch to Desktop asks SteamOS Manager over the session bus before falling back to
steamos-session-select (steamui.so). The Steam session had no session bus, the ask never
finished, and the client sat on "Switching to Desktop..."; the new stub was never called. A
bus with nothing on it answers at once, and the client takes its legacy path.
2026-09-25 09:41:21 -04:00
The412Banner 039948f4d2 Steam desktop UI on the desktop; Big Picture's Switch to Desktop works
- The front end's "Steam Desktop UI" started a Steam session without -gamepadui, and the client
  put itself into Big Picture under gamescope anyway. It now opens the desktop with Steam's
  desktop client started in it (BL_DESKTOP_STEAM, the desktop's autostart, the same
  bannerlator-steam-launch the menu's Steam entry uses).
- Big Picture's power menu "Switch to Desktop" runs steamos-session-select, which did not exist,
  so it sat on "Switching to Desktop..." for ever. The new stub leaves the app a request
  (session=desktop in the steam-launch file); the app ends the Steam session and starts the
  desktop with Steam's desktop client open.
2026-09-25 08:59:06 -04:00
The412Banner bbb95e8a60 Desktop: centre melonDS's 800x600 window
AutoPlace on its own left the resized window in the top-left corner; with policy="center" it
opens in the middle of the desktop. Tried in a running desktop (labwc --reconfigure).
2026-09-25 08:36:04 -04:00
The412Banner 7763d00b78 Desktop: melonDS opens as an 800x600 window, centred
melonDS remembers a 1x window for the front end's full-screen toggle, too small on a desktop.
A labwc window rule (only the desktop reads rc.xml) resizes it to 800x600 on open and places
it again by the desktop's centre policy.
2026-09-25 08:28:56 -04:00
The412Banner e50f61f5d9 Desktop: Qt falls back to X11, so melonDS opens from the menu
The desktop set QT_QPA_PLATFORM=wayland for every program. The melonDS AppImage bundles only
Qt's xcb plugin, so from the desktop it exited at once: "Could not find the Qt platform plugin
wayland ... Available platform plugins are: xcb" (exit 127). "wayland;xcb" keeps LXQt on
Wayland and lets such an AppImage use Xwayland. Proven in a running desktop: labwc mapped
"melonDS 1.1".
2026-09-25 08:18:43 -04:00
The412Banner e811576e79 melonDS: leave full screen to a 1x window, so its menus are big enough to use
The guide button's toggle returns to melonDS's saved window size. A 512x288 window (1x wide,
16:9) is stretched by gamescope to fill the panel, menu bar and cursor with it; at 2x and up
the menus stay at their real size, tiny on a handheld. Written once, with the layout.
2026-09-25 07:52:26 -04:00
The412Banner 960abec0ed melonDS: big top screen with the bottom screen alone beside it
Hybrid repeats the big screen, small, above the bottom one. Horizontal with the top screen
emphasised fills the panel's height with the top screen and centres the bottom screen in the
rest. Installs set up with Hybrid (or still on melonDS's defaults) move once.
2026-09-25 07:47:59 -04:00
The412Banner f7ee6e78f0 melonDS: Hybrid screens, full screen from the front end, guide toggles full screen, BIOS found in the ROMs folder
- bannerlator-pad-defaults: new installs start on the Hybrid layout with sharp pixels; an
  existing install is moved once, only where still on melonDS's defaults (marker keeps later
  choices). Guide = HK_FullscreenToggle. The user's DS/DSi BIOS, firmware and NAND are found in
  ROMs/nds/{bios,firmware} and filled in only where melonDS has no path.
- Front end starts melonDS with -f, at the panel's own resolution unless the user chose one.
2026-09-25 07:37:21 -04:00
The412Banner 8c171dd2c7 Merge remote-tracking branch 'org/main' into feat/desktop-steam-dolphin
# Conflicts:
#	app/src/main/java/com/droiddeck/launcher/session/SessionService.kt
2026-09-24 22:35:37 -04:00
The412Banner 96bbe0c4cc Merge remote-tracking branch 'origin/feat/desktop-steam' into feat/desktop-steam-dolphin 2026-09-24 22:24:00 -04:00
xXJSONDeruloXx a419c8097f fix(agent-bridge): launch sessions through debug activity 2026-09-24 22:16:28 -04:00
Kurt Himebauch c2d6d272a3 Merge branch 'main' into feat/debug-agent-control 2026-09-24 22:00:40 -04:00
Kurt Himebauch cc1f3d256b Merge branch 'main' into chore/codebase-deslop 2026-09-24 22:00:12 -04:00
xXJSONDeruloXx 4f744fc8fe chore: remove dead code and stale comments 2026-09-24 21:53:31 -04:00
xXJsonDeruloXx 54adf9ad68 Add debug-only agent control bridge 2026-09-24 21:34:50 -04:00
The412Banner 8b66adb8a5 Dolphin: guide = its Toggle Fullscreen hotkey (full default Hotkeys.ini), Wii Home on R1, input without focus from the rail 2026-09-24 21:31:25 -04:00
maxjivi05 9f0c1fc797 Merge Droid-Deck main into fix/proot-performance 2026-09-24 21:27:31 -04:00
xXJSONDeruloXx 7ae66337ef Trim signing key script comments 2026-09-24 21:02:13 -04:00