From 92bf2b2f9c739d502ae9cb3f559f83f82e5b2361 Mon Sep 17 00:00:00 2001 From: Shahzaib Ibrahim Date: Wed, 1 Oct 2025 14:58:13 +0200 Subject: [PATCH] Deprecating Display#getDPI Having the scale factor being based on the screen DPI leads to unexpected result e.g. Image too big/small. Having a screen dpi independent factor leads to consistent results --- .../cocoa/org/eclipse/swt/printing/Printer.java | 2 +- .../cocoa/org/eclipse/swt/graphics/Device.java | 16 ++++++++++++++-- .../cocoa/org/eclipse/swt/graphics/Font.java | 10 ++++++---- .../gtk/org/eclipse/swt/graphics/Device.java | 17 ++++++++++++++--- .../gtk/org/eclipse/swt/graphics/Font.java | 11 ++++++----- .../gtk/org/eclipse/swt/widgets/Display.java | 3 ++- .../win32/org/eclipse/swt/graphics/Device.java | 11 +++++++++++ .../examples/imageanalyzer/ImageAnalyzer.java | 4 ++-- .../org/eclipse/swt/snippets/Snippet361.java | 4 ++-- .../org/eclipse/swt/snippets/Snippet367.java | 2 +- .../Bug507020_WaylandIconsDoubleScaled.java | 2 +- .../Test_org_eclipse_swt_widgets_Display.java | 1 + 12 files changed, 61 insertions(+), 22 deletions(-) diff --git a/bundles/org.eclipse.swt/Eclipse SWT Printing/cocoa/org/eclipse/swt/printing/Printer.java b/bundles/org.eclipse.swt/Eclipse SWT Printing/cocoa/org/eclipse/swt/printing/Printer.java index 97b489a57b3..88a5f2a88a2 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT Printing/cocoa/org/eclipse/swt/printing/Printer.java +++ b/bundles/org.eclipse.swt/Eclipse SWT Printing/cocoa/org/eclipse/swt/printing/Printer.java @@ -624,7 +624,7 @@ public Point getDPI() { } Point getIndependentDPI() { - return super.getDPI(); + return new Point(72, 72); } /** diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Device.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Device.java index ef30e780765..36a6e040824 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Device.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Device.java @@ -391,7 +391,18 @@ public int getDepth () { * @exception SWTException + * + * @deprecated

This method returns a single global DPI value + * that does not reflect per-monitor DPI settings on modern operating systems. + * In environments with different scaling factors across monitors, it may provide + * a misleading or meaningless result, as it does not correspond to the actual DPI + * of any specific monitor.

+ * + *

Note: While deprecated for general {@code Device} instances like {@code Display}, + * this method may still be validly used when called on a {@code Printer} instance, + * where a single global DPI value is meaningful and expected.

