Commit Graph
42 Commits
Author SHA1 Message Date
lucannez64 de3bbe94b1 Extract runtime compatibility fixes from PR 41 2026-10-17 23:04:23 +02:00
lucannez64 d4dcd31a21 Merge main into setup runtime safety, preserving certificate setup 2026-10-17 22:56:34 +02:00
Nicolai Bruns 57b1df9e0b fix(setup): validate final runtime destinations 2026-10-17 22:24:06 +02:00
Nicolai Bruns 2e201dd19b fix(setup): use consistent runtime paths and reject incomplete installs 2026-10-17 22:09:29 +02:00
lucannez64 3264ca86fa Test merge root certificates 2026-10-17 21:08:12 +02:00
lucannez64andClaude Opus 5.5 52a6dae432 Build Darling's system root store from the host CA bundle
Security reads the system trust domain from
/System/Library/Keychains/SystemRootCertificates.keychain and
SystemTrustSettings.plist (TrustSettingsSchema.h). Darling ships neither, so
SecTrustSettingsCopyCertificates(kSecTrustSettingsDomainSystem) returns
errSecNoTrustSettings (-25263); Chromium's known_roots_mac and Riot's
CertBundle then report that they cannot read the system roots.

ensure-darling-root-certificates.py parses each host root with a minimal DER
walker and writes the trust record keyed by the uppercase SHA-1, with the
encoded issuer Name, the serial INTEGER's content octets, modDate and an
empty (unrestricted) trustSettings array. The keychain is built with the
guest security tool in one darling shell, in a private temporary directory,
and published from inside the guest so a running Darling sees it, falling
back to the host when the guest cannot write the directory. A digest stamp
skips later runs without starting Darling. The launcher warns and continues
on failure; install-runtime.sh runs it before stopping Darling.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 21:03:32 +02:00
lucannez64andClaude Opus 5.5 40f7a650d1 Report the host GPU name and VRAM from MTLDevice
-[MTLDevice name] returned "Darling Indium Device" for every GPU. It now
returns the selected Vulkan device's name in macOS Metal style: the
trailing driver note in brackets and the (R)/(TM) marks are removed, and
NVIDIA names are unchanged. The name is never replaced with another
vendor's. recommendedMaxWorkingSetSize is the device-local heap size on
discrete GPUs and all heaps on integrated/CPU devices, with the old 1 GiB
as fallback. Both are computed once per device.

hasUnifiedMemory stays YES by default: synchronizeResource:/
synchronizeTexture: are missing and Private buffers created with data
abort in Indium, so reporting NO on discrete GPUs would send apps down
unimplemented paths. DARLING_METAL_HOST_UNIFIED_MEMORY=1 opts in to the
GPU-type answer. DARLING_METAL_GPU_NAME and DARLING_METAL_VRAM_MB
override the name and working set.

The cleaning logic lives in private-include/Metal/MTLDeviceInfo.h and is
covered by the host check tools/test-metal-device-info.cpp. Metal now
links indium_private for the Vulkan properties, and the runtime build
script adds Indium's private headers before compiling MTLDevice.mm.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 20:49:42 +02:00
lucannez64 fc57385c68 Keep Metal presentation active in mixed IOSurface layer trees 2026-10-17 01:06:50 +02:00
lucannez64 698d295b6d Merge PR #18 visible-cursor tracking with serial-aware mouse warps 2026-10-17 00:26:47 +02:00
lucannez64 44faf79bd8 Merge PR #15 fullscreen transitions with runtime review fixes 2026-10-17 00:26:09 +02:00
lucannez64 6c742155e9 Fix runtime safety, Xorg mouse synchronization and fullscreen startup 2026-10-17 00:25:34 +02:00
DevWebeloperandClaude Opus 5.5 8c01fe1547 Keep the relative-mode cursor on the visible pointer when warps are not honoured
League enters relative mouse mode on GNOME (Xwayland) and inside gamescope, but
keeps a visible cursor and warps it every frame at its own mouse speed. Xwayland
cannot move a visible pointer, so those warps never took effect: the virtual
cursor, where clicks land, drifted hundreds of pixels from the cursor on screen
and never reached the screen edges, which also stopped edge panning.

