Skip to content

Conversation

@ShahzaibIbrahim
Copy link
Contributor


🐞 Problem Description

In SWT, custom cursors were being created with incorrect sizes on high-DPI displays. The root cause was this line:

OS.SetCursor(Cursor.win32_getHandle(cursor, getNativeZoom()));

The method Cursor.win32_getHandle(...) used getNativeZoom() to determine the scale at which the cursor image should be rendered.

However, getNativeZoom() only reflects the raw device DPI scaling (e.g., 125%, 150%), and does not account for SWT’s autoscale policy (controlled via the swt.autoScale property).

This leads to inconsistencies:

  • Shells, fonts, and other UI elements in SWT may scale according to a rounded zoom factor (e.g., 100%, 200%),
  • But the cursor was scaled using the unrounded native zoom, causing it to appear too small or too large compared to the rest of the UI.

The Fix

To align cursor scaling with the rest of the SWT UI, the cursor zoom should be computed using the same logic that SWT uses for autoscaling across the toolkit.

Replace:

Cursor.win32_getHandle(cursor, getNativeZoom())

With:

Cursor.win32_getHandle(cursor, DPIUtil.getZoomForAutoscaleProperty(getNativeZoom()))

This uses:

  • DPIUtil.getZoomForAutoscaleProperty(...), which applies the logic from swt.autoScale (e.g., rounding zoom levels up to the nearest 100%)
  • Ensures cursor size matches the size expectations of other UI components (like Shells, Fonts, Images)

Various Cases with Snippets

public class Snippet {
	public static void main(String[] args) {
		//System.setProperty("swt.autoScale", "int200");
		Display display = Display.getDefault();
		Cursor cursor = new Cursor(display, getImageData(100), 0, 0);
		Shell shell = new Shell(display, SWT.NO_TRIM);
		shell.setSize(100, 100);
		shell.setCursor(cursor);
		shell.setBackground(new Color(0, 255, 0));
		shell.open();
		while (!display.isDisposed()) {
			display.readAndDispatch();
		}
		cursor.dispose();
	}

	private static ImageData getImageData(int zoom) {
		Image image = new Image(null, 50, 50);
		try {
			GC gc = new GC(image);
			gc.setBackground(new Color(255, 0, 0));
			gc.fillRectangle(0, 0, 50, 50);
			return image.getImageData(zoom);
		} finally {
			image.dispose();
		}
	}
}

- autoScale=1000

20250717-1108-19 1137473

- autoScale=quarter, zoom = 175%

20250717-1109-46 7608369

- autoScale=int200, zoom = 175%

20250717-1110-48 6685659

@github-actions
Copy link
Contributor

github-actions bot commented Jul 17, 2025

Test Results

   546 files  + 7     546 suites  +7   30m 8s ⏱️ - 1m 40s
 4 407 tests +49   4 390 ✅ +47   17 💤 +3  0 ❌  - 1 
16 713 runs  +49  16 586 ✅ +47  127 💤 +3  0 ❌  - 1 

Results for commit cebe524. ± Comparison against base commit 2853d53.

♻️ This comment has been updated with latest results.

Copy link
Contributor

@amartya4256 amartya4256 left a comment

Choose a reason for hiding this comment

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

I have tested it for 175, 100 and 125% on both master and this branch.
My finding:

  1. On master the cursor takes the size of the native zoom.
  2. With this PR, the cursor is consistent with the zoom (device zoom/autoscaledZoom/specific to property, e.g.: quarter, half, etc)

Hence, approving it.

Copy link
Member

@fedejeanne fedejeanne left a comment

Choose a reason for hiding this comment

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

The code looks fine, I'm just confused about which issue does this PR solve (and how to test it). Is it #2308 ?
The screenshots you provided look similar to the ones in the issue but I don't see the "cursor" in them (the red square).

@fedejeanne
Copy link
Member

fedejeanne commented Jul 21, 2025

The code looks fine, I'm just confused about which issue does this PR solve (and how to test it). Is it #2308 ?

I see that this is documented in our internal issue (vi-eclipse/Eclipse-Platform#357). You just need to adapt the text of the commit and this PR's description to say that if fixes #2308.

The screenshots you provided look similar to the ones in the issue but I don't see the "cursor" in them (the red square).

Scratch that, I see now that they are GIFs and they ran only once so I missed the red square. It's there though 👍

Previously, custom cursors were scaled using the raw device zoom
(getNativeZoom),
which could result in mismatched sizes on high-DPI displays. This change
replaces
it with DPIUtil.getZoomForAutoscaleProperty to align cursor scaling with
the rest
of the UI.

Fixes eclipse-platform#2308
@fedejeanne
Copy link
Member

The API check failure is unrelated.

@fedejeanne fedejeanne merged commit 69a577c into eclipse-platform:master Jul 22, 2025
14 of 17 checks passed
@fedejeanne fedejeanne deleted the master-357 branch July 22, 2025 07:23
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.

Custom cursors not correct sized with specific auto-scale settings

3 participants