Skip to content

[Grid] Implement frozen first column in SWT (RCP), fixes #695#696

Open
PHMT-CW wants to merge 4 commits into
EclipseNebula:masterfrom
PHMT-CW:grid/frozen-first-column-pr
Open

[Grid] Implement frozen first column in SWT (RCP), fixes #695#696
PHMT-CW wants to merge 4 commits into
EclipseNebula:masterfrom
PHMT-CW:grid/frozen-first-column-pr

Conversation

@PHMT-CW
Copy link
Copy Markdown

@PHMT-CW PHMT-CW commented Apr 21, 2026

Closes #695.

Continues the scaffolding added in #645, which introduced the setFixed API but only wired the behaviour for the RAP platform. On SWT (RCP) the TODO in Grid.java noted that the RCP implementation was still pending; this PR delivers it for the common case of a single frozen first column.

Summary

  • getColumn(Point), getOrigin, and header/footer hit tests now resolve to the frozen column under the fixed-overlay rectangle, so expand/collapse, selection, tooltips, and GridEditor placement all behave correctly while the grid is scrolled horizontally.
  • Fixed-aware re-passes for header, footer, and cell paint; the cell pass is clipped to the overlay rectangle to prevent renderers from bleeding into the scrolled area.
  • Graceful degradation for GridColumnGroup: a frozen column that shares a group with scrollable members skips the group header and logs a one-time warning to stderr. Documented in the setFixed Javadoc.
  • Focus rectangle starts to the right of the frozen overlay so its left edge stays visible.
  • Scope is intentionally limited to a single frozen first column to keep the change focused and reviewable; setFixed Javadoc documents the supported case and the group restriction.

Tests

  • New GridFixedColumn_Test covering setFixed / isFixed, fixed-aware getOrigin, hit-testing under scroll, origin invariants, and the one-shot group-spanning warning.
  • org.eclipse.nebula.widgets.grid.test is now wired into the Tycho build. Surefire is scoped to GridFixedColumn_Test for now — the legacy *_Test classes in the bundle predate current SWT behaviour, JUnit and Mockito 1.8.4, and have been bit-rotting in the IDE-only .launch configuration for years. Restoring them is worthwhile but orthogonal; the commit message documents the rationale.

Manual verification

  • New snippet GridFrozenFirstColumnSnippet demonstrates the plain frozen column + GridEditor, and the group-spanning case.
  • Verified in a downstream SWT/JFace RCP product (~30 columns, tree toggles on the frozen column, column groups, and inline editors) at various horizontal scroll offsets.

Screenshots / demo

GRID.Frozen.First.Column.-.2026-04-21.17-18-31.webm

PHMT-CW added 2 commits April 21, 2026 17:06
Builds on the basic fixed column scaffolding from EclipseNebula#645 to make a frozen
first column behave correctly across the rest of Grid:

- getColumn(Point) resolves hits inside the fixed-column overlay to the
  frozen column on top instead of the scrolled column underneath.
  This automatically fixes getCell, overColumnHeader, overColumnFooter,
  and the mouse handlers that funnel through it.
- getColumnHeaderXPosition and getOrigin are now fixed-aware, so
  GridEditor.computeEditorBounds and GridItem.getBoundsCorrected place
  cell editors on the frozen column instead of off-screen.
- The fixed cell-painting pass now clips to the overlay rectangle so
  renderers cannot bleed into the scrolled area.
- paintFooter got a fixed-aware re-pass so the frozen column footer
  stays put on horizontal scroll, mirroring the existing header pass.
- The focus rectangle starts to the right of the frozen overlay so its
  left edge stays visible.
- The header fixed pass detects when a frozen column shares a column
  group with scrollable members; it logs a one-time warning to stderr
  and degrades gracefully by drawing only the column header (no group
  band) in the overlay.
- Updated GridColumn#setFixed Javadoc to document the supported case
  (single frozen first column) and the column-group restriction.
