Skip to content

fix(desktop): sleep idle pixel egg animation - #88406

Merged
teknium1 merged 1 commit into
NousResearch:mainfrom
frizikk:fix/desktop-pixel-egg-idle-raf
Aug 17, 2026
Merged

teknium1 merged 1 commit into
NousResearch:mainfrom
frizikk:fix/desktop-pixel-egg-idle-raf

Conversation

@frizikk

@frizikk frizikk commented Aug 17, 2026 •

Copy link
Copy Markdown

What does this PR do?

Stops PixelEggSprite from waking the Desktop renderer at display cadence while an intact egg is deliberately resting. The component now uses a timeout for the long first/rest gaps and only requests animation frames when a visible frame is due. The hatch sequence renders frames 6–11 once, calls onDone once on the final frame, and leaves no pending renderer work afterward.

Related Issue

Fixes #88395

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✅ Tests (adding or improving test coverage)

Changes Made

  • apps/desktop/src/components/pet/pixel-egg-sprite.tsx: replace unconditional chained RAF scheduling with cancellable timeout/RAF scheduling.
  • apps/desktop/src/components/pet/pixel-egg-sprite.test.tsx: cover rest sleeping, terminal hatch cleanup, and unmount cleanup.

How to Test

  1. Run NODE_ENV=test NODE_OPTIONS='--max-old-space-size=8192 --localstorage-file=/tmp/hermes-vitest-localstorage.json' npm --workspace apps/desktop exec -- vitest run --environment jsdom src/components/pet/pixel-egg-sprite.test.tsx.
  2. Run npm --workspace apps/desktop run typecheck.
  3. Run npm --workspace apps/desktop run build.

Checklist

Code

  • I've read the Contributing Guide.
  • My commit messages follow Conventional Commits.
  • I searched for existing PRs to make sure this isn't a duplicate.
  • My PR contains only changes related to this fix.
  • I've run pytest tests/ -q and all tests pass — N/A: this is an isolated Desktop TypeScript renderer change; focused Vitest, typecheck, ESLint, and production build were run instead.
  • I've added tests for my changes.
  • I've tested on my platform: CachyOS Linux via focused jsdom Vitest and a production Desktop build.

Documentation & Housekeeping

  • I've updated relevant documentation — N/A: no user-facing behavior or configuration changed.
  • I've updated cli-config.yaml.example — N/A.
  • I've updated CONTRIBUTING.md or AGENTS.md — N/A.
  • I've considered cross-platform impact — browser standard timer/RAF APIs only; no platform-specific code.
  • I've updated tool descriptions/schemas — N/A.

Screenshots / Logs

Focused test: 3 passed. Desktop typecheck and production build passed. Changed-file ESLint exited successfully with only the repository's existing test-style no-restricted-globals warnings for document.

@frizikk
frizikk force-pushed the fix/desktop-pixel-egg-idle-raf branch from 94b9fe9 to 2b20a95 Compare August 17, 2026 12:37
@frizikk
frizikk marked this pull request as ready for review August 17, 2026 12:37
@alt-glitch alt-glitch added type/perf Performance improvement or optimization comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have labels Aug 17, 2026
@frizikk
frizikk force-pushed the fix/desktop-pixel-egg-idle-raf branch from 2b20a95 to d108ad5 Compare August 17, 2026 13:18
@teknium1
teknium1 merged commit 36d5dd3 into NousResearch:main Aug 17, 2026
39 checks passed
teknium1 added a commit that referenced this pull request Aug 17, 2026
…imations