Where warps are not honoured, the virtual cursor now follows the physical
pointer and the game's warps leave it in place. With a hidden cursor, or on a
server that honours warps, nothing changes. The host model test gains a case
replaying the drift from an in-game trace.

Tested manually in the practice tool under gamescope 3.16.31 on GNOME 51 with
AMD RADV: clicks land on the cursor and edge panning works.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-17 00:49:53 +03:00
lucannez64 ed9cc8310a Restore X11 fullscreen requests for monitor-sized borderless windows
Port the fullscreen policy omitted when adapting PR #12. Track requested fullscreen state across frame and style changes, exclude unmanaged windows, and use EWMH REMOVE when leaving fullscreen.

Extend the native geometry probe and document passive tracing for the reported vertical click offset, whose cause remains unconfirmed.
2026-10-16 17:13:11 +02:00
ztancrellandClaude Opus 5.5 4f7916370a Return a real physical size from CGDisplayScreenSize; never return NULL display modes
CGDisplayScreenSize returned 0x0 for any display with EDID (upstream left
that branch unimplemented). League divides by it for its camera aspect
ratio, so the view-projection x row became NaN: every 3D vertex was
discarded, the scene showed only its blue clear colour, and world clicks
were ignored. Read the size from the EDID detailed timing (mm) or basic
parameters (cm), fall back to 96 dpi, and use the main display for an
unknown id.

CGDisplayCopyAllDisplayModes returned NULL for display 0 (a window off
every screen), which League passes straight to CFArrayGetCount. Fall back
to the main display, then to an empty array.

Add riot-display-modes-check covering both for the main display,
display 0 and an unknown id.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16 10:44:04 -04:00
lucannez64andMaka d89a303ebe Fix X11 primary-monitor coordinates without changing fullscreen policy
Adapt the geometry fix from PR #12 to the current relative-mouse implementation. Keep display IDs independent of primary-first screen ordering, translate window and pointer coordinates consistently, and invalidate geometry on both RandR event types.

Handle failed RandR snapshots and free EDID data. Add isolated native geometry regression coverage and use the configured SDK when linking the X11 probe.

Validated all 30 component patches, the X11 and CoreGraphics builds, six native geometry groups, and the existing relative-mouse checks. The user confirmed the installed fix works on 2026-10-16.

Co-authored-by: Maka <[email protected]>
2026-10-16 15:52:42 +02:00
lucannez64andClaude Opus 5.5 70fd5fdebd Emulate macOS relative mouse mode in the X11 backend and skip redundant cursor updates
CGAssociateMouseAndMouseCursorPosition(false) used to warp the pointer to the
window center, freeze the reported position there and treat the game's own
CGWarpMouseCursorPosition calls as motion. On Xwayland, which ignores warps
while the cursor is visible, this left League's cursor stuck in the middle.
The backend now keeps a frozen virtual cursor: physical motion only produces
deltas (deltaY positive downwards), application warps move the virtual cursor
and their echoes are dropped, mouseLocation returns it, and the pointer is only
warped back where the server honours warps. The grab no longer uses the
invalid FocusChangeMask and is released and retaken across focus changes.

setCursor: no longer re-sends XDefineCursor/XFlush when the window already has
that cursor; League set it about 190 times per second.

