Skip to content

fix(desktop): recover the embedded laser view when a project switch restarts the brain - #99

Merged
pyramation merged 1 commit into
mainfrom
fix/laser-view-black-on-project-switch
Aug 9, 2026
Merged

fix(desktop): recover the embedded laser view when a project switch restarts the brain#99
pyramation merged 1 commit into
mainfrom
fix/laser-view-black-on-project-switch

Conversation

@pyramation

Copy link
Copy Markdown
Contributor

Summary

Switching projects while on Show left the embedded artist UI a black rectangle until the app was reloaded. It isn't z-index: the native WebContentsView was still there, sitting on a load that never completed.

Two causes, one shape — nothing ever asked again:

  • invalidateLaserView() fires the reload right after the brain restarts. If that load fails (server not listening yet, or it is aborted by a laser:sync load racing it), the URL gate is cleared but the renderer has no reason to send another sync, so no code path retries.
  • A view mid-load paints nothing, and it was setVisible(true) regardless, so the failure showed as black rather than as the route's own empty state.

So the view now tracks desired vs loaded separately and heals itself:

load(url)   loadedUrl = url; painted = false
             loadURL(...).then(paint).catch(retryLater)
retryLater  setTimeout(load, min(2000, 250 * 2**attempts))   // only while desiredUrl === url
visible     desiredUrl != null && painted

Leaving Show (syncLaser({visible:false})) clears desiredUrl, which cancels the pending retry — a backoff that outlives the screen it belongs to is the next bug. Each load takes a loadSeq, so the ERR_ABORTED rejection of a superseded load can't schedule a retry over the load that replaced it.

__tests__/laser-view.test.ts covers this against a mocked electron: paint-then-show, retry after a failed load, backoff growth, cancellation on leaving Show, reload on project switch, and no reload for an unchanged URL. Four of the six fail against the previous implementation.

Link to Devin session: https://app.devin.ai/sessions/972698f89f494b86828010666a002b8f
Requested by: @pyramation

@pyramation pyramation self-assigned this Aug 9, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@pyramation
pyramation merged commit 662760c into main Aug 9, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant