eclipse.platform.swt icon indicating copy to clipboard operation
eclipse.platform.swt copied to clipboard

Custom cursor is not shown when "swt.autoScale.updateOnRuntime" is enabled

Open ptziegler opened this issue 6 months ago • 3 comments

Related to https://github.com/eclipse-platform/eclipse.platform.ui/issues/3047 and https://github.com/eclipse-platform/eclipse.platform.swt/issues/2308 but not quite the same.

On a monitor with 150% zoom, consider the following snippet:

package test;

import java.io.InputStream;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class Snippet {
	public static void main(String[] args) {
		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.setCursor(cursor);
		shell.setBackground(new Color(0, 255, 0));
		shell.open();
		
		Display display = shell.getDisplay();
		while (!display.isDisposed()){ 
			display.readAndDispatch();
		}
		cursor.dispose();
	}
	
	private static ImageData getImageData(int zoom) {
		try (InputStream is = Snippet.class.getResourceAsStream("Seg_Add.png")) {
			ImageLoader imageLoader = new ImageLoader();
			return imageLoader.load(is)[0];
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

And the following icon: Image

What I expect (see the other bug for the wrong scaling, otherwise this, except 50% larger):

Image

What I get:

Image

Tested with the 3.131.0.v20250709-1347.

ptziegler avatar Jul 10 '25 19:07 ptziegler

Note: Using new Cursor(null, Snippet::getImageData, 0, 0); works, but obviously returns the same image data, regardless of the zoom level.

ptziegler avatar Jul 10 '25 20:07 ptziegler

~~This seems to be the most likely cause for this behavior. This method is called with the image data at 100% zoom, which is then simply thrown away when it is scaled up to 150% zoom.~~

https://github.com/eclipse-platform/eclipse.platform.swt/blob/2ddc1ad4e2ca9f3988abc479026a34a29d21da96/bundles/org.eclipse.swt/Eclipse%20SWT/win32/org/eclipse/swt/graphics/Image.java#L1578-L1582

Correction: The magic is happening here. The call to Image.drawScaled(...), which would scale up the cursor from 32x32 to 48x48 is called, but the resulting ImageData is completely blank. This also explains why this problem only appears when smooth scaling is enabled.

https://github.com/eclipse-platform/eclipse.platform.swt/blob/2ddc1ad4e2ca9f3988abc479026a34a29d21da96/bundles/org.eclipse.swt/Eclipse%20SWT/common/org/eclipse/swt/internal/DPIUtil.java#L295-L312

ptziegler avatar Jul 11 '25 04:07 ptziegler

I somehow missed this report, sorry for that. I just came across it and tried to reproduce it (SWT master state, 150% monitor), but for me it works fine, i.e., running the snippet the cursor is shown in a properly scaled way. I am not sure if the actual PNG plays a role: I simply used the eclipse.png inside the SWT snippets source folder. @ptziegler can you still reproduce the issue?

HeikoKlare avatar Aug 13 '25 18:08 HeikoKlare