Also carries the opt-in input trace (/tmp/rclol-input-trace in the guest).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16 15:14:06 +02:00
lucannez64 937e632bcf Prepare nested Metal layers before compositing
Traverse the layer tree before compositing so nested Metal layers consume queued drawables and recycle their pool. Add a nested presentation probe covering pool reuse and Vulkan-to-OpenGL pixel readback.
2026-10-16 13:55:09 +02:00
lucannez64 3d03548b54 Avoid blocking X11 cursor updates on a server round trip 2026-10-16 13:44:11 +02:00
lucannez64andClaude Sonnet 5.5 6d5d04ff71 Use optimal tiling for the drawable GL import on NVIDIA
NVIDIA's GL rejects GL_LINEAR_TILING_EXT with GL_INVALID_VALUE, so the
linear internal image could not be imported and the window stayed black.
Pick the tiling by GL_VENDOR; other drivers keep linear.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-16 11:16:53 +02:00
lucannez64andClaude Opus 5.5 f7eef7d88a Make the CFHost cancel probe wait for delivery and reject completed lookups
Wait up to 2 s for the cancellation callback instead of one 50 ms run-loop
pass, count only callbacks without stored addresses so a completed lookup
cannot pass as a cancellation, print the failing stage, and have the runner
require the exact success line since Darling can exit zero after a trap.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16 09:09:28 +02:00
Hitalo M. 12b3b03a0f Fix Riot Client crash when cancelling CFHost resolution 2026-10-16 09:09:28 +02:00
lucannez64andClaude Opus 5.5 908f88bad7 Allocate League's Metal drawables in VRAM
League sets framebufferOnly=NO on its CAMetalLayer, and QuartzCore read
that as needing host-visible coherent memory, so the game's final
render target and the linear image handed to OpenGL both lived in
system RAM (type 2 on the RX 6600) and crossed PCIe every frame.
framebufferOnly=NO only lets Metal sample or blit the texture: nothing
maps either image (replaceRegion aborts, getBytes is a stub, Indium
maps only Shared/Managed buffers).

Drawables now take the first allowed DEVICE_LOCAL type whatever
framebufferOnly says; the guest file /tmp/metal-no-drawable-vram
restores the old placement. metal-device.log shows drawable-vram=on and
storage=vram.

A native EGL/RADV test exported the drawable's linear image from VRAM
and imported it into GL with no errors and identical pixels. In a
practice-tool baron fight on the RX 6600 with the same champion it ran
about 20 FPS faster and the same when idle; not yet measured in an ARAM.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16 02:17:51 +02:00
lucannez64andClaude Opus 5.5 60ebfda63f Prefer VRAM for GPU-only Metal memory and mark the GL import dedicated
Indium and QuartzCore took the first memory type a resource allowed. The
Vulkan spec orders a type with no flags before every DEVICE_LOCAL type,
and NVIDIA exposes such system-RAM types, so on NVIDIA private buffers,
textures and framebufferOnly drawables could land in system RAM. They
now take the first allowed DEVICE_LOCAL type and fall back to the old
choice; shared and managed resources are unchanged.

The drawable's exported image is a dedicated Vulkan allocation, but the
OpenGL import never set GL_DEDICATED_MEMORY_OBJECT_EXT, which
EXT_external_objects requires. Mesa ignores it; it is the suspected
cause of the black screen on NVIDIA in issue #3. The import's GL errors
were never checked (reportGLErrors is compiled out), so a failure was
silent.

/tmp/metal-device.log now lists the selected device's memory heaps and
types, the memory type chosen per resource kind (with the old choice and
changed=yes/no), and the result of the first drawable and semaphore
imports into OpenGL (later ones only on failure).

Practice match on the RX 6600: all choices changed=no, import
dedicated=yes with no GL errors, semaphore ok, match=yes. Not run on
NVIDIA.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16 02:04:43 +02:00
lucannez64andClaude Opus 5.5 3cf599c62e Log the Metal GPU and create a Vulkan device only for it
On a hybrid laptop (issue #3) Indium took whichever Vulkan device the
loader listed first, usually the integrated GPU, and still created a
VkDevice on every other supported GPU, waking a discrete GPU it never
used. Drawables reach the presenting OpenGL context as opaque FDs, which
only work on one physical device, and nothing checked that.

Indium now appends the device list, the selected device and the reason
to guest /tmp/metal-device.log, and creates a VkDevice for the selected
device only (/tmp/metal-all-devices restores the old behaviour).
/tmp/metal-gpu or METAL_INDIUM_GPU selects a device by index or name
for diagnosis. QuartzCore logs the presenting GL renderer and compares
its device UUID with the Vulkan device's (match=yes / MISMATCH); it
queries Vulkan itself, so it needs no new libindium export.

On the RX 6600 desktop the game selected RADV, created 1 VkDevice of 2
supported (lavapipe no longer gets one) and logged match=yes in a match.
Running on NVIDIA through prime-run is documented but not validated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-16 00:24:58 +02:00
lucannez64 c483f44ede Keep Iridium LLVM headers and runtime library on the same major 2026-10-15 23:22:15 +02:00
lucannez64andClaude Opus 5.5 96da34a633 Add an update script that re-applies changed patches
After a pull that changed a patch, prepare.py stopped: the patch neither
applied nor reverse-applied to a tree holding its earlier version. Now
it looks for the earlier version applied in that component -- the copy
it records in build/applied-patches, or a version from this
repository's history -- reverts exactly it and applies the new one.
It never resets a repository; when nothing matches it stops and names
the repository with other edits, and it restores the earlier version
if the new one does not apply.

scripts/update.sh runs build.sh, the base install and
install-runtime.sh, and refuses to start while a Riot Client or League
process is open, since the install steps stop Darling.

Checked on a sandbox Indium checkout holding the previous patch: the
result matches a clean apply, a second run is a no-op, an unrelated
local edit survives and a conflicting one stops with the error.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 22:11:26 +02:00
lucannez64andClaude Opus 5.5 3e76087dbe Translate LLVM 23 vector splat constants in Iridium
LLVM 23 represents vector splats such as `<3 x float> zeroinitializer`
as vector-typed ConstantFP/ConstantInt values instead of
ConstantAggregateZero/ConstantDataVector. Iridium only handled scalar
ConstantFP/ConstantInt, so on hosts with LLVM 23 nearly every League
shader failed to translate: the r3dlog fills with "Failed to compile
shader", the loading screen hits "Material Missing Pipeline" and the
game crashes. Our matches had only run the overlay pinned to LLVM 22.

Declare the scalar element and splat it into a constant composite.
Offline, on the 74,112 metallibs in ShaderCache.metal.wad.client,
LLVM 23 went from ~2% to 74,108 translated, the same set as LLVM 22
(the 4 remaining failures are pre-existing on both); a sample of the
LLVM 23 SPIR-V passes spirv-val for Vulkan 1.3. Confirmed in a match
with the Iridium overlay built against the system LLVM 23.

RIOT_IRIDIUM_SYSTEM_LLVM=1 makes build-riot-indium-runtime.py ignore
the LLVM 22 pin, to build what a fresh checkout gets.

Refs #1

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 22:05:05 +02:00
lucannez64 e94c3ce40f Fix League client resizing and runtime compatibility
Fix X11 presentation handoff after resizing, preserve NSView size callbacks, and correct content and backing-layer geometry. Add CoreText font enumeration for the language dropdown and rebuild/install the matching runtime overlays.

Correct CarbonCore Gestalt version queries and roll back proc_listpids for Vanguard testing. Document that VAN -101 can still recur. Include accumulated CoreAudio stream and AudioUnit corrections.

Add standalone font, version, resize and publisher-handoff regressions. Record manual confirmation of the language dropdown and window resizing; all 29 pinned patches and the source/script audit validate.
2026-10-15 18:44:43 +02:00
lucannez64 cbf878ea6c Remove Riot client/game automation, inspection and capture tooling
Drop the tooling that drives, automates, inspects, profiles, captures or
patches the Riot client and League game process, plus the historical
research/tools probes. These were never part of the supported workflow and
involve synthetic input, attaching to Riot's process, driving its local API,
or patching its binaries.

Removed from tools/: the baron-* and practice helpers, uinput_click.py,
lcu-practice-game.py, check-riot-vanguard.py, the riot-league-* / riot-open-url-*
inspector hooks and API/state helpers, the riot-*-watch.py observers,
riot-match-capture/ profilers, riot-cursor-watch/, the analyze-*/symbolize-*
profilers, capture-game-perf.py, the native VPX bridge and the client
log-dir/autofill shims. Removed all of research/tools/.

The supported launch/install pipeline is unchanged: scripts/, the launcher and
ensure-* helpers, fetch-installer.sh, stop-darling-runtime.py, the
build-*-runtime / build-m58f3* runtime builders, the install-* overlays and
offline installer checks, and the standalone operator/-check regression probes
are all retained. Docs that referenced the removed tools were updated.
2026-10-15 13:00:01 +02:00
lucannez64 9e8165e056 Fix client window visibility in Darling AppKit, not by patching Electron
Electron 22.3.27's NativeWindowMac::IsVisible() compares the window's
occlusion state for exact equality with NSWindowOcclusionStateVisible:

    bool occluded = [window occlusionState] == NSWindowOcclusionStateVisible;

Apple's contract is a bitmask: an on-screen window's state *includes* that bit
(tested with &). The exact == test is inverted, so an Apple-correct value made
every ordered-in window look occluded and the client's visible/not-minimized
checks failed. The previous workaround byte-patched Riot's shipped Electron
Framework to flip that comparison.

Fix it in Darling's AppKit instead: -[NSWindow occlusionState] now also reports
the reserved 1 << 2 bit for an on-screen window. &-based readers (Electron's own
windowDidChangeOcclusionState:, Chromium) still see NSWindowOcclusionStateVisible
set, while the exact == test is false, so unpatched Electron resolves
IsVisible() correctly. No Riot binary is modified.

Delete tools/patch-riot-electron-visibility.py and its call in
install-riot-gpu-runtime.sh; sync README and docs/STATUS, which already
described the binary patch as excluded.
2026-10-15 12:46:48 +02:00
lucannez64 6085f98f64 Remove library injection from Riot Client launches 2026-10-15 12:11:19 +02:00
lucannez64 e554644d0d Implement legacy IOKit power assertions with host idle inhibitors 2026-10-15 12:05:30 +02:00
lucannez64 e2f1392369 Implement IOKit system sleep and wake notifications through logind 2026-10-15 11:37:25 +02:00
lucannez64andClaude Opus 5.5 084e003f79 Request the X11 EGL platform in iokitd
iokitd passed an Xlib Display to eglGetDisplay(), so Mesa chose the
platform from EGL_PLATFORM. Wayland sessions often set it to "wayland",
and the first darling command passes its environment to every guest
service; Mesa then treated the Display as a wl_display, iokitd crashed
in pthread_mutex_lock and launchd restarted it every 10 seconds. Use
eglGetPlatformDisplay(EGL_PLATFORM_X11_KHR, ...) as OpenGL already does.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 10:07:36 +02:00
lucannez64andClaude Opus 5.5 8f62017627 Open web and mail links on the Linux desktop from LaunchServices
LaunchServices now hands http, https and mailto URLs to the host desktop
itself instead of NSWorkspace writing them to a spool that nothing in
the normal workflow drains. It loads the host libsystemd through the ELF
loader and calls xdg-desktop-portal OpenURI on the session bus, falling
back to xdg-open in a transient systemd user unit, so the browser starts
outside Darling's namespaces. LSGetApplicationForURL reports the host
opener for these schemes because Electron checks for a handler before
opening a link. NSWorkspace goes through LSOpenCFURLRef.

Tested with a host-side D-Bus regression (79 checks) and in a fresh
guest prefix through open(1) and NSWorkspace, both reaching the portal
with the exact URL.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 09:58:59 +02:00
lucannez64andClaude Opus 5.5 c030b8ff82 Start the installed Riot Client after the first-time installer exits
Riot's installer puts the client in /Users/Shared/Riot Games and exits;
its LaunchServices hand-off to that client does not start it under
Darling, so the window just closes. The installer wrapper now launches
the installed client itself, and the runner links it to
/Applications/Riot Client.app when that link is missing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 09:27:29 +02:00
lucannez64 7bbf9ec0e7 Fetch pinned darling-swift LFS objects from GitHub, not the dead host
The pinned src/external/swift/.lfsconfig points lfs.url at the retired
git-lfs.darlinghq.org, so a fresh `git submodule update --init --recursive`
blocks with no output right after src/external/sqlite is checked out: swift is
the next submodule in sorted order and its checkout waits on that host.

Override lfs.url to GitHub's endpoint, which still serves the objects (verified
44 objects / 16 MB, real Mach-O dylibs), and print explicit submodule progress so
the last completed submodule is not mistaken for the stalled one.
2026-10-15 01:12:47 +02:00
lucannez64andClaude Opus 5.5 4027cb9aa7 Make the Indium hand-off changes opt-in and record the Hyprland findings
Two matches with the Indium hand-off round (narrow present wait, deferred
blits, worker-side command-buffer lease, skipping CPU Vulkan devices) ran
slower than before, with more main-thread futex waiting. Each change is now
behind a guest flag file and off by default, so the default libindium matches
the round-3 build (vertex-descriptor dirty masks, cheaper resource setters).