Desktop shipped the same bug class four times in one week: a decorative
animation loop that never sleeps (bots face clock #88543, pixel egg #88406,
diffusion placeholder #88564, plus the #77651 hidden-renderer wave). Each fix
hand-rolled the same four behaviors. This extracts them into one helper in
src/lib/budgeted-loop.ts:

- fps budget (default 15) on top of rAF
- observability pause via the existing createRendererLoopPauseController
- idle dormancy: idleWhen() true after a draw parks the loop with zero
  pending work until wake() — the piece every hand-rolled loop forgot
- teardown: dispose() cancels the frame, disposes the controller, and makes
  wake() a no-op

DiffusionCanvas migrates onto it as the first consumer (net -40 lines at the
call site); its existing scheduling/budget/instance-cap tests pass unchanged
against the migrated implementation. Helper suite covers budget, pause,
park/wake, dormancy-survives-focus-churn, and dispose idempotency; sabotage
run (budget+dormancy stripped) fails 4/5.
lisajlau pushed a commit to lisajlau/hermes-agent that referenced this pull request Aug 20, 2026
…imations

Desktop shipped the same bug class four times in one week: a decorative
animation loop that never sleeps (bots face clock NousResearch#88543, pixel egg NousResearch#88406,
diffusion placeholder NousResearch#88564, plus the NousResearch#77651 hidden-renderer wave). Each fix
hand-rolled the same four behaviors. This extracts them into one helper in
src/lib/budgeted-loop.ts:

- fps budget (default 15) on top of rAF
- observability pause via the existing createRendererLoopPauseController
- idle dormancy: idleWhen() true after a draw parks the loop with zero
  pending work until wake() — the piece every hand-rolled loop forgot
- teardown: dispose() cancels the frame, disposes the controller, and makes
  wake() a no-op

DiffusionCanvas migrates onto it as the first consumer (net -40 lines at the
call site); its existing scheduling/budget/instance-cap tests pass unchanged
against the migrated implementation. Helper suite covers budget, pause,
park/wake, dormancy-survives-focus-churn, and dispose idempotency; sabotage
run (budget+dormancy stripped) fails 4/5.
bobaba76 pushed a commit to bobaba76/hermes-agent that referenced this pull request Aug 27, 2026
…imations

Desktop shipped the same bug class four times in one week: a decorative
animation loop that never sleeps (bots face clock NousResearch#88543, pixel egg NousResearch#88406,
diffusion placeholder NousResearch#88564, plus the NousResearch#77651 hidden-renderer wave). Each fix
hand-rolled the same four behaviors. This extracts them into one helper in
src/lib/budgeted-loop.ts:

- fps budget (default 15) on top of rAF
- observability pause via the existing createRendererLoopPauseController
- idle dormancy: idleWhen() true after a draw parks the loop with zero
  pending work until wake() — the piece every hand-rolled loop forgot
- teardown: dispose() cancels the frame, disposes the controller, and makes
  wake() a no-op

DiffusionCanvas migrates onto it as the first consumer (net -40 lines at the
call site); its existing scheduling/budget/instance-cap tests pass unchanged
against the migrated implementation. Helper suite covers budget, pause,
park/wake, dormancy-survives-focus-churn, and dispose idempotency; sabotage
run (budget+dormancy stripped) fails 4/5.
melon-xf added a commit to melon-xf/hermes-agent that referenced this pull request Sep 3, 2026
…imations

Desktop shipped the same bug class four times in one week: a decorative
animation loop that never sleeps (bots face clock NousResearch#88543, pixel egg NousResearch#88406,
diffusion placeholder NousResearch#88564, plus the NousResearch#77651 hidden-renderer wave). Each fix
hand-rolled the same four behaviors. This extracts them into one helper in
src/lib/budgeted-loop.ts:

- fps budget (default 15) on top of rAF
- observability pause via the existing createRendererLoopPauseController
- idle dormancy: idleWhen() true after a draw parks the loop with zero
  pending work until wake() — the piece every hand-rolled loop forgot
- teardown: dispose() cancels the frame, disposes the controller, and makes
  wake() a no-op

DiffusionCanvas migrates onto it as the first consumer (net -40 lines at the
call site); its existing scheduling/budget/instance-cap tests pass unchanged
against the migrated implementation. Helper suite covers budget, pause,
park/wake, dormancy-survives-focus-churn, and dispose idempotency; sabotage
run (budget+dormancy stripped) fails 4/5.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have type/perf Performance improvement or optimization

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Desktop: sleep the pixel egg animation while it rests

3 participants