- Replaced the stale "TODO: column freezing" note with a pointer to
  setFixed and the new snippet.

Adds GridFrozenFirstColumnSnippet (plain frozen column with editor +
group-spanning case) and GridFixedColumn_Test (setFixed, frozen-aware
getOrigin, hit-testing under scroll, one-shot group-spanning warning).

Fixes EclipseNebula#695

Signed-off-by: Cameron Weick <cpwei@phmtechnology.com>
Add a Tycho test-plugin pom for org.eclipse.nebula.widgets.grid.test
and register the bundle as a child module of widgets/grid so CI runs
the new GridFixedColumn_Test alongside the rest of the build.

Surefire is intentionally scoped to **/GridFixedColumn_Test.java for
now: the legacy *_Test classes in the bundle predate current SWT
behavior, JUnit, and Mockito (1.8.4), and have been bit-rotting in
the IDE-only .launch configuration for years. Restoring them is a
worthwhile but orthogonal effort that should not block the
frozen-first-column work this bundle was wired up to validate.

While here, harden the freeze tests against a hidden ordering bug:
ScrollBar.setSelection is silently clipped to the SWT default
maximum of 100 until Grid.updateScrollbars() runs as part of a
paint, so a setSelection(150) called before the first paint never
actually scrolled. The new flushPaint / scrollHorizontallyTo helpers
force a paint, set the requested selection, and return the actual
clipped value; tests assert on the real delta and refuse to silently
pass at scroll=0.

Signed-off-by: Cameron Weick <cpwei@phmtechnology.com>
@laeubi
Copy link
Copy Markdown
Contributor

laeubi commented Apr 21, 2026

ontinues the scaffolding added in #645, which introduced the setFixed
API but only wired the behaviour for the RAP platform. On SWT (RCP) the
TODO in Grid.java noted that the RCP implementation was still pending

I'm a bit confused, I use this in SWT (Nebula has nothing to do with RCP) ... not sure whats needed for RAP.

@PHMT-CW
Copy link
Copy Markdown
Author

PHMT-CW commented Apr 21, 2026

ontinues the scaffolding added in #645, which introduced the setFixed
API but only wired the behaviour for the RAP platform. On SWT (RCP) the
TODO in Grid.java noted that the RCP implementation was still pending

I'm a bit confused, I use this in SWT (Nebula has nothing to do with RCP) ... not sure whats needed for RAP.

Hello,

With regard to RAP, this comment specifically references the developer guide here. Currently, it remains somewhat unclear whether the SWT implementation was fully finalized.

During our recent testing of the frozen column feature within our Eclipse RCP product, we encountered an issue where the frozen columns did not satisfy the hit test for expanding and collapsing tree items, alongside a few additional complications.

On headless Linux GTK the SWT widget is never realized during the
synthetic redraw/update/readAndDispatch cycle used by these tests,
so Grid.updateScrollbars() never runs and the horizontal scrollbar
stays at its defaults (visible=false, max=1, thumb=1). GTK treats
setSelection on an invisible scrollbar as a silent no-op, which
caused three frozen-column tests to fail on CI while passing
everywhere else.

Switch the scroll helper to ScrollBar.setValues with explicit
setVisible(true), which atomically assigns selection/max/thumb and
bypasses the realization dependency entirely. Fixes three CI
failures in PR EclipseNebula#696.

Signed-off-by: Cameron Weick <cpwei@phmtechnology.com>
@PHMT-CW PHMT-CW force-pushed the grid/frozen-first-column-pr branch from 3bcced2 to b549a0d Compare April 21, 2026 08:18
@laeubi
Copy link
Copy Markdown
Contributor

laeubi commented Apr 21, 2026

During our recent testing of the frozen column feature within our Eclipse RCP product, we encountered an issue where the frozen columns did not satisfy the hit test for expanding and collapsing tree items, alongside a few additional complications.

