- a forwarded SIGINT/SIGTERM/SIGHUP now leaves the polling loop, so the
five-second TERM grace and the SIGKILL fallback actually run; a loader that
ignores SIGTERM no longer blocks the supervisor forever
- surviving guest processes now return a non-zero status instead of 0
- an invalid RCLOL_STOP_AFTER_CLIENT_SECONDS warns and disables the idle stop
instead of aborting the launch with a traceback
Adds a regression test that sends SIGTERM to a loader and a descendant that
both ignore it, and asserts the process group is killed.
Signed-off-by: zero <zero@localhost>
The stub records the final darling launch after exec-guest.py. The launcher
now runs session-supervisor.py first, so the stub hands the supervised command
to exec-guest.py instead of stopping at the supervisor. The guest assertions
are unchanged: they still inspect the launch that exec-guest.py performs.
The Riot Client does not exit when its window closes, and a loader that dies
first leaves launchd/mldr and the client tree holding memory until the runtime
is restarted by hand. run-riot-client.sh now execs a small supervisor instead
of the guest loader:
- SIGINT/SIGTERM/SIGHUP are forwarded to the guest process group, the loader
gets a grace period, and darling shutdown runs before any leftover guest
process is stopped.
- Leftovers are stopped only when they carry this prefix's __mldr_sockpath and
the same uid, deepest-first, SIGTERM then SIGKILL. The guest PID namespace is
learned while the session runs; a namespace equal to the host's is refused.
- Cleanup only runs when this launcher started the runtime, so a second launch
that attaches to an existing server leaves it running.
- RCLOL_STOP_AFTER_CLIENT_SECONDS=N adds an opt-in idle stop: it fires only
after a managed client window was seen and is gone for N seconds with no game
process, and never when the window state cannot be read. Off by default.
- RCLOL_CLEAN_ON_EXIT=0 keeps the previous exec-only behaviour.
Adds 23 unit tests for attribution, namespace scoping, shutdown ordering, the
attached-session guard and the idle decision.
- doctor: resolve the workspace/Nix runtime before the native path, honour
multi-entry XDG_DATA_DIRS, raise the kernel minimum to 5.14, and redact
home/prefix/workspace paths by default (--no-redact opts out). Reports are
written mode 0600.
- crash-report: drop the whole-process table from the default bundle
(--all-processes opts in), mask credentials in argv, strip window titles,
validate --label, find the workspace launcher log, bound the log tail,
describe missing logs, write the archive 0600 without owner metadata, and
keep --json output pure JSON.
- perf-baseline: reject non-finite times and absurd frame times, count
--last by usable match, include the last sample interval in duration,
record only the log basename, and rename p50/p95/p99 to sample_p* to make
clear they are ten-second samples.
- docs: correct the metric descriptions, flag names and shader-cache sign.
wait_for_exit counted any live PID with the same number as a leftover, so a
reused PID produced a misleading "still present after SIGKILL" message. Compare
the original start time and use the process state only to include the original
process while it is an unreaped zombie.
Each of these hit NSUnimplementedMethod and either dropped the value
or returned zero.
- NSWindow: store and return collectionBehavior; setContentMinSize and
setShowsResizeIndicator keep their value without the warning;
isOnActiveSpace and keyViewSelectionDirection answer.
- NSApplication activateIgnoringOtherApps: activates through the
display backend, as NSRunningApplication activateWithOptions: does.
With NO it does nothing, since the window server cannot tell whether
another app is active and NO must not take focus from one.
- NSSpellChecker dismissCorrectionIndicatorForView is a no-op, as there
is no correction indicator to dismiss.
The X11 backend's activateProcessIdentifier: now looks the process up
in the root's _NET_CLIENT_LIST before falling back to the root's
children: under a reparenting window manager those children are frames
without _NET_WM_PID, so activation found no window.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Turns "it does not work" into an attachable report instead of a log-less
issue. Three read-only host tools, reachable from the launcher:
- doctor.py checks GPU/driver, Vulkan ICDs, display session, memory, disk,
overlay layer, core-dump limit, i915 panel self-refresh and prefix/runtime
state. --json and --report produce an issue attachment; warnings do not fail.
- crash-report.py bundles the doctor checks, process table, dserver and
launcher log tails, graphics kernel messages, display state and recent core
dumps. Environment is never collected and home/user/host are redacted.
- perf-baseline.py parses the game's own netstats.csv into average FPS,
p50/p95/p99 frame time, slowest-quarter FPS and hitch count, with --json and
--append for before/after comparisons.
COMPATIBILITY.md records the verified UHD 620 row with measured numbers
(24-32 avg FPS, p99 44-98 ms) and explains how to submit another one.
Children whose parent dies are reparented to the guest launchd, and its job
manager only reaps PIDs it has a job record for, so every leftover mldr/CEF
process from a killed client tree stayed a zombie until shutdown. Reap zombies
that launchd owns but does not track on a 5 second timer; tracked jobs keep
their exit status for job_reap(). proc_listpids() is not implemented in Darling
yet, so the scan enumerates the guest PID namespace through /proc.
recover-stale-client now signals the stale tree deepest-first so a live parent
can still reap its own children, and prepare.py repairs interrupted checkouts
and missing Git LFS objects instead of publishing pointer text as a library.
State that scripts/validate.py checks revision format, patch existence and
patch parsing but does not verify applicability to pinned revisions. Point
patch changes at the separate prepare.py --check-only workflow.
Signed-off-by: 3AvisD <[email protected]>
Distinguish the opt-in hide helper (local window management) from the
opt-in close helper (terminates eligible League client UI processes), and
list the tracked project artwork in the distribution scope.
Scope the platform-identity statement to repository-owned code: the
repository does not pass the identifiers as Riot authentication data, but
the values are guest-visible through IOKit and the official client's later
handling is outside the repository's scope. Use US spelling for licence
consistently.
Signed-off-by: 3AvisD <[email protected]>
Link the project repository in the interoperability scope so readers can
distinguish it from the upstream Darling repository.
Signed-off-by: 3AvisD <[email protected]>
Add docs/INTEROPERABILITY.md, an English scope document that describes
the project's interoperability and responsible-use practices: what it
distributes, how it handles local platform metadata and the MAC/AMFI
probe, how it keeps copyright and licence notices, how it avoids
access/authentication/integrity shortcuts, how it presents trademarks
and handles notices, and the user's responsibility for Riot's terms.
Update README, NOTICE, COMPLIANCE and PLATFORM_IDENTITY to link the
document and to state the opt-in window-helper and synthetic-identity
behaviour accurately. Add CONTRIBUTING with DCO sign-off and a scope
checklist.
Documentation-only change: no launcher, patch, build or test behaviour
changes.
Signed-off-by: 3AvisD <[email protected]>