*/ +@Deprecated public Point getDPI () { checkDevice (); return getScreenDPI(); @@ -611,8 +622,9 @@ protected void init () { /* Initialize the system font slot */ boolean smallFonts = System.getProperty("org.eclipse.swt.internal.carbon.smallFonts") != null; double systemFontSize = smallFonts ? NSFont.smallSystemFontSize() : NSFont.systemFontSize(); - Point dpi = this.dpi = getDPI(), screenDPI = getScreenDPI(); - NSFont font = NSFont.systemFontOfSize(systemFontSize * dpi.y / screenDPI.y); + final int DOTS_PER_INCH = 72; + Point dpi = this.dpi = getDPI(); + NSFont font = NSFont.systemFontOfSize(systemFontSize * dpi.y / DOTS_PER_INCH); font.retain(); systemFont = Font.cocoa_new(this, font); } diff --git a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Font.java b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Font.java index e9729d4055a..089fcefecbb 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Font.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/cocoa/org/eclipse/swt/graphics/Font.java @@ -244,6 +244,7 @@ public boolean equals(Object object) { */ public FontData[] getFontData() { if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); + final int DOTS_PER_INCH = 72; NSAutoreleasePool pool = null; if (!NSThread.isMainThread()) pool = (NSAutoreleasePool) new NSAutoreleasePool().alloc().init(); try { @@ -258,8 +259,8 @@ public FontData[] getFontData() { if ((traits & OS.NSBoldFontMask) != 0) style |= SWT.BOLD; if ((extraTraits & OS.NSItalicFontMask) != 0) style |= SWT.ITALIC; if ((extraTraits & OS.NSBoldFontMask) != 0) style |= SWT.BOLD; - Point dpi = device.dpi, screenDPI = device.getScreenDPI(); - FontData data = new FontData(name, (float)handle.pointSize() * screenDPI.y / dpi.y, style); + Point dpi = device.dpi; + FontData data = new FontData(name, (float)handle.pointSize() * DOTS_PER_INCH / dpi.y, style); data.nsName = nsName; return new FontData[]{data}; } finally { @@ -312,8 +313,9 @@ public int hashCode() { void init(String name, float height, int style, String nsName) { if (name == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); if (height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - Point dpi = device.dpi, screenDPI = device.getScreenDPI(); - float size = height * dpi.y / screenDPI.y; + final int DOTS_PER_INCH = 72; + Point dpi = device.dpi; + float size = height * dpi.y / DOTS_PER_INCH; NSFont systemFont = NSFont.systemFontOfSize(size); NSFont boldSystemFont = NSFont.boldSystemFontOfSize(size); String systemFontName = systemFont.familyName().getString(); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java index d329fb6670f..48c9d9bab5f 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Device.java @@ -455,7 +455,18 @@ public int getDepth () { * @exception SWTException + * + * @deprecated

This method returns a single global DPI value + * that does not reflect per-monitor DPI settings on modern operating systems. + * In environments with different scaling factors across monitors, it may provide + * a misleading or meaningless result, as it does not correspond to the actual DPI + * of any specific monitor.

+ * + *

Note: While deprecated for general {@code Device} instances like {@code Display}, + * this method may still be validly used when called on a {@code Printer} instance, + * where a single global DPI value is meaningful and expected.

*/ +@Deprecated public Point getDPI () { checkDevice (); return getScreenDPI(); @@ -641,6 +652,7 @@ public boolean getWarnings () { * @see #create */ protected void init () { + final int DOTS_PER_INCH = 96; if (debug) { if (xDisplay != 0) { /* Create the warning and error callbacks */ @@ -723,10 +735,9 @@ protected void init () { } } defaultFont = OS.pango_font_description_copy (defaultFont); - Point dpi = getDPI(), screenDPI = getScreenDPI(); - if (dpi.y != screenDPI.y) { + if (this.dpi.y != DOTS_PER_INCH) { int size = OS.pango_font_description_get_size(defaultFont); - OS.pango_font_description_set_size(defaultFont, size * dpi.y / screenDPI.y); + OS.pango_font_description_set_size(defaultFont, size * this.dpi.y / DOTS_PER_INCH); } systemFont = Font.gtk_new (this, defaultFont); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Font.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Font.java index a394f1090ae..fc0e0a2a3e4 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Font.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/graphics/Font.java @@ -184,15 +184,15 @@ public boolean equals(Object object) { */ public FontData[] getFontData() { if (isDisposed()) SWT.error(SWT.ERROR_GRAPHIC_DISPOSED); - + final int DOTS_PER_INCH = 96; long family = OS.pango_font_description_get_family(handle); int length = C.strlen(family); byte[] buffer = new byte[length]; C.memmove(buffer, family, length); String name = new String(Converter.mbcsToWcs(buffer)); float height = (float)OS.pango_font_description_get_size(handle) / OS.PANGO_SCALE; - Point dpi = device.dpi, screenDPI = device.getScreenDPI(); - float size = height * screenDPI.y / dpi.y; + Point dpi = device.dpi; + float size = height * DOTS_PER_INCH / dpi.y; int pangoStyle = OS.pango_font_description_get_style(handle); int pangoWeight = OS.pango_font_description_get_weight(handle); int style = SWT.NORMAL; @@ -254,8 +254,9 @@ public int hashCode() { void init(String name, float height, int style, byte[] fontString) { if (name == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); if (height < 0) SWT.error(SWT.ERROR_INVALID_ARGUMENT); - Point dpi = device.dpi, screenDPI = device.getScreenDPI(); - float size = height * dpi.y / screenDPI.y; + final int DOTS_PER_INCH = 96; + Point dpi = device.dpi; + float size = height * dpi.y / DOTS_PER_INCH; if (fontString != null) { handle = OS.pango_font_description_from_string (fontString); if (handle == 0) SWT.error(SWT.ERROR_NO_HANDLES); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java index 5b52c106f48..0b4bde8ecfc 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/gtk/org/eclipse/swt/widgets/Display.java @@ -5043,7 +5043,8 @@ String debugInfoForIndex(long index) { } void dpiChanged(int newScaleFactor) { - DPIUtil.setDeviceZoom (DPIUtil.mapDPIToZoom(getDPI().x * newScaleFactor)); + final int DOTS_PER_INCH = 96; + DPIUtil.setDeviceZoom (DPIUtil.mapDPIToZoom(DOTS_PER_INCH * newScaleFactor)); Shell[] shells = getShells(); for (int i = 0; i < shells.length; i++) { shells[i].layout(true, true); diff --git a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Device.java b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Device.java index 04c7c51b1c4..1a3783448d3 100644 --- a/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Device.java +++ b/bundles/org.eclipse.swt/Eclipse SWT/win32/org/eclipse/swt/graphics/Device.java @@ -519,7 +519,18 @@ public int getDepth () { * @exception SWTException + * + * @deprecated

This method returns a single global DPI value + * that does not reflect per-monitor DPI settings on modern operating systems. + * In environments with different scaling factors across monitors, it may provide + * a misleading or meaningless result, as it does not correspond to the actual DPI + * of any specific monitor.

+ * + *

Note: While deprecated for general {@code Device} instances like {@code Display}, + * this method may still be validly used when called on a {@code Printer} instance, + * where a single global DPI value is meaningful and expected.

*/ +@Deprecated public Point getDPI () { checkDevice (); long hDC = internal_new_GC (null); diff --git a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/imageanalyzer/ImageAnalyzer.java b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/imageanalyzer/ImageAnalyzer.java index 3285b60eb5a..8debbee97d7 100644 --- a/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/imageanalyzer/ImageAnalyzer.java +++ b/examples/org.eclipse.swt.examples/src/org/eclipse/swt/examples/imageanalyzer/ImageAnalyzer.java @@ -1165,6 +1165,7 @@ void menuPrint() { if (image == null) return; try { + final int DOTS_PER_INCH = 96; // Ask the user to specify the printer. PrintDialog dialog = new PrintDialog(shell, SWT.NONE); if (printerData != null) dialog.setPrinterData(printerData); @@ -1172,9 +1173,8 @@ void menuPrint() { if (printerData == null) return; Printer printer = new Printer(printerData); - Point screenDPI = display.getDPI(); Point printerDPI = printer.getDPI(); - int scaleFactor = printerDPI.x / screenDPI.x; + int scaleFactor = printerDPI.x / DOTS_PER_INCH; Rectangle trim = printer.computeTrim(0, 0, 0, 0); if (printer.startJob(currentName)) { if (printer.startPage()) { diff --git a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet361.java b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet361.java index 56ef65dbeaa..3423008bc82 100644 --- a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet361.java +++ b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet361.java @@ -146,6 +146,7 @@ public void getName(AccessibleEvent e) { } private static void performPrintAction(final Display display, final Shell shell) { + final int DOTS_PER_INCH = 96; Rectangle r = composite.getBounds(); Point p = shell.toDisplay(r.x, r.y); org.eclipse.swt.graphics.Image snapshotImage @@ -159,9 +160,8 @@ private static void performPrintAction(final Display display, final Shell shell) data = dialog.open(); if (data != null) { Printer printer = new Printer(data); - Point screenDPI = display.getDPI(); Point printerDPI = printer.getDPI(); - int scaleFactor = printerDPI.x / screenDPI.x; + int scaleFactor = printerDPI.x / DOTS_PER_INCH; Rectangle trim = printer.computeTrim(0, 0, 0, 0); if (printer.startJob("Print Image")) { ImageData imageData = snapshotImage.getImageData(); diff --git a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet367.java b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet367.java index 54b53dc1d39..8e5b7c2f7d7 100644 --- a/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet367.java +++ b/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet367.java @@ -185,7 +185,7 @@ public int getGcStyle() { createSeparator(shell); - new Label (shell, SWT.NONE).setText ("5. 50x50 box\n(Display#getDPI(): " + display.getDPI().x + ")"); + new Label (shell, SWT.NONE).setText ("5. 50x50 box"); Label box= new Label (shell, SWT.NONE); box.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); box.setLayoutData (new GridData (50, 50)); diff --git a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug507020_WaylandIconsDoubleScaled.java b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug507020_WaylandIconsDoubleScaled.java index 49bb534ffa5..6ebf219bac2 100644 --- a/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug507020_WaylandIconsDoubleScaled.java +++ b/tests/org.eclipse.swt.tests.gtk/ManualTests/org/eclipse/swt/tests/gtk/snippets/Bug507020_WaylandIconsDoubleScaled.java @@ -42,7 +42,7 @@ public static void main (String [] args) { gridData.horizontalSpan = 2; canvas.setLayoutData (gridData); - new Label (shell, SWT.NONE).setText ("5. 50x50 box\n(Display#getDPI(): " + display.getDPI().x + ")"); + new Label(shell, SWT.NONE).setText("5. 50x50 box"); Label box= new Label (shell, SWT.NONE); box.setBackground(display.getSystemColor(SWT.COLOR_WIDGET_DARK_SHADOW)); box.setLayoutData (new GridData (50, 50)); diff --git a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Display.java b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Display.java index c66d1ccc7c1..05fdb3a2444 100644 --- a/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Display.java +++ b/tests/org.eclipse.swt.tests/JUnit Tests/org/eclipse/swt/tests/junit/Test_org_eclipse_swt_widgets_Display.java @@ -1573,6 +1573,7 @@ public void test_wake() { /* custom */ boolean disposeExecRan; +@SuppressWarnings("deprecation") @Test public void test_getDPI() { Display display = new Display();