Skip to content

Commit 1ec7d05

Browse files
committed
[90] Fix cursor initialization when using fractional scaling
Recent Eclipse version support fractional zoom level as opposed to 100% or 200% zoom. Because no icons exist for those levels, an IllegalArgumentException is thrown when trying to create the corresponding cursors. In order to solve this, one has to consider the following cases: 1) Newer SWT versions provide a Cursor constructor that accepts an ImageDataProvider. This constructor always creates image data matching the device zoom. 2) Older SWT versions automatically upscale the image data to match the device zoom. Therefore the original image data must be at 100% zoom.
1 parent 0be4aeb commit 1ec7d05

File tree

1 file changed

+31
-18
lines changed
  • bundles/org.eclipse.gmf.runtime.gef.ui/src/org/eclipse/gmf/runtime/gef/ui/internal/l10n

1 file changed

+31
-18
lines changed
Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/******************************************************************************
2-
* Copyright (c) 2002, 2003 IBM Corporation and others.
2+
* Copyright (c) 2002, 2025 IBM Corporation and others.
33
* This program and the accompanying materials are made
44
* available under the terms of the Eclipse Public License 2.0
55
* which is available at https://www.eclipse.org/legal/epl-2.0/
@@ -12,7 +12,14 @@
1212

1313
package org.eclipse.gmf.runtime.gef.ui.internal.l10n;
1414

15+
import java.lang.reflect.Constructor;
16+
17+
import org.eclipse.jface.resource.ImageDescriptor;
1518
import org.eclipse.swt.graphics.Cursor;
19+
import org.eclipse.swt.graphics.Device;
20+
import org.eclipse.swt.graphics.Image;
21+
import org.eclipse.swt.graphics.ImageData;
22+
import org.eclipse.swt.graphics.ImageDataProvider;
1623

1724

1825
/**
@@ -33,27 +40,33 @@ public class Cursors {
3340
* Constant define for a cusor used to move an existing line segment
3441
*/
3542
public static final Cursor CURSOR_SEG_MOVE;
36-
37-
private static int deviceZoom = -1;
3843

3944
static {
40-
CURSOR_SEG_ADD = new Cursor(null, GefUIPluginImages.DESC_SEG_ADD.getImageData(getDeviceZoom()), 0, 0);
41-
CURSOR_SEG_MOVE = new Cursor(null, GefUIPluginImages.DESC_SEG_MOVE.getImageData(getDeviceZoom()), 0, 0);
45+
CURSOR_SEG_ADD = createCursor(GefUIPluginImages.DESC_SEG_ADD, 0, 0);
46+
CURSOR_SEG_MOVE = createCursor(GefUIPluginImages.DESC_SEG_MOVE, 0, 0);
4247
}
4348

44-
// Taken from org.eclipse.gef.SharedCursors.java
45-
private static int getDeviceZoom() {
46-
if (deviceZoom == -1) {
47-
deviceZoom = 100; // default value
48-
String deviceZoomProperty = System.getProperty("org.eclipse.swt.internal.deviceZoom"); //$NON-NLS-1$
49-
if (deviceZoomProperty != null) {
50-
try {
51-
deviceZoom = Integer.parseInt(deviceZoomProperty);
52-
} catch (NumberFormatException ex) {
53-
// if the property can not be parsed we keep the default 100% zoom level
54-
}
55-
}
49+
// Taken from org.eclipse.gef.internal.InternalGEFPlugin.java
50+
private static Cursor createCursor(ImageDescriptor source, int hotspotX, int hotspotY) {
51+
ImageDataProvider imageDataProvider = zoom -> getScaledImageData(source, zoom);
52+
try {
53+
// SWT version >= 3.131.0
54+
Constructor<Cursor> ctor = Cursor.class.getConstructor(Device.class, ImageDataProvider.class, int.class,
55+
int.class);
56+
return ctor.newInstance(null, imageDataProvider, hotspotX, hotspotY);
57+
} catch (NoSuchMethodException e) {
58+
return new Cursor(null, imageDataProvider.getImageData(100), hotspotX, hotspotY);
59+
} catch (ReflectiveOperationException e) {
60+
throw new RuntimeException("Failed to instantiate Cursor", e); //$NON-NLS-1$
61+
}
62+
}
63+
64+
private static ImageData getScaledImageData(ImageDescriptor descriptor, int zoom) {
65+
Image image = descriptor.createImage();
66+
try {
67+
return image.getImageData(zoom);
68+
} finally {
69+
image.dispose();
5670
}
57-
return deviceZoom;
5871
}
5972
}

0 commit comments

Comments
 (0)