Skip to content

[GTK] Render Tree and Table images crisp at HiDPI zoom - #3631

Open
vogella wants to merge 1 commit into
eclipse-platform:masterfrom
vogella:gtk-tree-cell-surface
Open

vogella wants to merge 1 commit into
eclipse-platform:masterfrom
vogella:gtk-tree-cell-surface

Conversation

@vogella

@vogella vogella commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

On GTK3 at 200% zoom, images set with TreeItem.setImage or TableItem.setImage were rendered blurry, because GtkCellRendererPixbuf treats the bound pixbuf as a scale 1 image and reduces it to 1x before scaling it up again. Views that paint their images in a PaintItem listener, such as JFace StyledCellLabelProvider based ones, were unaffected, so plain label provider trees like the Mylyn Task List looked noticeably softer than their neighbours. The cell data function now hands the pixbuf renderer the cairo surface already kept in CELL_SURFACE, which carries the device scale, so native cell images are as sharp as GC.drawImage output. Rendering at 100% and on GTK4 is unchanged.

@vogella

vogella commented Sep 29, 2026

Copy link
Copy Markdown
Contributor Author
tasklist_compare tasklist_zoom_compare

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (linux)

  109 files  ±0    109 suites  ±0   15m 11s ⏱️ -3s
4 637 tests ±0  4 402 ✅ ±0  235 💤 ±0  0 ❌ ±0 
3 482 runs  ±0  3 393 ✅ ±0   89 💤 ±0  0 ❌ ±0 

Results for commit 4734b80. ± Comparison against base commit 6799800.

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.

Copilot review overview

🟡 Changes recommended

Reused column model slots retain stale surfaces, causing removed images to reappear.

Review effort: Balanced
Findings: 2 Medium severity

Open (2)
What changed in this PR

Uses scale-aware Cairo surfaces to render crisp Tree/Table images on GTK3 HiDPI displays.

Changes:

  • Binds GTK3 cell renderers to stored image surfaces.
  • Registers pixbuf data callbacks for all Tree/Table renderers.
  • Adds the GTK surface property constant.
File Description
Tree.java Renders Tree images from Cairo surfaces.
Table.java Renders Table images from Cairo surfaces.
OS.java Defines the native surface property name.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java Outdated
Comment thread bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java Outdated
@github-actions

github-actions Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

  212 files  ± 0    212 suites  ±0   27m 58s ⏱️ +13s
4 978 tests + 4  4 950 ✅ +4   28 💤 ±0  0 ❌ ±0 
7 233 runs  +12  7 034 ✅ +7  199 💤 +5  0 ❌ ±0 

Results for commit 74ebb77. ± Comparison against base commit 8b89d66.

♻️ 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.

Copilot review overview

🟡 Changes recommended

Raw surface pointers can become dangling, and GTK4 receives unnecessary per-cell callbacks.

Review effort: Balanced
Findings: 2 High severity

Open (2)
Resolved since last review (2)

Comment thread bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java Outdated
Comment thread bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java Outdated

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.

Copilot review overview

🟡 Changes recommended

GTK4 receives unnecessary render callbacks, and the painting regressions use zero-sized controls.

Review effort: Balanced
Findings: 2 Medium severity · 2 Low severity

Open (4)
Resolved since last review (2)

Comment thread bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java Outdated
Comment thread bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java Outdated
@akurtakov

akurtakov commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

There are all the details to handle here but it also fixes a nasty drawing problem:

public static void main(String[] args) {
      Display display = new Display();
      Shell shell = new Shell(display);
      shell.setText("zoom " + display.getPrimaryMonitor().getZoom() + "%");
      shell.setLayout(new RowLayout());

      // 1 device pixel black/white stripes at every zoom, any resampling makes it grey
      Image stripes = new Image(display, (ImageDataProvider) zoom -> {
              int size = 16 * zoom / 100;
              ImageData data = new ImageData(size, size, 24, new PaletteData(0xFF0000, 0xFF00, 0xFF));
              for (int y = 0; y < size; y++)
                      for (int x = 0; x < size; x++)
                              data.setPixel(x, y, x % 2 == 0 ? 0 : 0xFFFFFF);
              return data;
      });

      Tree tree = new Tree(shell, SWT.BORDER);
      new TreeItem(tree, SWT.NONE).setImage(stripes);

      Label reference = new Label(shell, SWT.NONE);
      reference.setImage(stripes);

      shell.pack();
      shell.open();
      while (!shell.isDisposed()) {
              if (!display.readAndDispatch()) display.sleep();
      }
      stripes.dispose();
      display.dispose();
}

with GDK_SCALE=2 draws a solid gray instead of striped.

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.

Copilot review overview

🟢 Approval recommended

The GTK3-specific implementation is coherent, with only minor test resource-cleanup feedback remaining.

Review effort: Balanced
Findings: 2 Low severity

Open (2)
Resolved since last review (4)

@vogella
vogella force-pushed the gtk-tree-cell-surface branch 2 times, most recently from 98c9281 to 010e9df Compare September 30, 2026 04:34
@akurtakov
akurtakov requested a balanced review from Copilot September 30, 2026 04:56

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.

Copilot review overview

🟡 Changes recommended

Stale non-owning surface addresses can alias replacement surfaces and render the wrong image.

Review effort: Balanced
Findings: 2 Medium severity

Open (2)
Resolved since last review (2)

Comment thread bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Table.java Outdated
Comment thread bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Tree.java Outdated
@vogella
vogella force-pushed the gtk-tree-cell-surface branch 2 times, most recently from 0ee8728 to 371ae10 Compare September 30, 2026 16:17
@akurtakov
akurtakov requested a balanced review from Copilot September 30, 2026 16:48

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.

Copilot review overview

🟢 Approval recommended

The rendering and ownership changes are coherent and tested; only a minor class-reference cleanup remains.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
Resolved since last review (2)

Comment thread bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java Outdated
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. The cell data function now feeds the renderer the cairo surface
already stored in CELL_SURFACE, which carries the device scale.

Disposing a column now also clears its CELL_SURFACE slot, so a column
that later reuses the slot neither renders nor returns the old image.

The surface is only used at a device scale above 1 on an enabled
control, because it bypasses GTK's icon effects such as dimming when
disabled. Elsewhere the pixbuf path including the SWT.SetData refresh is
unchanged. Surface backed cells report no accessible image size, since
GTK reads that from the pixbuf only.

CELL_SURFACE now holds a reference through the cairo surface boxed type,
so a surface stays valid while a row shows it even after its image was
disposed, and its address cannot be reused by another image.

Assisted-by: multiple AI agents and layers of automated tooling 🤖
@vogella

vogella commented Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

Fixed

@vogella
vogella force-pushed the gtk-tree-cell-surface branch from 371ae10 to 74ebb77 Compare October 2, 2026 04:22
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