The wait counters stay opt-in, write a "waits enabled" line when they are on
and keep their state per image. The docs explain that flag files created from
the host while Darling runs may stay invisible through the overlay mount.

Also adds a passive cursor watcher. The stuck in-game cursor is Hyprland's
direct scanout, not Darling. The first match with direct scanout off averaged
135 FPS. STATUS, TROUBLESHOOTING and README are updated with the new matches.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 00:29:19 +02:00
lucannez64andClaude Opus 5.5 6559f19fcc Add main-thread hardware counter capture and record its results
The counters (user space, counting only) show page walks cost the game's
main thread at most 3.5% of its cycles, so huge pages for its code are not
worth pursuing and for its heap are worth at most 1-3%.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 17:47:46 +02:00
lucannez64andClaude Opus 5.5 4370f375cd Cut Darling overhead in League fights and add passive match capture
Game process (ARAM Hexgate: 84 -> 127 FPS average, slowest stretches ~110):
- Local pthread mutexes, condition variables and Mach semaphores are on by
  default in the game process only, with /tmp/rclol-no-local-* opt-outs.
  The main thread's darlingserver waits fell from 1.36 to 0.10 ms per frame.
- Local semaphores: the count and the slot generation change in one
  compare-exchange, a destroy leaves a negative marker, the table is reset
  after fork, and names the table did not create go to the server.