Would you mind to enhance the Snippet first to show the problems? That usually a bit easier to understand then. Also it is unclear why it is only affecting the first column?

And yes this feature is quite new and would likely need some improvements or hardening, so thanks for working on this!

Extend GridFrozenFirstColumnSnippet with a third section that
demonstrates the freeze + tree interaction interactively: a frozen
first column configured as the tree column, with expandable parent
rows and a caption telling the reader what to do to verify the
behaviour.
This is the scenario that motivated the original bug report. Without
freeze-aware hit-testing, clicking an expand/collapse toggle while the
grid is horizontally scrolled routes the click to the column underneath
the overlay and the toggle appears unresponsive. The snippet now lets
a reviewer reproduce the original symptom and confirm the fix.
The same scenario is also covered by an automated regression test,
GridFixedColumn_Test.testTreeToggle_OnFrozenColumn_RespondsWhenScrolled.
Refs EclipseNebula#695

Signed-off-by: Cameron Weick <cpwei@phmtechnology.com>
@PHMT-CW
Copy link
Copy Markdown
Author

PHMT-CW commented Apr 22, 2026

During our recent testing of the frozen column feature within our Eclipse RCP product, we encountered an issue where the frozen columns did not satisfy the hit test for expanding and collapsing tree items, alongside a few additional complications.

Would you mind to enhance the Snippet first to show the problems? That usually a bit easier to understand then. Also it is unclear why it is only affecting the first column?

And yes this feature is quite new and would likely need some improvements or hardening, so thanks for working on this!

Yes of course.

I've added a third section to GridFrozenFirstColumnSnippet (createTreeSection) that makes the original failure mode interactive: a frozen first column that is also the tree column, with expandable parent rows. The Javadoc on the snippet now explicitly walks through what to verify in each of the three scenarios. With the fix in place, scrolling horizontally and then clicking a toggle still expands/collapses the row; without it, the click is routed to the scrolled column underneath the overlay and the toggle appears unresponsive.

The same scenario is also covered by an automated test, GridFixedColumn_Test.testTreeToggle_OnFrozenColumn_RespondsWhenScrolled, so the regression is guarded going forward. As evidence, here is the current PR test suite run against unmodified master Grid.java:

Failures:
  GridFixedColumn_Test.testGetColumn_FrozenOverlayWinsHitTesting
    expected same:<GridColumn {col_0}> was not:<GridColumn {col_3}>
  GridFixedColumn_Test.testGetOrigin_FrozenColumn_PinnedAcrossScroll
    expected:<0> but was:<-150>
  GridFixedColumn_Test.testTreeToggle_OnFrozenColumn_RespondsWhenScrolled
    Clicking the toggle on the frozen column while scrolled should expand the row

All three pass with the PR applied.

Why first column only?
I kept the scope small to make the contribution easier to review and to keep the risk of regressions low. The freeze interacts with quite a few code paths in Grid: hit-testing, painter clipping, the focus rectangle, editor positioning, and GridColumnGroup spanning. Supporting an arbitrary number of fixed columns multiplies the work in each of those paths, so I wanted to land the foundational pieces first (the fixed-aware geometry helpers, hit-test priority, paint and clip overlay, and the group-spanning rule) with clear test coverage before going any further.

On the broader question of whether Grid should eventually match the RAP build and support N fixed columns, my own preference would be to keep the SWT Grid relatively lean and point users with heavier needs at NatTable, which already handles multi-region freeze, fixed rows, viewport layers, and large datasets very well. That is only my opinion as a contributor though, so I am happy to defer to your judgement on the intended scope. If full parity with the RAP side is the goal then widening it to N columns afterwards should be a relatively small follow-up.

@wimjongman
Copy link
Copy Markdown
Contributor

@laeubi are you happy with these changes?

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.

[Grid] Implement frozen first column for SWT (RCP) parity with RAP

3 participants