A performance and correctness patch. Headlines: drastically narrowed Moonraker subscriptions (the prior nullptr-everything pattern was firing per-frame led_effect notifications on AFC hardware — a Voron Trident bundle showed 46 LED-effect objects updating per render frame); a tangle of six interlocking fixes to the wizard preset path so AD5M Pro on ForgeX firmware actually skips hardware steps on fresh install; and a UAF / OOB-read fix for a shared-component XML callback collision caught in bundle SSHGTVZQ.
-
Jog soft-stops driven by kinematic envelope —
MotionPanel::jog()now refuses moves that would push the toolhead pasttoolhead.axis_minimum/axis_maximumand toasts the user. Skipped when bounds aren't published yet or the axis isn't homed. -
Wizard preset application: AD5M Pro ForgeX skipping hardware steps on fresh install — six interlocking issues (preset path resolution, late
preset_modecapture, Moonraker connect gated behind wizard, validate-before-detect ordering, wrong fan names inad5m_*_forgex.json,_zmodprobe firing on_forgexpreset, missing aux fan slot recognition). -
Layer-source precedence within a status update — slicer
SET_PRINT_STATS_INFOnow wins overvirtual_sdcard.layerwithin the same tick (sdcard branch was running second and silently overwriting). Across updates, last source still wins. -
toolhead.max_velocitysubscription regression — caught in code review of subscription narrowing;max_velocity_would have stuck at its initial value, breaking the print-tune overlay and machine-limits panel after every reconnect. Field list is now locked by a 19-case / 178-assertion regression test naming each parser file it mirrors. -
XML callback name collision could SEGV on click (bundle SSHGTVZQ, Qidi Q2, pi) — first-write-wins for
lv_xml_register_event_cbmeant two C++ owners registering the same callback name globally for a shared XML component (e.g.,WizardWifiStep+NetworkSettingsOverlayonwifi_network_item) silently dropped the second registration. The first owner's handler then fired against the second owner'suser_data, casting a small struct as a much larger one and reading ~400 bytes past valid memory. Now last-write-wins. -
Moonraker subscription narrowing — heaters, fans, sensors, tools, macros — eliminated the remaining
nullptr(= all-fields) subscriptions in the discovery sequence. Narrowed to the actual fields each parser consumes (heaters →{temperature, target}, standard fans →{speed}, native LEDs →{color_data}, etc.). Droppedidle_timeoutentirely (no parser reads it). -
Moonraker subscription narrowing —
led_effect, AFC, core motion — biggest perf win on AFC/BoxTurtle: a Voron Trident bundle showed 46led_effectobjects firing per-frame animation updates because we'd been subscribing withnullptr. Nowled_effectis just[enabled]. Also narrowed allAFC*objects to their parser fields, and the per-step core motion objects (toolhead,gcode_move,motion_report). -
Launcher
nice +10when co-hosted with Klipper/Moonraker —helix-launcher.shreduces UI process priority on shared-CPU hardware (Pi, SonicPad, AD5M class) so the printer control loop keeps CPU headroom for stepper timing and MCU comms. Detection is process-based (pgrep -f) with a Unix-socket fallback. Standalone displays (remote-display SonicPad, dev workstation, kiosk pointed at a network printer) are unaffected. Override withHELIX_NICE=<n>inhelixscreen.env;HELIX_NICE=0disables. -
make clean-testsnow wipes the PCH and all sanitizer test binaries — recover from a sanitizer-contaminated tree withoutmake clean. Previously, ASan/TSan test runs reused the PCH compiled with-fsanitize=address, and a subsequentmake test-runwould fail with "ASan runtime does not come first."