feat(debug): full UI screenshot sweep — captures modals/dialogs/flows/states
The existing sweep only captures tabs. This adds a "Full UI sweep" (DEBUG OPTIONS) that also drives every normally-hidden surface into view and captures it under every skin, so all the UI a normal sweep misses can be reviewed at once. - The capture unit becomes a "surface" (SweepTarget: a base tab, optionally with a setup()/teardown() that forces a modal / multi-step flow / state overlay on top). Tabs are surfaces with a null setup. The existing tab sweep is folded into the same state machine (one code path). All sweep logic + the catalog + demo data move into a new src/app_sweep.cpp. - Runs OFFLINE against injected demo data (installDemoWalletData snapshots then restores the real state_ — WalletState isn't copy-assignable, so a targeted field snapshot is used) and fires NO live op: capture_mode_ guards the seed-backup RPC, auto-lock, and the migration pumps; the async-firing dialogs are neutralized by pre-setting their state (fetch_started_ + demo phrase; seed_migration_step_ set directly). Verified: 0 RPC/secret/send calls. - Catalog (v1): tabs + the bool-flag modals (import/export key, backup, seed-backup, about, settings) + the 6 migrate-to-seed steps + 4 wizard steps + lock/warmup/not-ready overlays + the send-confirm popup (via a new ui::SweepShowSendConfirm debug hook, since its state is send_tab-static). - Overlay/blur surfaces settle 8 frames (blur backdrop freeze); setup re-runs each frame (OpenPopup popups must re-fire). updateScreenshotSweep now runs before the first-run-wizard early-return in render() so the sweep advances while a wizard step is shown. main.cpp drops vsync during a sweep so it isn't throttled to the compositor's unfocused rate. Output: <config>/screenshots-full/<surface>/<skin>.png + index.md. - DRAGONX_FULL_SWEEP=1 runs the sweep headlessly then quits (CI / verification). Verified end-to-end under WSLg: 288 PNGs (9 skins x 32 surfaces), all 1200x720, [Sweep] done, clean quit, no daemon. Byte-identity across runs holds only for static skins on data-free surfaces — the rest vary by animated theme effects / live price / relative timestamps (expected for a review tool, not a bug). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
25
src/main.cpp
25
src/main.cpp
@@ -1754,6 +1754,16 @@ int main(int argc, char* argv[])
|
||||
SDL_GL_MakeCurrent(backup_current_window, backup_current_context);
|
||||
}
|
||||
|
||||
// Uncap FPS during a screenshot sweep so it doesn't crawl at the compositor's (often
|
||||
// heavily throttled for an unfocused window) vsync rate. Restored when the sweep ends.
|
||||
{
|
||||
static bool sweepVsyncOff = false;
|
||||
const bool sweeping = app.isScreenshotSweeping();
|
||||
if (sweeping != sweepVsyncOff) {
|
||||
SDL_GL_SetSwapInterval(sweeping ? 0 : 1);
|
||||
sweepVsyncOff = sweeping;
|
||||
}
|
||||
}
|
||||
SDL_GL_SwapWindow(window);
|
||||
#endif
|
||||
PERF_END("Present", _perfPresent);
|
||||
@@ -1761,6 +1771,21 @@ int main(int argc, char* argv[])
|
||||
// --- PerfLog: end frame ---
|
||||
dragonx::util::PerfLog::instance().endFrame();
|
||||
|
||||
// Headless verification hook: DRAGONX_FULL_SWEEP=1 runs the full UI sweep once the app has
|
||||
// settled, then quits when it finishes. Used to run the sweep without clicking the button.
|
||||
{
|
||||
static const bool autoSweep = std::getenv("DRAGONX_FULL_SWEEP") != nullptr;
|
||||
static int autoFrames = 0;
|
||||
static bool autoStarted = false;
|
||||
if (autoSweep) {
|
||||
if (!autoStarted) {
|
||||
if (++autoFrames >= 90) { app.startFullUiSweep(); autoStarted = true; }
|
||||
} else if (!app.isScreenshotSweeping()) {
|
||||
running = false; // sweep complete
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Exit when shutdown is complete
|
||||
if (app.shouldQuit()) {
|
||||
running = false;
|
||||
|
||||
Reference in New Issue
Block a user