Skip to content

fix: prevent scrolling rows from bleeding into frozen trailing band - #1193

Open
annahaa874 wants to merge 2 commits into
glideapps:mainfrom
Workfront:fix/frozen-row-span-overflow
Open

fix: prevent scrolling rows from bleeding into frozen trailing band#1193
annahaa874 wants to merge 2 commits into
glideapps:mainfrom
Workfront:fix/frozen-row-span-overflow

Conversation

@annahaa874

@annahaa874 annahaa874 commented Jul 3, 2026

Copy link
Copy Markdown

Problem

When a cell in a freezeTrailingRows row uses span, two visual bugs appear:

  1. Content bleed on horizontal scroll. walkRowsInCol draws scrolling rows all the way to the canvas bottom — past the frozen boundary. The frozen row normally paints over that overflow, but a spanning cell only fills once (first column), so subsequent columns never overwrite the bleed.

  2. Partial highlight/selection. Same root cause — per-column accent (selection, highlight) is skipped by the span short-circuit, so only the first non-sticky column highlights.

Repro

  • freezeTrailingRows: 1 (or higher)
  • getCellContent returns a cell with span: [a, b] for the frozen row
  • Enough scrolling rows so the last one crosses the freeze boundary
  • Scroll horizontally → scrolling-row data leaks inside the span
  • Select the row → only the first column of the span highlights

Fix

Three changes that prevent scrolling rows from entering the frozen band at all:

  1. Clamp walkRowsInCol at freezeY. The scrolling-row walk loop now stops at height - freezeTrailingRowsHeight instead of height. Scrolling rows never enter the frozen zone.

  2. Clip straddling rows. If a scrolling row's rendered rectangle still crosses freezeY (sub-pixel rounding), ctx.clip it at the boundary during full redraws.

  3. Exempt sticky spans from the clip. Sticky columns are re-composited every frame. Clipping them would accumulate a visible seam. They don't need clipping because frozen trailing rows paint over them during the sticky pass.

Test

Regression test in test/data-editor.test.tsx: renders a frozen trailing row with a spanning cell and asserts fillRect is called more than once at the frozen row's y. Fails on main; passes with the fix. Full suite passes.

Co-authored-by: Sassoun Derderian sassound2@gmail.com

`walkRowsInCol` does not clip scrolling rows at freezeY, so the last
visible scrolling row's y-range crosses into the freeze band. Glide's
normal flow relies on each column repainting the frozen row's fill after
the scrolling walk to overwrite that overflow. With a wide `span` this
short-circuits via `handledSpans` for every column after the first,
leaving scrolling-row content visible inside the frozen span; per-column
selection/highlight accents were also skipped for the same reason.

Fall through with `skipContents=true` for sticky rows so each column
repaints its own fill. Content stays drawn once by the initial span push.
Non-frozen spans keep the short-circuit — they don't hit the
overflow-into-freeze-band issue and rely on the wide-fill column for
highlightRegions.

Adds a regression test that fails without the fix.
@annahaa874
annahaa874 force-pushed the fix/frozen-row-span-overflow branch from 662c6a8 to 1b69a25 Compare July 3, 2026 11:02
Stop per-column repainting for spans in frozen trailing rows and
restore single-pass span rendering. Clamp scrollable row walking and
full redraw painting to the frozen-row boundary, with a sticky-span
exception to avoid group-row seam darkening. Update tests for the new
row count and span fill behavior.
@annahaa874 annahaa874 changed the title fix: repaint per-column fill for spanning cells in frozen trailing rows fix: prevent scrolling rows from bleeding into frozen trailing band Jul 20, 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.

1 participant