Skip to content

fix: DH-22093: Fix web UI freezing bug from grid-block-events#2646

Merged
vbabich merged 1 commit intodeephaven:mainfrom
vbabich:vlad_dh-22093
Mar 27, 2026
Merged

fix: DH-22093: Fix web UI freezing bug from grid-block-events#2646
vbabich merged 1 commit intodeephaven:mainfrom
vbabich:vlad_dh-22093

Conversation

@vbabich
Copy link
Copy Markdown
Collaborator

@vbabich vbabich commented Mar 27, 2026

No description provided.

@vbabich vbabich changed the title fix: DH-22093: Fix mouse up cleanup while dragging fix: DH-22093: Fix web UI freezing bug from grid-block-events Mar 27, 2026
@vbabich vbabich requested review from a team and dgodinez-dh and removed request for a team March 27, 2026 18:32
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 27, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 49.55%. Comparing base (68e2734) to head (5a05e2e).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2646      +/-   ##
==========================================
+ Coverage   49.51%   49.55%   +0.04%     
==========================================
  Files         774      774              
  Lines       43864    43868       +4     
  Branches    11292    11293       +1     
==========================================
+ Hits        21720    21740      +20     
+ Misses      22098    22082      -16     
  Partials       46       46              
Flag Coverage Δ
unit 49.55% <100.00%> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a web UI freeze caused by the grid-block-events document class being left behind or removed incorrectly during drag interactions/unmount, by tightening cleanup behavior and adding regression tests.

Changes:

  • Track whether a Grid instance added grid-block-events and adjust cleanup logic accordingly.
  • Reorder handleMouseUp cleanup to ensure drag timers/cursor overlays are removed even on non-left mouseups (when not actively dragging).
  • Add test coverage for grid-block-events cleanup scenarios (normal drag, right/middle click interactions, unmount during drag, multi-instance cases).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
packages/grid/src/Grid.tsx Adds per-instance tracking for grid-block-events ownership and adjusts mouseup cleanup order.
packages/grid/src/Grid.test.tsx Adds regression tests around grid-block-events cleanup and multi-instance/unmount scenarios.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1322 to +1327
// removeDocumentCursor should still clean up
// BUG: Currently it doesn't because documentCursor is null and
// the entire function body is guarded by `if (this.documentCursor != null)`
component.removeDocumentCursor();

// After fix, this should be false
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

These comments describe behavior as a current bug ("BUG: Currently it doesn't...") but the implementation in this PR makes removeDocumentCursor() remove grid-block-events even when documentCursor is null. Please update/remove the bug explanation so the test documents the new expected behavior rather than the pre-fix state.

Suggested change
// removeDocumentCursor should still clean up
// BUG: Currently it doesn't because documentCursor is null and
// the entire function body is guarded by `if (this.documentCursor != null)`
component.removeDocumentCursor();
// After fix, this should be false
// removeDocumentCursor should clean up grid-block-events
// even if documentCursor is currently null
component.removeDocumentCursor();
// grid-block-events should be removed after calling removeDocumentCursor

Copilot uses AI. Check for mistakes.
expect(hasBlockEventsClass()).toBe(false);
});

it('should remove grid-block-events when right-clicking during drag (case 1)', () => {
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

Test title is misleading: the test asserts grid-block-events remains after the right-click mouseup and is only removed after the subsequent left mouseup. Rename the test (or adjust assertions) so the title matches the behavior being verified.

Suggested change
it('should remove grid-block-events when right-clicking during drag (case 1)', () => {
it('should keep grid-block-events after right-click during drag until left mouse up (case 1)', () => {

Copilot uses AI. Check for mistakes.
Comment on lines +1188 to +1195
function getColumnSeparatorX(columnIndex: VisibleIndex): number {
const { rowHeaderWidth, columnWidth } = resizableTheme;
return rowHeaderWidth + columnWidth * (columnIndex + 1) - 2;
}

function getColumnHeaderY(): number {
return Math.floor(resizableTheme.columnHeaderHeight / 2);
}
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

getColumnSeparatorX / getColumnHeaderY helpers are duplicated from the earlier "column separators" tests in this file. To reduce drift and make future updates easier, consider hoisting these helpers to a shared scope (or reusing the existing ones) instead of redefining them in each describe block.

Copilot uses AI. Check for mistakes.
Comment on lines 1710 to +1711
document.documentElement.classList.add('grid-block-events');
this.hasAddedBlockEvents = true;
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

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

hasAddedBlockEvents is set to true unconditionally after classList.add('grid-block-events'). If another Grid instance (or any other code) already added grid-block-events, this instance will later remove it in removeDocumentCursor(), reintroducing the cross-instance interference this change is trying to prevent. Consider setting hasAddedBlockEvents only when the class was not present before (or using a shared ref-count / global ownership token) so removal only happens when this instance actually transitioned the class from absent→present.

Suggested change
document.documentElement.classList.add('grid-block-events');
this.hasAddedBlockEvents = true;
const docEl = document.documentElement;
const hadBlockEventsClass = docEl.classList.contains('grid-block-events');
docEl.classList.add('grid-block-events');
this.hasAddedBlockEvents = !hadBlockEventsClass;

Copilot uses AI. Check for mistakes.
@vbabich vbabich merged commit c1ba8d9 into deephaven:main Mar 27, 2026
16 checks passed
@github-actions github-actions bot locked and limited conversation to collaborators Mar 27, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants