Skip to content

fix(canvas): keep background aligned with usable rect - #345

Merged
draedful merged 1 commit into
mainfrom
codex/fix-background-usable-rect
Sep 21, 2026
Merged

draedful merged 1 commit into
mainfrom
codex/fix-background-usable-rect

Conversation

@draedful

@draedful draedful commented Sep 20, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fix the stock canvas Background and PointerGrid falling out of sync with the usable rectangle when an expanded rectangle coordinate becomes zero. This is a maintenance fix for the supported v1 line, targeting main.

Background.extendedUsableRect was initialized to (0, 0, 0, 0) but never updated. Geometry updates compared against this stale rectangle while writing to component state. As a result, a computed x or y of 0 was skipped: the initial state could remain incomplete, or the background/grid could keep an earlier nonzero origin even though hitTest.$usableRect already included all content.

Changes

  • Remove the stale rectangle field.
  • Compute the full expanded rectangle and compare it with getState(), including pending state updates, before applying it with one setState call.
  • Keep the standard Background, its appearance, PointerGrid, gap calculation, scheduler priority, debounce and unmount cleanup unchanged. No changes to HitTest, dependencies or public entry points.
  • Add nine regression tests covering actual Path2D fill geometry and PointerGrid fill rectangles: initial zero coordinates, transitions to zero on both/individual axes, ordinary/negative coordinates, resizing/removing content, queued state updates and unmount cancellation.

Reproduction / manual verification

  1. Use the default Background with system.USABLE_RECT_GAP = 248 and a nonzero-size graph container.
  2. Render a block at {x: 800, y: 800, width: 200, height: 100} and let the scheduler render it. The expanded background starts at (552, 552).
  3. Add a custom comment component in a separate layer at {x: 248, y: 248, width: 1800, height: 1400}, with its hitbox contributing to the usable rectangle. Keep the original block.
  4. After the scheduler settles, hitTest.$usableRect should be {x: 248, y: 248, width: 1800, height: 1400}. Both the background and grid must use {x: 0, y: 0, width: 2296, height: 1896}.

Before the fix, the background/grid origin remains (552, 552). Also repeat with the comment present before the initial render, then move/resize/remove it and test zero on each axis independently.

Verification

  • npm run lint — passed.
  • npm run typecheck — passed, including publish build and published Playwright consumer types.
  • node_modules/.bin/jest --runInBand --ci — 32 suites, 350 tests passed; 4 skipped, 6 todo; 9 snapshots passed, without snapshot updates.
  • npm run test:e2e — 186 Chromium tests passed.
  • Additional local browser harness against the actual rebuilt build/index.js — all 10 content/background/grid states passed; zero geometry mismatches. No diagnostic patch was used.
  • Negative control on the exact base revision 3f2f668e194206ea913949bb09bc1add8d097c8c: re-run the nine new tests with only Background.ts loaded from that revision at transform time. Six tests fail with the original geometry error and three pass; with the real fix all nine pass. Working sources were not reverted for this control.
  • The standalone browser harness also reproduced five expected geometry mismatches on the original npm 1.11.3 artifact.

Validation covers library fixtures and the built library, not the original downstream application graph. Package publication is not part of this PR.

Summary by Sourcery

Keep canvas background geometry synchronized with the current usable rectangle.

Bug Fixes:

  • Keep the canvas background and pointer grid aligned with the expanded usable rectangle when coordinates transition to zero or change rapidly.

Enhancements:

  • Replace stale geometry tracking with complete rectangle comparisons that account for pending component state updates.

Tests:

  • Add regression coverage for zero, negative, resized, removed, queued, and unmounted background geometry updates, including matching Path2D and PointerGrid output.

@sourcery-ai

sourcery-ai Bot commented Sep 20, 2026 •

Copy link
Copy Markdown

Reviewer's Guide

Fixes Background geometry synchronization by atomically updating the full expanded usable rectangle from current state, preventing zero-valued coordinates from being skipped and keeping Background and PointerGrid aligned. Comprehensive canvas-level regression tests cover coordinate transitions, size changes, queued updates, and unmount cleanup.

File-Level Changes

Change Details Files
Replace stale geometry tracking with computation and state-aware comparison of the complete expanded usable rectangle.
  • Remove the never-updated rectangle cache.
  • Derive all four expanded bounds from the usable rectangle and configured gap.
  • Compare against getState(), including queued state, then apply one atomic state update.
src/components/canvas/layers/belowLayer/Background.ts
Add regression coverage for background and pointer-grid geometry synchronization across zero-coordinate and lifecycle scenarios.
  • Verify actual Path2D and fillRect geometry for initial, ordinary, negative, zero-axis, resize, and removal cases.
  • Cover queued updates and cancellation after unmount.
  • Assert both rendering paths use the same expanded rectangle.
src/components/canvas/layers/belowLayer/Background.test.ts

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Approved.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

@gravity-ui-bot

Copy link
Copy Markdown
Contributor

Preview is ready.

@draedful
draedful merged commit 2c34d3b into main Sep 21, 2026
7 checks passed
@gravity-ui gravity-ui Bot mentioned this pull request Sep 21, 2026
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.

2 participants