Clicking the color-picker eyedropper on a software-render Mac (VM, no Metal device) logs the whole session out.
Crash chain (DiagnosticReports 2026-07-20, macOS Tahoe guest):
ColorSampler (the NSColorSampler XPC service behind NSColorPanel's loupe) requests a window capture; it crashes with SIGILL in CFRelease.
- WindowServer takes SkyLight's SOFTWARE capture path —
CaptureSurfaceSW::Populate → WSCompositeDestinationCreateWithIOSurface — and SIGABRTs. WindowServer death restarts the login session.
- The wrapper then segfaults in
QWebEnginePage::setVisible during the session teardown (collateral).
This is an OS defect in Tahoe's software capture path, but the wrapper must not arm it. Fix: on _software_render machines (the existing ioreg -rc IOAccelerator probe) the bridge refuses OS screen sampling and emits eyedropperInPage; colorPicker.js overlays a crosshair and resolves samplePagePixel(x, y) against view.grab() — Qt's own offscreen widget render, zero WindowServer capture. Native NSColorPanel is unchanged on real hardware. Windows wrapper gets the same gate on its WARP probe for consistency.
Verified live on the macOS bench via CDP: openColorPicker → eyedropperInPage → samplePagePixel(200,200) → colorPicked #181825. Static contract tests in tests/test_eyedropper_software_render.py.
Clicking the color-picker eyedropper on a software-render Mac (VM, no Metal device) logs the whole session out.
Crash chain (DiagnosticReports 2026-07-20, macOS Tahoe guest):
ColorSampler(the NSColorSampler XPC service behind NSColorPanel's loupe) requests a window capture; it crashes with SIGILL inCFRelease.CaptureSurfaceSW::Populate→WSCompositeDestinationCreateWithIOSurface— and SIGABRTs. WindowServer death restarts the login session.QWebEnginePage::setVisibleduring the session teardown (collateral).This is an OS defect in Tahoe's software capture path, but the wrapper must not arm it. Fix: on
_software_rendermachines (the existingioreg -rc IOAcceleratorprobe) the bridge refuses OS screen sampling and emitseyedropperInPage; colorPicker.js overlays a crosshair and resolvessamplePagePixel(x, y)againstview.grab()— Qt's own offscreen widget render, zero WindowServer capture. Native NSColorPanel is unchanged on real hardware. Windows wrapper gets the same gate on its WARP probe for consistency.Verified live on the macOS bench via CDP: openColorPicker → eyedropperInPage → samplePagePixel(200,200) → colorPicked
#181825. Static contract tests in tests/test_eyedropper_software_render.py.