Skip to content

[GTK] Keep the Image of each Tree and Table cell for getImage() - #3695

Merged
akurtakov merged 1 commit into
eclipse-platform:masterfrom
akurtakov:gtk-table-tree-cell-images
Oct 9, 2026
Merged

akurtakov merged 1 commit into
eclipse-platform:masterfrom
akurtakov:gtk-table-tree-cell-images

Conversation

@akurtakov

Copy link
Copy Markdown
Member

getImage() mapped the cell's surface address back to an Image through the ImageList. Once the slot of a disposed Image was reused, it returned the Image of another cell, and a column created after another one was disposed could report the old column's image. TableItem and TreeItem now keep the Image of each cell in a per column array, maintained like cellFont, and getImage() returns from it.

getTextBounds() and the owner draw measure and paint code ignore a disposed cell image instead of failing in getBounds().

Split from #3631.

Assisted-by: multiple AI agents and layers of automated tooling 🤖
Assisted-by: Anthropic Claude Code (claude-opus-5-5)

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Test Results (linux)

  115 files  ±0    115 suites  ±0   14m 5s ⏱️ +49s
4 664 tests +6  4 429 ✅ +6  235 💤 ±0  0 ❌ ±0 
3 554 runs  +9  3 465 ✅ +9   89 💤 ±0  0 ❌ ±0 

Results for commit 846d00a. ± Comparison against base commit f87da9a.

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Test Results (macosx)

   72 files  ±0     72 suites  ±0   7m 25s ⏱️ +26s
4 638 tests +6  4 377 ✅ +6  261 💤 ±0  0 ❌ ±0 
2 316 runs  +6  2 238 ✅ +6   78 💤 ±0  0 ❌ ±0 

Results for commit 846d00a. ± Comparison against base commit f87da9a.

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

  224 files  ± 0    224 suites  ±0   25m 22s ⏱️ -28s
5 016 tests + 6  4 988 ✅ + 6   28 💤 ±0  0 ❌ ±0 
7 380 runs  +18  7 186 ✅ +18  194 💤 ±0  0 ❌ ±0 

Results for commit c56b651. ± Comparison against base commit f87da9a.

♻️ This comment has been updated with latest results.

Copilot AI 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.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

3 open findings
What changed in this PR

Fixes incorrect getImage() results for GTK TreeItem/TableItem cells by storing per-column Image references (instead of reverse-mapping native surfaces through ImageList), and makes layout/paint paths ignore disposed images.

Changes:

  • Store per-cell images in TreeItem/TableItem (cellImage[]) and return from it in _getImage()
  • Keep cellImage[] aligned with column insert/remove in Tree/Table
  • Add JUnit coverage ensuring images don’t “inherit” across disposed columns and disposed images aren’t replaced
File Description
tests/​org.eclipse.swt.tests/​JUnit Tests/​org/​eclipse/​swt/​tests/​junit/​Test_org_eclipse_swt_widgets_TreeItem.java Adds regression tests around column disposal/recreation and disposed-image stability for TreeItem.getImage()
tests/​org.eclipse.swt.tests/​JUnit Tests/​org/​eclipse/​swt/​tests/​junit/​Test_org_eclipse_swt_widgets_TableItem.java Adds analogous regression tests for TableItem.getImage()
bundles/​org.eclipse.swt/​Eclipse SWT/​gtk/​org/​eclipse/​swt/​widgets/​TreeItem.java Introduces cellImage[], switches _getImage() to use it, and ignores disposed images in text bounds calculations
bundles/​org.eclipse.swt/​Eclipse SWT/​gtk/​org/​eclipse/​swt/​widgets/​Tree.java Maintains TreeItem.cellImage[] when columns are inserted/removed; ignores disposed images during render sizing
bundles/​org.eclipse.swt/​Eclipse SWT/​gtk/​org/​eclipse/​swt/​widgets/​TableItem.java Introduces cellImage[], switches _getImage() to use it, and ignores disposed images in text bounds calculations
bundles/​org.eclipse.swt/​Eclipse SWT/​gtk/​org/​eclipse/​swt/​widgets/​Table.java Maintains TableItem.cellImage[] when columns are inserted/removed; ignores disposed images in measure/render sizing

🧠 Review effort: Lite


Give feedback about Copilot approvals in this survey to enter a drawing for a $150 gift card.

Copilot stopped reviewing on behalf of akurtakov due to an error October 8, 2026 16:34
Comment thread bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java Outdated
getImage() mapped the cell's surface address back to an Image through
the ImageList. Once the slot of a disposed Image was reused, it returned
the Image of another cell, and a column created after another one was
disposed could report the old column's image. TableItem and TreeItem now
keep the Image of each cell in a per column array, maintained like
cellFont, and getImage() returns from it.

getTextBounds() and the owner draw measure and paint code ignore a
disposed cell image instead of failing in getBounds().

Split from eclipse-platform#3631.

Assisted-by: multiple AI agents and layers of automated tooling 🤖
Assisted-by: Anthropic Claude Code (claude-opus-5-5)
@akurtakov
akurtakov force-pushed the gtk-table-tree-cell-images branch from 846d00a to c56b651 Compare October 9, 2026 06:12

@vogella vogella left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGMT.

Before

Image

After:

Image

vogella added a commit to vogella/eclipse.platform.swt that referenced this pull request Oct 9, 2026
GtkCellRendererPixbuf treats the "pixbuf" attribute as a scale 1 image,
so at 200% zoom native Tree and Table cell images were reduced to 1x and
upscaled again, while the same image drawn with GC.drawImage stayed
sharp. On GTK3 at a widget scale factor above 1 the pixbuf renderer now
binds its "surface" property to the CELL_SURFACE model column, a boxed
cairo surface that carries the device scale, instead of "pixbuf".

