mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-11 02:51:10 +00:00
feat/refresh-loading-tips
51
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
+1 |
3733c50902 |
feat: non-Adreno graphics stack (Venus, open driver pairs, gamescope patches) (#2029)
* Retain compositor resources when GPU completion is unconfirmed * Stop quarantined GPU callers before retries and mapped writes * Support Android hardware-buffer presentation over Wayland * Support PowerVR swapchains and linear image imports in Gamescope * Bundle verified PowerVR graphics components through existing build preparation * Detect and select the system Vulkan backend on PowerVR * Apply PowerVR Steam and game compatibility during normal launches * Show PowerVR support through existing driver and component controls * Update existing hardware guidance for system Vulkan support * Import the shared system Vulkan readiness check * Discover and propagate the actual PowerVR render node * Prune obsolete PowerVR runtimes after guest processes exit * Retain external DMA-BUF ownership after GPU quarantine * Name the PowerVR HAL selection explicitly * Isolate component UI tests from application startup * Cover the inherited FEX preset in PowerVR profile tests * Log test worker failures for CI diagnosis * Remove temporary test logging after diagnostic CI * Prefer system dependencies for the Android Vulkan loader * Capture raw stderr before test worker termination * Remove the temporary test worker crash probe * Import pinned DXVK recipe prerequisite from PowerVR PR570 Copy only the standalone build recipe, source pin, BC-format prerequisite and presentation-sync patch/check from wallentx/DroidDeck at |
||
|
|
906e60a042 |
feat(desktop): show programs installed by Windows installers (#2146)
* Desktop: programs a Windows installer adds get a menu entry and desktop icon Opening a Windows installer on the desktop runs it with Proton in a prefix of its own (droiddeck-proton-run's "own" prefix). Proton's menu builder turns the installer's Start Menu links into .desktop files, but keeps them in the prefix's drive_c/proton_shortcuts with a Windows .lnk path as Exec, and nothing outside the prefix pointed at the installed program: Nexon Launcher installed fine on an AYANEO Pocket FIT Elite and could only be found by browsing the hidden compatdata folder. droiddeck-desktop-programs reads proton_shortcuts in every prefix that is neither a Steam game's nor a current Steam shortcut's, resolves each link to its program inside the prefix, and writes a menu entry that opens it with droiddeck-open, so it runs in that same prefix, with the icon Proton extracted. A program whose installer also put a link on the Windows desktop gets a desktop icon once; one the user deletes is not put back. Entries go away with their program; uninstallers get none. It runs when the desktop starts and after droiddeck-open finishes a Windows program. * Desktop programs: only programs that run in their prefix, Windows argument rules, one refresh at a time A link resolved through Proton's Z: mapping could name a program outside the scanned prefix, and droiddeck-open would then run it in another one. A program is now listed only when droiddeck-proton-run's prefix_of puts it in the prefix it was found in. Shortcut arguments were split with shlex, so a Windows argument with an apostrophe raised and stopped the whole refresh; they are now split by the Windows command-line rules. The desktop start and the end of a Windows program can refresh at the same time and race on the same temporary files; refreshes now take turns on a lock beside the placement record. * Desktop programs: extract the script at session start SessionFiles lists the overlay scripts the app copies into the runtime; droiddeck-desktop-programs was missing, so a real build would never have installed it and check_session_assets failed the build. * Desktop programs: a compatdata folder it cannot read changes nothing Any error listing steamapps/compatdata made the refresh see no prefixes, so it removed every program entry and forgot which desktop icons it had placed; the next good run then put back icons the user had deleted. Only a missing compatdata now means there is nothing installed; any other read error leaves the menu, the desktop and the placement record as they were. * Desktop programs: an unreadable shortcut or desktop folder changes nothing os.path.isdir and glob read an unreadable proton_shortcuts or Windows desktop folder as empty, so the refresh dropped that prefix's entries and placement records and a later run put back icons the user had deleted. Those folders are now listed directly: a missing one is still empty, and any other error leaves the menu, the desktop and the record as they were. * Desktop programs: only a missing file reads as absent read(), link_target() and host_path()'s letter-case lookup turned any error into "absent", so an unreadable placement record read as empty and brought back icons the user had deleted, and an unreadable shortcut or link dropped its program's entry. A missing file, a wrong file type and a malformed link still read as absent; any other error now reaches main(), which leaves the menu, the desktop and the record as they were. * Desktop programs: keep the placement record true when a run fails part way The placement record was read after the menu was already rewritten, so an unreadable record changed the menu although the run reported it had not. It is now read first. When writing desktop icons failed part way, the icons already written were not recorded, and the next run recreated any of them the user had deleted. The record is now written from the icons that exist after the attempt, icons are written in a fixed order, and a failed write leaves no temporary file on the desktop. os.path.exists and isfile also read a program whose path cannot be reached as missing; a stat that fails only because the file is absent now counts as missing, and any other error leaves everything as it was. * Desktop programs: leave the menu alone when Steam's shortcuts cannot be read The list of Steam shortcuts comes from a reader that treats an unreadable or damaged shortcuts.vdf as having no shortcuts, so a Steam shortcut's prefix could get a menu entry and a desktop icon of its own. The file is now checked first: a missing one still means no shortcuts, and any other read or parse failure leaves the menu and the desktop as they were. * Desktop programs: an unreadable Steam account or empty shortcuts file also stops the refresh account_dir takes an unreadable loginusers.vdf or userdata folder as missing, so the shortcuts check could be skipped and a Steam shortcut's prefix still get its own entry. Both are now read first, and an access error leaves the menu as it was. An empty shortcuts.vdf is now parsed like any other, so it stops the refresh too, the same way droiddeck-steam-shortcuts refuses to rewrite it. --------- Co-authored-by: K11MCH1 <81425424+K11MCH1@users.noreply.github.com> |
||
|
|
bba40cd69c |
fix(desktop): a game's window follows its own window mode (#2094)
* fix(desktop): a game's window follows its own window mode Desktop games ran in a titled gamescope window whatever mode they asked for. gamescope now fills the desktop for a fullscreen or borderless game and matches the window size of a windowed one. * Use the p30 gamescope test build * fix(desktop): a windowed game too big for the desktop is maximised * fix(desktop): a decorated game window stays a window * Use the published gamescope p21 |
||
|
|
f05e0df39e | Merge remote-tracking branch 'origin/main' into review/malibridge-1950 | ||
|
|
b16b67e6c4 | feat: desktop session follows the app language (#1971) | ||
|
|
8171bf20fd | Merge latest origin/main and resolve conflicts | ||
|
|
c5577478ca |
chore: remove source comments and unused code, translate every missing string (#1965)
* chore(i18n): translate every missing string in all locales Adds the 87 strings the bottom-screen Dashboard and in-game stats pages introduced to all 32 locales, plus the 51 older settings strings Japanese and the 50 Chinese locales were still missing. Every locale now has all 3456 translatable strings with the same placeholders as English. Also translates 36 entries that were still English where the language does not use the English word, and makes es-419 touch_app_id use the same %1$s placeholder as English. * chore(patches): drop comments from the lines downstream patches add Removes comment lines and trailing comments from lines our patches add, with hunk headers recounted. Lines that a later patch uses as context and the upstream backport 0123 are left as they are. The gamescope, FEX, proot and xodus series still apply to their pinned sources, and the patched trees differ only in those comments. test_hud_frames now finds the HUD writer by its first declaration. * docs: credit Greenlight, Better xCloud, viture-v2, GameNative and DiRTTelemetryErrorFix These were credited only in source headers and NOTICE files. * chore: remove source comments and unused functions Removes explanatory comments from first-party Kotlin, Java, C, C++, Rust, TypeScript, Python, shell, Gradle, CMake and workflow files. License and attribution headers stay, and vendored third-party trees, generated files and license files are untouched. A shellcheck directive is kept, and udevmon's fallthrough comments became fallthrough attributes. Syntax trees and token streams match the previous sources apart from the comments and Python docstrings. Module docstrings that argparse prints are kept, and device-smoke.sh prints the same --help text from a heredoc. Also removes 37 functions and 4 fields that nothing referenced. * chore: remove comments from the Syncthing integration and the latest main sources * docs: credit Syncthing and the syncthing-android fork * chore(i18n): translate the Syncthing strings in all locales The 107 strings the Syncthing integration added are now in all 32 locales. sync_web_path_locked names the Syncthing tab by its label. * docs: credit @xXJSONDeruloXx for the HUD metric readers The CPU, GPU load, thermal and battery readers come from their PerformanceHudView pull requests #777, #877, #991, #1406 and #1573. The FusionHUD credit line is unchanged. * docs: credit the HUD metric readers to @xXJSONDeruloXx's work |
||
|
|
bf9435cd36 |
feat: KDE desktop on the bottom screen beside the session (#1966)
* feat: KDE desktop as a bottom-screen mode beside the top-screen session * test: bottom-desktop launch test sets DISPLAY instead of inheriting it * fix: drop the bottom desktop's launch when the session stops while preparing it * fix: bottom desktop restarts on a fresh surface, trackpad/touch toggle, loading throbber, DroidDeck's display driver * fix: bottom desktop pauses with the session and opens the keyboard for a tapped text field * fix: no bottom desktop guest starts or keeps running unfrozen while the session is paused * fix: bottom desktop treats a freeze in progress as paused * fix: only the session that began a freeze clears its pausing flag * fix: bottom desktop launch is stored and cleared only for its own session generation * fix: a stopped session tears down the bottom desktop it started even after a newer launch is prepared * fix: a new session's bottom desktop replaces one an earlier session left running * fix: release the bottom desktop's keyboard watcher when its compositor dies * fix: bottom desktop starts its guest only for the launch its compositor was attached for * fix: bottom desktop ignores compositor replies to an earlier session's attach |
||
|
|
9419a19c66 | local: MaliBridge rc4, auto local DNS, KWin render node | ||
|
|
22d39998f0 | fix(desktop): let desktop apps save read-only game files, and make game libraries writable (#1781) | ||
|
|
0258f10df0 | fix(desktop): start Electron and Chromium apps from apt without the sandbox, on X11 (#1775) | ||
|
|
29c83976d0 | Move the Linux runtime to Ubuntu 26.04 LTS with a separate Kubuntu desktop (#1733) | ||
|
|
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. |
||
|
|
e4a7e52f81 |
Fix nested KWin rendering on Android (#1330)
Select the explicitly configured Android render node for nested KWin 6.8, apply OpenGL settings before Plasma starts, and pin the original signed Mesa 26.2.4 package that passed Thor rendering. Remove build-directory runtime search paths and fail closed on ELF inspection errors. Native ARM64 build passed. Thor validated a visible nested Wayland terminal, active OpenGL ES/Zink on Turnip, 1280x720 output, and keyboard input. Mesa pin regression tests, launcher and ELF failure controls, shell syntax, and human authorship checks passed. Published desktop pin remains r2; full latest-head CI is pending and maintainer authorized this merge after device validation. |
||
|
|
db8d1c9910 |
feat: optional x86-64 Steam client (Valve's Linux client under FEX) beside the arm64 one (#152)
An opt-in second Steam client (Steam settings, Steam client: x86-64): Valve's x86-64 Linux client, unchanged, runs under FEX in its own home with its own game library and the same sign-in. Linux builds run directly, so titles such as Team Fortress 2 and Half-Life use their Linux versions; Windows games use DroidDeck-Proton as on arm64. The arm64 client stays the default. - droiddeck-steam-x64: FEX and the x86-64 rootfs from DroidDeck-Components (sha256-pinned), client install and sync from Valve's CDN, sign-in shared with the arm64 client, its web helper on the GPU (ANGLE GL over FEX's GL thunk, zink, Turnip), Proton wrappers for the arm64 client's tools, DroidDeck direct for Linux builds, SD-card library (x86-64/ beside the arm64 one), repair. - FEX 2610 built by build-fex.yml with thunks and three patches: an openat2 fallback without openat2 (proot), newer-clang thunkgen, MAP_32BIT exhaustion returning ENOMEM. libblsession resolves RESOLVE_IN_ROOT paths inside the root. - Session: x86-64 gating, shortcuts and compatibility tools per client, logs from the client that ran. - App: client setting with the FEX version, an x86-64 chip on the Games header, the active client's library, art, storage, downloads, repair, Offline Mode, Decky, desktop mode, optional VAC diagnostics; per-client state for art, the content log, repair and leftovers. - Strings in every locale. - Review fixes: the library cache is saved only by the newest scan; an abandoned session's Steam logs come from the client it recorded; distinct VAC console names; FEXInterpreter in CPU pinning; clearer VAC hint in pl, ru, uk, cs and bg. |
||
|
|
aecd2ebe1d | cleanup (#764) | ||
|
|
486032f5db | fix: keep the Steam desktop client in KDE (#610) | ||
|
|
2a06204eb4 |
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. |
||
|
|
d99ed8e00b | fix(desktop): address KDE feedback and keep local builds in sync with CI (#488) | ||
|
|
fe71084f23 |
feat: replace the LXQt desktop with SteamOS-style KDE Plasma (#473)
* feat: replace the LXQt desktop with SteamOS-style KDE Plasma * feat: leaving the KDE desktop logs out through Plasma and returns to gaming mode * feat: DroidDeck logo wallpaper as the KDE desktop default * feat: build the KDE wallpaper from the DroidDeck mark artwork * ci: keep the built desktop package as a short-lived artifact for device testing * fix: the desktop loading screen no longer promises Steam on the desktop * docs: the output resize comments name the desktop's KWin * fix: the desktop package verifies every package's Arch Linux ARM signature and never replaces a published tag * fix: programs sent to the GPU from the desktop drop its software rendering overrides * fix: an interrupted desktop install no longer counts as installed * feat: pin the desktop package to its DroidDeck-Components release instead of the catalog |
||
|
|
28da3dcbde |
Desktop: Firefox skips shared-memory seals again (Android 16 tab crash) (#460)
Desktop: Firefox skips shared-memory seals again (Android 16 tab crash, #280 line lost in #252) Co-authored-by: The412Banner <the412banner@users.noreply.github.com> |
||
|
|
b56c44bd0b |
Share font defaults across runtime sessions (#252)
* Support CJK text with the device's own fonts The Linux runtime's rootfs ships DejaVu alone, which has no CJK glyphs, so Chinese, Japanese and Korean text in Steam Big Picture and on the LXQt desktop draws as tofu boxes (issues #118, #206, #249). Bind the device's own CJK fonts - Android's world-readable Noto CJK .ttc, or DroidSansFallback / Source Han - into the guest under /usr/share/fonts/droiddeck-cjk, so nothing is added to the ~790 MB runtime image and the coverage follows the device. A new droiddeck-fonts script, run by droiddeck-session before any program that queries fontconfig, links the default rules, writes local.conf with DejaVu first and the CJK families after it, and rebuilds the fontconfig cache once per set of font files. The desktop's own fontconfig block moves there, so every mode gets it. * Fix CJK and Thai: bind the device font directory, not one file at a time The first cut bound each device font with its own proot -b host:guest. A per-file binding into a plain directory is not applied here: the guest sees a zero-byte placeholder where the font should be (stat size=0, fc-scan empty), so Chinese stayed tofu even though the app had "bound" the font. A directory binding is what the rest of the runtime relies on, so bind /system/fonts as a whole under /usr/share/fonts/droiddeck-device. That also brings Thai, Arabic, Devanagari and the emoji fonts, which the runtime did not have either. Verified on the AYN Thor: the session's fontconfig probe reports sans=DejaVu Sans, zh=Noto Sans CJK SC, th=Noto Serif Thai, and Steam Big Picture in Simplified Chinese renders without tofu (screenshot under docs/development/evidence/). --------- Co-authored-by: xXJsonDeruloXx <danielhimebauch@gmail.com> |
||
|
|
d1760cd49f |
Draw Steam's CJK and Thai text with the device's fonts (#374)
Steam ships no CJK font and the rootfs only has DejaVu, so a phone set to Chinese, Japanese or Korean got Steam in that language with every character drawn as a box. Bind Android's /system/fonts into the guest, index it again whenever it changes, and prefer the matching Noto CJK face for each language. |
||
|
|
6f6bd35b96 |
Firefox: skip shared-memory seals (tabs crash on Android 16) (#280)
On Android 16 phones (Galaxy S25 SM-S931B, SM-S948B, RedMagic NP05J)
every Firefox and LibreWolf tab dies at once: Firefox seals the size of
the shared memory it hands a tab, adding the seal fails there, Firefox
only warns, and the tab refuses the unsealed memory ("IPDL protocol
error: Shared memory PlatformHandle is not safe to map") and exits on
signal 11. The window opens; no page ever loads.
MOZ_SHM_NO_SEALS=1 is Firefox's own switch to skip the seals
(ipc/glue/SharedMemoryPlatform_posix.cpp). Set it beside the sandbox
switches in all three places a browser starts from: the desktop session,
AppImages, and Flatpak sandboxes.
Co-authored-by: The412Banner <the412banner@users.noreply.github.com>
|
||
|
|
27782068a3 |
ESync, FSync, NTSync + OpenNow + FEX for Desktop Apps (#197)
* Make the Compatible Proton ARM64 the default and label compatible builds
The CompatToolMapping "0" default always points at DroidDeck's Proton
ARM64 tool, and per-game picks of adopted GE/CachyOS builds are kept,
including when the shortcuts writer remaps.
The tool is named after the Proton build it runs, Proton Experimental
ARM64 (Compatible), or Proton 11.0 ARM64 (Compatible) once that newer build
is installed. Adopted builds carry the same Compatible mark, read from a
string resource the app stages into the runtime, and the Proton page
explains which builds have the prefix fixes.
The registrar is renamed steam-compatibility and the tool
droiddeck-proton-arm64. Existing installs migrate on the next session: the
old tool directory is removed, every mapping that named it moves to the new
tool, and the retired bannerlator-steam-compat script is removed from the
runtime. CI and local packaging include the renamed script.
* Drop the duplicate R import left by merging main
* Add userspace ntsync for Proton on Android
Android kernels have no /dev/ntsync and its app policy refuses futex_waitv,
so every Proton 11 build here fell back to wineserver for every wait.
libblsession now serves /dev/ntsync itself: wineserver opens a memfd region,
each sync object is a timerfd that carries its slot, and the kernel ntsync
ioctls are answered in shared memory with futexes, following the kernel
driver's wake order. Valve's Proton Experimental ARM64, GE-Proton and
proton-cachyos use it unchanged.
Locks record their owner so a killed process cannot wedge the others,
signals are held off inside each critical section, dead processes and
exiting threads are swept, and object lifetimes follow close, dup2, dup3,
close_range and received descriptors.
Fast sync is on by default under Performance > Session fixes, and
PROTON_NO_NTSYNC=1 turns it off per game.
* Add droiddeck-esync as the default sync for Proton on Android
Without a kernel ntsync driver, Proton 11 builds here fell back to
wineserver for every wait. droiddeck-esync brings eventfd and shared-memory
sync to the exact Proton build a game runs on: a pack holds that build's
ntdll.so and wineserver with the patch series in tools/droiddeck-esync
applied, and the guest runs Proton from a shadow tree that links the stock
tool and swaps in those two files. A wineserver from a pack still prefers
/dev/ntsync when a kernel driver or droiddeck-ntsync is there.
Packs are built in Valve's SDK image from each release's own wine source
(Proton Experimental ARM64 tags, GE-Proton and proton-cachyos releases); the
control build must reproduce the release binaries byte for byte, and a
signed index lists the packs. The APK bundles the packs pinned in
release.env, the app fetches newer ones, and Steam's compatibility tool
picks the pack for each Proton build, so new Proton releases get packs
without an app update.
The ntdll side reads, writes and polls its eventfds with raw system calls,
so the guest's LD_PRELOAD wrappers stay out of the sync path. The server
abandons a mutex once a thread killed by TerminateThread has really exited
and when its process dies, and a mutex's owner and recursion count change
in one atomic step, so a killed owner cannot touch the next owner's count.
droiddeck-esync is on by default and PROTON_NO_ESYNC=1 turns it off per
game; droiddeck-ntsync, the userspace ntsync, is now an opt-in toggle.
* Watch Valve's Proton releases and build droiddeck-esync packs for them
A scheduled workflow reads the Proton ARM64 builds Steam ships (anonymous
steamcmd app info) and the upstream source tags, compares them with the
previous watch state and starts the pack build for any build that has no
pack yet. The pack build applies the patch series with --fuzz=0 and runs a
smoke test of each new pack against the esstress suite before it is
published.
* Add droiddeck-fsync, keep Steam and the app on one Proton, fix DirectAudio
droiddeck-fsync: libblsession answers futex_waitv(2), which the app
sandbox refuses, in userspace, so Proton's own fsync runs on the stock
Proton files with no pack. Waiters register the words they wait on in a
table beside the fsync shared memory and sleep on a futex of their own;
FUTEX_WAKE on the fsync memory wakes the registered waiters. Slots carry
one owner word that the sweeper and the owner claim with a CAS, and the
mapping table is rebuilt under a lock held across the real munmap, so a
reused address or a recycled slot cannot lose a waiter. It stands in for
a Proton build without a pack (droiddeck-ntsync where fsync is off), takes
over for games with esync off, and the "droiddeck-fsync first" toggle
(BL_FSYNC_FIRST, also per game) puts it ahead of the packs. The games
Proton keeps off fsync and esync never get it. A launch into a prefix
whose wineserver is still running keeps that server's sync choice.
One Proton for Steam and the app: the Components page's Proton is the
default Steam uses, applied live through the client while Steam runs
(droiddeck-steam-compat) and at the next start otherwise; a choice made in
Steam's menu comes back to the app. Requests are ordered by a sequence that
never goes backwards, and the page no longer jumps back to the default
after a swap or restore.
DirectAudio: the wrapper wrote the driver key with its backslashes
stripped, so no game ever used DirectAudio. Wine 11 also loads a builtin
only from the prefix, so the driver is now linked into system32 and
syswow64 before "directaudio,pulse" is selected; mmdevapi falls back to
winepulse whenever DirectAudio cannot start.
* Pick esync, ntsync or fsync from the Steam settings' Games group
A three-way tab row above the FEX preset sets the sync Proton games use. It
writes the existing switches together (droiddeck-ntsync, droiddeck-fsync
first, droiddeck-esync), so the Performance toggles and the tabs always agree,
starts on esync and keeps the choice until it is changed again.
* Make droiddeck-fsync the default sync for Proton games
A fresh install, or one that never picked a sync, starts on fsync; a choice made
in the Steam settings' Games group still sticks. Games Proton keeps off fsync
still fall back to droiddeck-esync.
* Add wineserver to the Wine sync tabs and order them ntsync, fsync, esync, wineserver
wineserver turns every in-process sync off so games wait through wineserver;
picking any other tab turns sync back on. The tabs shrink to fit a narrow pane.
* Shorten the Wine sync description
* Answer openat2 and execveat for FEX in the session preload
FEX opens every file of its x86 rootfs with openat2(RESOLVE_IN_ROOT) and
only falls back to the host path on EXDEV. Under proot on Android openat2
answers ENOSYS, so each lookup of an x86 library silently went to the host
and missed. The exported syscall() now turns openat2 into openat once the
real call reports ENOSYS: RESOLVE_IN_ROOT paths are taken relative to the
root fd (FEX has already resolved the links inside the rootfs), and an
absolute path under RESOLVE_BENEATH fails with EXDEV as the kernel would.
execveat with an absolute path, or relative to AT_FDCWD, and without
AT_EMPTY_PATH or AT_SYMLINK_NOFOLLOW, is plain execve; it is sent as such
because proot refuses execveat with a directory fd, which FEX uses when it
re-executes itself for a child x86 program.
* Run x86 Linux games and programs through FEX
Steam: Linux-only titles that have no ARM64 build (from the client's
appinfo cache: type game, demo, application or beta) are mapped to a new
compatibility tool, droiddeck-fex ("Linux x86 (FEX)", linux to linux,
no required runtime). Valve's own "fex" tool needs pressure-vessel, which
cannot run under proot, so a mapping to it or to a Steam Linux Runtime is
replaced; any other pick the user made stays. Titles that also ship for
Windows stay on Proton. When such a title is installed and FEX or the
sniper runtime is missing, the client is asked to install them.
droiddeck-fex runs the program under the FEX that Steam installs (app
3127680), with Steam Linux Runtime 3.0 (sniper, app 1628350) as the x86
rootfs:
- the sniper platform is linked in place from its usr-mtree (relative
links only, files/usr -> .), once per runtime version;
- the x86_64 and i386 builds of libblsession and libfakeinput go into the
runtime's lib/<triplet>/droiddeck and its etc/ld.so.preload, mirroring
the session's own list, so x86 programs get the pads and the session
fixes (FEX passes their system calls straight to the kernel, so the
ARM64 preloads cannot reach them);
- Config.json sets RootFS and the GL and Vulkan thunks, so x86 games draw
with the device's Turnip and Mesa;
- the FEX preset and the game's own environment from the Steam settings
apply, and ARM64 entries are dropped from LD_PRELOAD/LD_LIBRARY_PATH.
It also links ~/.steam/sdk64 and sdk32 to the client's x86 steamclient
when the client has one and nothing is there yet.
Desktop: x86_64 and i386 AppImages can be imported now; they unpack
through FEX (or unsquashfs) and record their architecture. Scripts,
AppImages and programs started in a run session use FEX automatically
when they are x86, and each added app has a "Use FEX" Auto/On/Off choice
in its edit dialog. The launchers' "still running" checks also look at
FEX processes, whose exe is FEX rather than the program. A GitHub release
without an ARM64 AppImage falls back to its x86_64 one. Decky's x86
loader starts through droiddeck-fex instead of the fex-mesa rootfs path,
which no runtime ships.
The x86 preloads are built against glibc 2.31 (Debian 11) so they load
in sniper: tools/linuxfs/build-x86-preloads.sh, run in CI and by
build_local.sh. fakeinput's stat hooks fall back to __xstat on a glibc
without a stat export, and mmap64 takes off64_t for the i386 build.
* Keep a FEX unixlib from outliving its DLL
A FEX package or original bundle without the aarch64-unix helpers left
the previous version's libarm64ecfex.so / libwow64fex.so in the Proton,
so the new DLLs loaded a unixlib built for another FEX. A swap now removes
the helpers the package does not carry; FEX then runs DLL-only, which it
already falls back to when Wine cannot load the unixlib.
* Fix the Wine sync choices an audit found
- wineserver tab: it passed Proton's environment through, so a build with
esync built in (GE, cachyos) still ran esync and a kernel ntsync would
still be used. It now sets PROTON_NO_ESYNC, PROTON_NO_FSYNC and
PROTON_NO_NTSYNC (unless the game's own environment sets them).
- ntsync tab: a Proton whose wineserver has no /dev/ntsync client got
wineserver-only sync although fsync would work. The hash cache records
whether the wineserver has one; without it the launch goes to
droiddeck-fsync, and no stand-in or pack turns droiddeck-ntsync on.
- A build with esync built in returned before the per-game fallbacks, so
a game that turns esync off ran with no in-process sync. It now gets
droiddeck-fsync, or droiddeck-ntsync where fsync is off too.
- When a pack's proton cannot start and the stock one is used, or the
selection fails, the prefix's record now says stock, so a second
launch into the same running prefix no longer picks the pack's ntdll.
- droiddeck-fsync: its mutex is held across fork and re-made in the
child, a closed or replaced shm fd is forgotten (close, dup2, dup3,
close_range, closefrom), and a waiter woken while it was leaving on a
timeout or signal reports the wake instead of losing it.
- BL_SYNC_MIN_NOFILE applies per game to every verb, debug logs carry
prefixes.json, the device report names the chosen sync instead of the
three raw switches, and PATCHES.md and the proot notes describe the
selector, the fsync default and droiddeck-fsync's futex_waitv.
* Name the runtime's scripts and files droiddeck, migrating old installs
The guest scripts are droiddeck-* now (droiddeck-session and the other 19),
as are the files the app and scripts generate (etc/droiddeck, the network
state files, the components dir, the Steam install stamp, the redist marker,
the extra-Proton wrapper and backups) and the compositor's own names
(libdroiddeckwayland, droiddeck_* sources, DROIDDECK_* switches, the
wl_output and seat names).
Installed runtimes carry on: LegacyNames moves etc/bannerlator and
share/bannerlator over and leaves relative links at the old paths before
every proot command, turns any old script into a link to its new name,
moves the generated files and points menu entries at the new scripts.
The session scripts and steam-compatibility move their markers on first
use, the components dir's desired.tsv is rewritten with it, and the
runtime counts as installed under either session script.
Kept: the banner_ahb_v1/banner_desktop_v1 wire names and BANNER_AUDIO_DIRECT
(read by prebuilt Turnip and Wine builds), Banners-Turnip and other
third-party names, BL_* switches, libblsession, and credits to Bannerlator.
* Unpack x86 AppImages without FEX, then ask Steam for FEX
Importing an x86 AppImage failed when FEX was not installed yet ("needs FEX
to unpack and no unsquashfs is installed"). AppImages now unpack with
uruntime (VHSgunzo, MIT, v0.8.1 aarch64, pinned by sha256 and shipped
unmodified with its licence), which reads SquashFS and DwarFS images of any
architecture natively. FEX's own --appimage-extract and unsquashfs stay as
fallbacks, and an ARM64 image whose own runtime cannot unpack it goes the
same way.
An x86 import with FEX missing records that FEX is wanted, so the next
Steam session requests FEX and the Steam Linux Runtime, and the program's
page says FEX is not set up yet and how to get it.
* Run Vulkan Qt Quick AppImages on Wayland
OpenNOW (Qt 6.8, Qt Quick on Vulkan) closed within two seconds in a run
mode. The session sends toolkits to gamescope's Xwayland, and Qt's xcb
backend only presents with Vulkan when Mesa's X11 WSI does, which needs
DRI3; Xwayland on KGSL has none, so Qt found no queue that can present and
aborted ("Failed to create RHI").
An AppImage that bundles Qt Quick, the Vulkan loader and Qt's Wayland
plugin now runs on gamescope's Wayland socket (the desktop's, outside
gamescope), where Turnip presents as it does for games, with Qt's xcb
backend as the fallback. SDL_VIDEODRIVER and XDG_SESSION_TYPE follow, so
helpers that pick their window system from them (OpenNOW's streamer) agree
with Qt. Everything else stays on X11; a qt file in the app's directory
(wayland or xcb) overrides the choice.
* Keep gamescope's WSI layer away from Qt apps on its Wayland socket
OpenNOW still closed at once: its FFmpeg (the Raspberry Pi fork, libavutil
61) creates its Vulkan queues internally synchronized whenever the driver
offers VK_KHR_internally_synchronized_queues, which DD-Turnip does. The
gamescope WSI layer registers every queue of a new device through
vkGetDeviceQueue, which only returns queues created without flags, so it
got VK_NULL_HANDLE and vkroots aborted on assert(obj) before Qt opened a
window.
Programs that draw on gamescope's Wayland socket do not need the layer,
which only carries X11 windows past Xwayland, so it is turned off for
them. OpenNOW bundles no Vulkan loader (it reaches Vulkan through Qt and
dlopen), so a binary that uses QVulkanInstance counts as a Vulkan app too,
and a Qt Quick app left on X11 says why in the session log.
* Keep the end of the session log, and say when FEX is missing
The session sends its output through head -c into session.log. head
writes through stdio, so it held up to 4 KB that proot's --kill-on-exit
threw away when the guest ended: every log stopped mid-line at a 4096-byte
boundary, losing exactly the lines that say why a program quit (an x86
AppImage's "x86 Linux programs need FEX" among them). dd writes each read
as it comes and keeps the same cap.
A run mode always ends with status 0 (gamescope does not pass its child's
on), so a program that could not start just closed. When the log says FEX
is missing, the ended screen now says so and how to get it.
The app reads FEX's readiness from status.json, which only a launch or an
import wrote, so it still said "not set up" after Steam installed FEX.
droiddeck-fex status rewrites it, and a Steam session ends with it while
FEX is wanted. FEX is also looked for at the tool's root and under files/,
and a tool folder without it lists what it holds.
* Let FEX and its runtime install runnable on an SD card library
A Steam library on shared storage loses the executable bits, so native
tools are staged in private directories bound over it; only Proton and
SteamLinuxRuntime folders were. FEX (3127680) installed there could never
run, droiddeck-fex saw no FEX and kept asking Steam for it. FEX and the
sniper runtime (1628350) now get private directories from their first
download, whatever their install folder is called.
* Keep fsync off in the pack smoke test
A runner whose kernel allows futex_waitv started stock Proton with fsync,
so the server-side baseline never said what the test waits for and every
pack was waved through as untestable; the esync run would have measured
fsync too.
* Judge a pack against stock's own esstress failures
Stock Proton fails esstress's dup wait all under server-side sync as well
(a Wine bug, seen on the phone too), and any stock failure made the test
call the runner unusable. A pack now fails only when it crashes, hangs or
fails a check stock passes.
* Ask Steam for FEX and its runtime one at a time
Both steam://install requests were started together, and the running client
took only the first: FEX installed, the sniper runtime FEX needs never did.
Each request now waits for the client to take it before the next.
* Bundle the first published droiddeck-esync packs in the apk
* Log how an x86 program under FEX ends
FEX keeps its own errors quiet unless asked, so a program it could not run
left nothing in the session log. Its log now goes to stderr, and the AppImage
launcher records the program's exit status or the signal that ended it.
* Show the log a failed AppImage program wrote
Programs like Eden stop themselves on a failed check and say why only in
their own log under the home folder. When the program ends badly, the end of
any log it wrote during the run is copied into the session log.
* Report where an x86 program under FEX hit an illegal instruction
A tiny x86_64 preload, built without libc, catches SIGILL and writes the
address, the instruction bytes and the mapping they belong to before the
program dies as it would have. droiddeck-fex preloads it into x86_64 programs.
* Load the fault reporter from the x86 runtime
Programs under FEX look libraries up in the x86 runtime, so the reporter is
copied there with the other preloads and named by its path inside it.
* Hand FEX its x86 runtime and thunks through the environment
Valve's FEX runs portable and reads its config beside itself, so the
Config.json droiddeck-fex writes was not seen: programs ran without the
runtime. The runtime, thunk libraries and thunk list now also go in FEX's
own environment variables, and each launch says what it was given.
* Use the sync pack built for the installed Proton release
Some Proton releases ship byte-identical ntdll.so and wineserver (Valve
11.0-2b/2c, CachyOS 0702/0703), so a pack built for a newer release
matched an older install exactly and the older install never fetched its
own pack. A pack from a newer release no longer counts as an exact match;
among matches the one built for the installed version wins, then rev.
The app ranks the pack a tool already uses the same way and only fetches
a pack that ranks higher, reads the release epoch from tools.tsv and
refetches when tools.tsv changes. A prefix whose server is still running
re-checks its recorded pack on waitforexitandrun and starts fresh when a
better one now applies.
* Keep published sync packs and revocations consistent
The publish step never replaces a pack that has an entry beside it; a
pack left without its entry by an interrupted run is replaced so the
build stops repeating. Discovery counts revocations the signed index does
not show yet, including superseded packs only the flavor releases list,
so the index is signed again. The release watch always builds every
flavor.
* Fetch the droiddeck-esync packs from DroidDeck-Components
The packs, the signed index and the apk bundle now live in the releases
of Droid-Deck/DroidDeck-Components, together with the pipeline that
builds them, so this repository keeps only the app and the guest code
that consumes them. The app's index and asset URLs point there,
release.env names the repository its bundle comes from, and the apk
builds drop bundled packs that the published index revokes.
* Stop the apk build when the published sync index cannot be read
* Ask Steam for one FEX dependency at a time
The client shows a confirmation dialog for each steam://install, and a
second request replaces the first dialog, so FEX was never installed
when the runtime was requested right after it. The next dependency is
now requested once the previous one has an app manifest.
* Use generic names in the AppImage test fixtures
* Give x86-64 apps under FEX the Vulkan thunk
Apps that bring their own glibc and Vulkan loader skipped FEX's thunk
overlay and loaded their bundled desktop Mesa drivers, which crash on the
phone's GPU during Vulkan setup. droiddeck-fex now adds an x86-64 audit
module when a program's bundled glibc and libstdc++ meet the thunk's
version needs. The module sends libvulkan.so.1 lookups to a nodelete stub
that needs FEX's thunk path. That keeps the thunk mapped when an app
unloads Vulkan and loads it again, since FEX keeps its first trampoline
links and the old addresses get reused.
The fault reporter now restores the default action before re-raising,
because FEX ignores SA_RESETHAND and the handler looped.
|
||
|
|
4a234b2824 |
feat: Flatpak apps and a Flathub store (#77)
* feat: run Flatpak apps through a proot bwrap stand-in and add a Flathub store * feat: give Flatpak apps the KGSL GPU, the controllers and a CPU LLVM can target * feat: Flatpak games on the desktop, Store apps on the Desktop page, safer remove * test: cover the sandbox planner and store helpers; docs: explain Flatpak on DroidDeck * fix: keep controller focus through Store tabs and app pages; show progress per Flatpak step * fix: let Chromium, Electron and Firefox Flatpaks start without their own sandboxes * fix: fetch Flatpak's supporting libraries when the runtime lacks them * fix: add Flathub without a download, log store commands, keep Electron apps on X11 under gamescope * feat: import ARM64 AppImages from storage and run them from the Desktop page * fix: report failed Flatpak installs as failures and deploy runtimes that ship a resolv.conf link * fix: let Flatpak create its repo where Android denies hard links * fix: point store commands at the current network's DNS * fix: keep failed Flatpak extensions non-fatal, give Electron AppImages a bus, X11 and time to relaunch * docs: AppImage import and what x86 apps would take * feat: put the Flathub Store and AppImage import behind beta toggles in Setup --------- Co-authored-by: MaxsTechReview <maxjividen@gmail.com> |
||
|
|
f87289f75b |
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.
|
||
|
|
fff1e837d3 |
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. |
||
|
|
7c6df51bfa |
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. |
||
|
|
09e5172052 |
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). |
||
|
|
132b434d78 |
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. |
||
|
|
347a5a4dcb |
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". |
||
|
|
6192d5be2c |
Desktop: Vulkan by default; a renderer that fails to start is remembered
vulkan is the default desktop renderer (settings list it first). When labwc cannot start on a GPU renderer the desktop falls back to pixman as before, and now records the renderer with the patched wlroots and Linux driver it failed on, so later desktops go straight to pixman instead of waiting 20 s each time; an app update, a different driver, or choosing a renderer again in the settings (which deletes the record) retries. |
||
|
|
ae863cc613 |
Controller profiles for every desktop emulator; PC keyboard under half the screen
bannerlator-pad-defaults now covers DuckStation, PCSX2, Dolphin (GameCube and Wii), Cemu, melonDS, PPSSPP and RetroArch as well as RPCS3, from each project's source: files an emulator would otherwise fill with keyboard-only defaults are seeded when missing (Dolphin, Cemu, PPSSPP, RPCS3), or given SDL bindings in the config the emulator wrote itself when nothing binds a controller yet (DuckStation, PCSX2 with its SettingsVersion, melonDS). RetroArch gets an Xbox 360 profile for its sdl2 driver and is moved off udev, which finds no pads in the runtime. The desktop re-runs it every 30 s, so an emulator's first config is covered for its next start. The PC keyboard takes 47% of the screen height, header included. |
||
|
|
a6bab67508 |
Desktop programs: controller seen by every emulator, Player 1 profiles, big-core pinning
- The pad keeps Steam Input's virtual-gamepad identity only in Steam sessions. SDL ignores a Steam virtual gamepad unless run under Steam, so on the desktop and from the rail every SDL emulator saw no controller at all; there it is a plain Xbox 360 pad now, which SDL and evdev map by themselves. - bannerlator-pad-defaults writes Player 1 on the controller for emulators that have no profile yet (RPCS3 first: without one it takes the keyboard). Run at desktop start and before a program from the rail; never overwrites. - The desktop and everything started from it, and a program from the rail, run on the game cores when chosen, else every core but the slowest cluster (program_cores); BL_PIN_CORES=0 turns it off. Game cores reach every mode. |
||
|
|
b9ec8458f8 |
Desktop: remote runs from ~/.cache/droiddeck/run behind ~/.droiddeck-remote-run
For driving the desktop from a debugger: a script dropped there runs once inside the session. Off unless the marker exists. |
||
|
|
60d53fda47 |
Desktop GPU: full labwc log on the GPU renderers; a labwc that hangs at start falls back to pixman
The vulkan desktop sat on the loading screen: labwc connected and never opened its window, and it did not exit, so the exit-based fallback never fired. The launcher now asks labwc's socket for an answer (wayland-info, 3 s) for up to 20 s, then stops it and starts the desktop on pixman. labwc runs with -d on vulkan/gles2 so desktop.log shows where it stopped. |
||
|
|
29597c3fbe |
Desktop GPU: menu games run in their own gamescope; labwc on the patched wlroots
droiddeck-gpu runs a program in a gamescope of its own on the app's compositor (wayland-0), full screen over the desktop - the path the rail's play chips use, where Vulkan works. droiddeck-desktop-gpu gives every Game/Emulator menu entry a per-user copy through it (auto: while the desktop is on pixman), keeping 'Run in a desktop window' as an action. droiddeck-desktop loads /usr/local/lib/droiddeck-wlroots for the vulkan/gles2 renderers and falls back to pixman when labwc stops at start. The build stages the wlroots release named by tools/wlroots/release.env, once published. |
||
|
|
ae6dcc9798 |
Rename the app SteamDeck → DroidDeck
App name, app ID and code package: DroidDeck, com.droiddeck.launcher (sources moved to com/droiddeck/launcher, the 68 JNI functions renamed with them). The new app ID installs beside SteamDeck rather than over it. Everywhere the name was the app's own: the sidebar title, the session report, share zips, the shell title, wake-lock and log tags, User-Agents, the Compose theme, the Download folder and switch files (droiddeck-env, -osc, -driver, -tu-debug, -no-pad, -pad-log, -no-hud, -wlr-renderer; the old names are not read), and inside the runtime (droiddeck-desktop, Firefox's droiddeck.js, the shortcuts tag, the rumble socket, debug and cache paths). Build scripts, CI artifact (droiddeck-apk), CMake project, README and the progress log follow. Kept on purpose: Valve's Steam Deck (the -steamdeck flag, steamdeck_publicbeta/stable, 'Steam Deck mode', the steamos.cloud package URLs) and names inside the hosted desktop package (steamdeck.png, steamdeck-steam, steamdeck-bigpicture). 'Desktop installed' now tests for labwc instead of the launcher the app stages itself. A committed __pycache__ .pyc is removed. |
||
|
|
b28e91128f |
The desktop uses the client's own game entries; a steam shim hands them to the app
The client already writes one menu entry per installed game (steam steam://rungameid/<id>, with the game's icon); they were dead for want of a steam command, and r45 added a second entry per game beside them. Now: steam on the desktop is a shim that hands off to bannerlator-steam-launch (and is the client itself anywhere else), and bannerlator-desktop-games writes an entry only for a game the client wrote none for. |
||
|
|
d0ca41d160 |
The client's games on the desktop, launching Steam's desktop UI under gamescope
bannerlator-desktop-games writes one menu entry per installed game (both libraries, the client's own artwork) and links Steam Games / SD Games in the home folder. The entries, and the menu's Steam / Big Picture ones, run bannerlator-steam-launch: the client cannot draw on the desktop (labwc, no dma-buf), so it leaves a request in the session directory; the service watches it (FileObserver), ends the desktop session and hands the activity a Steam session to start - desktop UI (BL_STEAM_UI=desktop drops -gamepadui) with the game's rungameid URL. |
||
|
|
aa047ce942 |
Logs: one folder per session, a device report, and credentials scrubbed
A session used to leave a loose session-<stamp>.log in Download/SteamDeck and a compositor log in a different folder entirely, with Steam's own logs copied beside the first one only if the session exited cleanly - which the sessions worth reading never do. Reports arrived needing three questions answered before anything could be read: what device, which drivers, which settings. Now each session claims Download/SteamDeck/session-<stamp>/ and everything lands in it: device.txt, session.log, wayland.log, steam.log plus steam/ in Steam mode, desktop.log in desktop mode. The folder is claimed by whoever starts first, since the activity starts the compositor before the service starts the session, and the compositor is told where to write through its environment - it opens that file once, so the service also copies it in at teardown, which covers the second and later sessions of one process. device.txt is written before the session starts, so a session that dies in its first second still says what it ran on: model, SoC, Android, kernel, cores and ceilings, RAM, the GPU as KGSL names it, the panel, the driver each half of the session chose, the runtime version, every switch in effect, and whether Android is set to kill the session's child processes. Nothing identifying is collected - no serial, no device or advertising id, no account name, no network names - and Steam's logs are scrubbed line by line on the way in, with Bannerlator's patterns: session tokens (including the bare numeric "Using JWT" form), machine-auth GUIDs, WebAPI keys, Guard codes, emails, and SteamIDs masked to their last four digits so lines still correlate. loginusers.vdf, config.vdf and the ssfn files are never copied. Also from Max: a switch to run proot without its seccomp acceleration (PROOT_NO_SECCOMP=1), for kernels that handle that filter badly - ENOSYS from calls that plainly exist is the signature, which is what the Fold's storm looks like; and the phantom-process warning above, which is his "your OS killed it". |
||
|
|
c18fe1a86e |
Desktop: turn Firefox's child-process sandboxes off
The screenshot shows the tab crashing while the chrome around it draws text perfectly, and the 'no fonts' line is an annotation on that crash, logged by the child. The parent reads the fonts; the child, sandboxed with seccomp and namespaces that do not behave under proot, cannot, and Gecko takes a fatal path with no usable face. The prefs for this are advisory and a profile can override them, so the sandboxes are turned off in the environment the session hands every program it starts. |
||
|
|
ce9cf2bdf3 |
Desktop: name a default font family, and rebuild fontconfig's cache once
Firefox's own network log shows it fully online - DNS answering for both families, sockets connecting, HTTP/2 and HTTP/3 sessions carrying data - so the blank pages were never the network. They are the fonts: Gecko reports 'no fonts' with 13 families found, which is what it says when no generic family resolves to a face. The linked rules map sans-serif onto faces a full distribution installs; this rootfs has DejaVu and nothing else, so local.conf names it outright for every generic, and the cache built into the image is rebuilt once so the new rules are seen. |
||
|
|
6c380528f3 |
Desktop: give fontconfig its default rules
/etc/fonts/conf.d in the rootfs holds only the README: none of fontconfig's rules that map sans-serif, serif and monospace onto installed faces. Programs find the fonts and no default font; Firefox logs 'no fonts' and draws pages without text. The desktop launcher links the 33 default rules in when the directory has none. |
||
|
|
5417587ac4 |
Desktop: Firefox writes its network log in debug runs
The session reaches the internet over both families (r32's probe), so a browser saying otherwise has to explain itself: with the debug marker set, Firefox logs its name lookups, connects, HTTP transactions and link/offline decisions to ~/.cache/steamdeck/firefox-net.log. |
||
|
|
3d4cfededf |
Desktop: keep Firefox out of Work Offline, and probe the network in debug runs
Firefox decides whether it is online by dumping the routing table over netlink, which Android denies to apps; it sees no default route, switches to Work Offline and every page fails while the network is fine. A defaults file staged into Firefox's pref directory turns that off, and drops the process sandboxes that have nothing to set up under proot. Debug runs now log a name lookup and a fetch over IPv4 and IPv6 from inside the session. |
||
|
|
36b0bea470 |
Compositor: tell a nested toplevel the output's size
labwc's Wayland backend, configured with 0x0, opened wlroots' default 1280x720 window and the whole desktop was upscaled from it - the r29 and r30 logs both show the output at 1280x720 whatever rc.xml and wlr-randr asked. The configure now carries the output's size; gamescope is told the same numbers on its command line, so nothing changes for the Steam client. |
||
|
|
8362f48750 |
Desktop: name the panel in panel.conf, size the nested output to the app's surface
The panel was there all along, a bare strip at the top: the first package's panel.conf described a panel it never named in [General] panels=, so lxqt-panel built itself a default one with no plugins. panel.conf now travels with the app like the rest of the desktop's defaults, and the old nameless file on a device is replaced once. The nested labwc output was 1280x720 - wlroots' default window - with the desktop upscaled from that; rc.xml now carries the app's surface size and the autostart sets it again via wlr-randr. Debug runs keep each program's full output under ~/.cache/steamdeck/. |
||
|
|
f10919d4be |
Desktop: give pcmanfm-qt's desktop the wallpaper, and a debug marker that logs window mapping
The desktop came up black with the panel alive but unseen. pcmanfm-qt's desktop surface, unconfigured, paints solid black over swaybg's wallpaper; it now gets the wallpaper. With ~/.steamdeck-desktop-debug present, labwc logs at debug level and the panel and file manager log their shell, layer and output protocol traffic, capped, so where a window went can be read off the session log. |