Skip to content

Conversation

@HeikoKlare
Copy link
Contributor

@HeikoKlare HeikoKlare commented Oct 17, 2025

Cursors are initialized with the zoom of the control on which they are set. However, cursors are usually expected to scale according to the autoscaled UI around those controls for which autoscaling was disabled.

This change adapts the cursor initializations to use the autoscale zoom of the containing shell instead of the zoom of the control itself. In consequence, cursors will have the same size in the whole shell, no matter on which control they are set.

Contributes to eclipse-gef/gef-classic#821

How to test

Best possibility to productively test is with Draw2d/GEF and according examples.

For simple testing, the following snippet can be used (adapted from #2308). The lines for different properties AUTOSCALE_DISABLED, swt.autoScale and swt.autoScale.updateOnRuntime can be changed to test different combinations. The combination that is activated by default shows the bug in the existing implementation. The others allow to test that we do not have possible regressions regarding previous issue reports, such as #2308.

In any case, a primary monitor with zoom != 100% should be used.

public class Snippet1 {

	public static void main(String[] args) {
//		System.setProperty("swt.autoScale", "200");
//		System.setProperty("swt.autoScale", "false");
		System.setProperty("swt.autoScale.updateOnRuntime", "true");
		Cursor cursor = new Cursor(null, getImageData(100), 0, 0);

		Shell shell = new Shell(SWT.NO_TRIM);
		shell.setSize(100, 100);
		shell.setLayout(new FillLayout());
		Composite c = new Composite(shell, SWT.NONE);
		c.setBackground(new Color(0, 255, 0));
		c.setData("AUTOSCALE_DISABLED", true);
		c.setCursor(cursor);
		shell.open();

		Display display = shell.getDisplay();
		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();
		}
	}
}

The red cursor is expected to always have half the width and height of the green shell.

With the default configuration is looks like this without the change:
cursor_old

And this is how it looks with the change:
cursor_new

@github-actions
Copy link
Contributor

github-actions bot commented Oct 17, 2025

Test Results

  115 files  ±0    115 suites  ±0   10m 16s ⏱️ - 2m 13s
4 560 tests ±0  4 544 ✅ ±0  16 💤 ±0  0 ❌ ±0 
  311 runs  ±0    308 ✅ ±0   3 💤 ±0  0 ❌ ±0 

Results for commit 1a4e6c2. ± Comparison against base commit 55b5adf.

♻️ This comment has been updated with latest results.

@arunjose696
Copy link
Contributor

One minor observation: when I start GEF with "swt.autoScale" set to "false" on a 200% monitor, some cursors (e.g., select, marquee) are scaled, while others (e.g., connection) are not. This creates a slight inconsistency, but I assume this has always been the behavior.

Apart from this I have tested the changes using the snippet and also on GEF, and the cursors are now scaled correctly in both cases compared to master. The code looks good as well.

@HeikoKlare
Copy link
Contributor Author

One minor observation: when I start GEF with "swt.autoScale" set to "false" on a 200% monitor, some cursors (e.g., select, marquee) are scaled, while others (e.g., connection) are not. This creates a slight inconsistency, but I assume this has always been the behavior.

Yes, that's also my understanding. It should have always been like this (either intended or by accident), as disabling auto-scaling with swt.autoScale=false results in every control/image/cursor etc. not being scaled. For the cursors, this does only apply to custom cursors and not the ones coming from the OS, which makes the experience inconsistent. This is why, in my opinion, cursors should always be scaled according to the current monitor on which they are used (so that they conform to the OS cursors), which is exactly what happens now when monitor-specific scaling is enabled.

Cursors are initialized with the zoom of the control on which they are
set. However, cursors are usually expected to scale according to the
autoscaled UI around those controls for which autoscaling was disabled.

This change adapts the cursor initializations to use the autoscale zoom
of the containing shell instead of the zoom of the control itself. In
consequence, cursors will have the same size in the whole shell, no
matter on which control they are set.
@akoch-yatta akoch-yatta force-pushed the cursorsize-autoscaledisabled branch from 56d74b2 to 1a4e6c2 Compare October 22, 2025 15:02
Copy link
Contributor

@akoch-yatta akoch-yatta left a comment

Choose a reason for hiding this comment

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

Code looks solid and i did not find regression when testing with the IDE and the Snippet

@akoch-yatta akoch-yatta merged commit 03cc46e into eclipse-platform:master Oct 22, 2025
17 checks passed
@akoch-yatta akoch-yatta deleted the cursorsize-autoscaledisabled branch October 22, 2025 15:18
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.

Incorrectly sized cursors for controls with disabled autoscaling

3 participants