The binding is swapped through gtk_tree_view_column_add_attribute, so
plain widgets run no Java code per row: the cell data function is still
installed only for VIRTUAL, custom draw and owner draw, as before, and
there it sets the surface or the pixbuf according to the same mode. The
binding goes back to "pixbuf" when the control is disabled, because the
surface bypasses GTK's insensitive icon effect, and when the scale
factor drops to 1. Table and Tree rebind from enableWidget and from the
existing scale factor notification (dpiChanged).

At a scale above 1 the cell differs from the 100% rendering in ways
inherent to the surface property: theme icon effects on selected or
hovered rows are not applied, GTK's accessible image size is missing
because it is read from the pixbuf, and the cell draws the surface of
the Image itself rather than a pixbuf copy, so drawing into an Image
after setImage shows up in the cell at that scale only. A snapshot copy
was not added, since it would duplicate the pixels of every cell image
that is shared between many rows.

Disposing a column also clears its CELL_SURFACE slot, so a column that
reuses the slot does not show the old image. getImage() relies on the
per cell Image array from eclipse-platform#3695 rather than the surface address.

The CELL_SURFACE column type is taken from the value type of the pixbuf
renderer's "surface" GParamSpec and a missing type raises
ERROR_NO_HANDLES instead of being cached as 0. The VIRTUAL path keeps
setData = checkData (item), since binding by attribute needs no early
return.

Assisted-by: multiple AI agents and layers of automated tooling 🤖
@akurtakov
akurtakov merged commit a4bc054 into eclipse-platform:master Oct 9, 2026
22 checks passed
vogella added a commit to vogella/eclipse.platform.swt that referenced this pull request Oct 9, 2026
GtkCellRendererPixbuf treats the "pixbuf" attribute as a scale 1 image,
so at 200% zoom native Tree and Table cell images were reduced to 1x and
upscaled again, while the same image drawn with GC.drawImage stayed
sharp. On GTK3 at a widget scale factor above 1 the pixbuf renderer now
binds its "surface" property to the CELL_SURFACE model column, a boxed
cairo surface that carries the device scale, instead of "pixbuf".

The binding is swapped through gtk_tree_view_column_add_attribute, so
plain widgets run no Java code per row: the cell data function is still
installed only for VIRTUAL, custom draw and owner draw, as before, and
there it sets the surface or the pixbuf according to the same mode. The
binding goes back to "pixbuf" when the control is disabled, because the
surface bypasses GTK's insensitive icon effect, and when the scale
factor drops to 1. Table and Tree rebind from enableWidget and from the
existing scale factor notification (dpiChanged).

At a scale above 1 the cell differs from the 100% rendering in ways
inherent to the surface property: theme icon effects on selected or
hovered rows are not applied, GTK's accessible image size is missing
because it is read from the pixbuf, and the cell draws the surface of
the Image itself rather than a pixbuf copy, so drawing into an Image
after setImage shows up in the cell at that scale only. A snapshot copy
was not added, since it would duplicate the pixels of every cell image
that is shared between many rows.

Disposing a column also clears its CELL_SURFACE slot, so a column that
reuses the slot does not show the old image. getImage() relies on the
per cell Image array from eclipse-platform#3695 rather than the surface address.

The CELL_SURFACE column type is taken from the value type of the pixbuf
renderer's "surface" GParamSpec and a missing type raises
ERROR_NO_HANDLES instead of being cached as 0. The VIRTUAL path keeps
setData = checkData (item), since binding by attribute needs no early
return.

Assisted-by: multiple AI agents and layers of automated tooling 🤖
akurtakov pushed a commit to vogella/eclipse.platform.swt that referenced this pull request Oct 9, 2026
GtkCellRendererPixbuf treats the "pixbuf" attribute as a scale 1 image,
so at 200% zoom native Tree and Table cell images were reduced to 1x and
upscaled again, while the same image drawn with GC.drawImage stayed
sharp. On GTK3 at a widget scale factor above 1 the pixbuf renderer now
binds its "surface" property to the CELL_SURFACE model column, a boxed
cairo surface that carries the device scale, instead of "pixbuf".

The binding is swapped through gtk_tree_view_column_add_attribute, so
plain widgets run no Java code per row: the cell data function is still
installed only for VIRTUAL, custom draw and owner draw, as before, and
there it sets the surface or the pixbuf according to the same mode. The
binding goes back to "pixbuf" when the control is disabled, because the
surface bypasses GTK's insensitive icon effect, and when the scale
factor drops to 1. Table and Tree rebind from enableWidget and from the
existing scale factor notification (dpiChanged).

At a scale above 1 the cell differs from the 100% rendering in ways
inherent to the surface property: theme icon effects on selected or
hovered rows are not applied, GTK's accessible image size is missing
because it is read from the pixbuf, and the cell draws the surface of
the Image itself rather than a pixbuf copy, so drawing into an Image
after setImage shows up in the cell at that scale only. A snapshot copy
was not added, since it would duplicate the pixels of every cell image
that is shared between many rows.

Disposing a column also clears its CELL_SURFACE slot, so a column that
reuses the slot does not show the old image. getImage() relies on the
per cell Image array from eclipse-platform#3695 rather than the surface address.

The CELL_SURFACE column type is taken from the value type of the pixbuf
renderer's "surface" GParamSpec and a missing type raises
ERROR_NO_HANDLES instead of being cached as 0. The VIRTUAL path keeps
setData = checkData (item), since binding by attribute needs no early
return.

Assisted-by: multiple AI agents and layers of automated tooling 🤖
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.

3 participants