- Metal: drop identical re-binds (keyed on the Indium object, depth-stencil
  retained), pass blit resources by reference, and stop resetting vertex
  descriptors twice.
- Core isolation of the main thread is opt-in (/tmp/rclol-core-isolation);
  it lowered FPS in its only match.
- Optimized libc/libc++/Foundation overlays, AVX2 string primitives, real CPU
  topology and their installers and offline checks.

Tools and docs:
- tools/riot-match-capture: passive /proc sampler, user-space IP profiler and
  reports, plus a comparison against the game's netstats.
- tools/riot-lsem-model and tools/riot-metal-bind-model: host models that
  extract the shipped code and check it.
- tools/install-riot-metal-pair.sh installs Metal and Indium together.
- Status, setup, testing and troubleshooting docs updated with the measured
  matches and the switch table; manifest file counts match the patches.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-14 16:48:34 +02:00
lucannez64 5609d96f16 Fix Darling runtime performance and new-PC compatibility
Preserve floating-point arguments in GL resolvers, retain presentation across differently sized windows, export AppKit click and URL fixes, and guard nullable LaunchServices errors. Include compiler/build and installer corrections for the new PC.

Reuse server receive buffers with descriptor-safe exception cleanup and avoid disabled debug-string allocation. Translate Darwin free/reuse memory hints, add atomic server/library installers with separate user-owned memory backups, and preserve active processes until a manual namespace restart.

Remove automatic inspectors, client helpers and forced unlimited UI frames from normal launches. Retain historical hooks with offline mocks and document their exclusion, unresolved installer handoff, activation requirements and unmeasured FPS/RAM benefits.

Validation: all 29 pinned patches apply; all 461 exported source files match; host receive and memory checks, launcher and JavaScript mocks, syntax and documentation-link checks pass. No live client/game was controlled or restarted.
2026-10-13 15:09:23 +02:00
lucannez64 a96cdc62b1 Publish portable Darling runtime patch snapshot and testing tools 2026-10-12 20:15:55 +02:00