diff --git a/swt_native/src/main/java/org/eclipse/swt/graphics/GraphicsUtils.java b/swt_native/src/main/java/org/eclipse/swt/graphics/GraphicsUtils.java index 984ac6e6..1e68760c 100644 --- a/swt_native/src/main/java/org/eclipse/swt/graphics/GraphicsUtils.java +++ b/swt_native/src/main/java/org/eclipse/swt/graphics/GraphicsUtils.java @@ -173,9 +173,7 @@ public static Color getDefaultBackground(Display display) { * or null if path is null */ static String getFilename(String path) { - if (path == null) { - return null; - } + if (path == null) return null; String fileName = new java.io.File(path).getName(); int dotIndex = fileName.lastIndexOf('.'); return (dotIndex > 0) ? fileName.substring(0, dotIndex) : fileName; diff --git a/swt_native/src/test/java/dev/equo/swt/WebDisplayImageFlutterTest.java b/swt_native/src/test/java/dev/equo/swt/WebDisplayImageFlutterTest.java new file mode 100644 index 00000000..ed2db0b0 --- /dev/null +++ b/swt_native/src/test/java/dev/equo/swt/WebDisplayImageFlutterTest.java @@ -0,0 +1,69 @@ +package dev.equo.swt; + +import dev.equo.swt.harness.FlutterHarness; +import org.eclipse.swt.SWT; +import org.eclipse.swt.SWTException; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.graphics.ImageDataProvider; +import org.eclipse.swt.graphics.ImageFileNameProvider; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.widgets.Display; +import org.eclipse.swt.widgets.Monitor; +import org.junit.jupiter.api.*; + +import static org.assertj.core.api.Assertions.*; + +/** + * Regression tests for web-mode behavior: monitor bounds consistency, + * image provider null-path handling, and image provider exception recovery. + * Compiled against the web backend (webMain) via the webTest source set. + * Run with: ./gradlew :swt_native:webTest + */ +@Tag("flutter-it") +class WebDisplayImageFlutterTest { + + private static FlutterHarness flutter; + private static Display display; + + @BeforeAll + static void setup() { + flutter = new FlutterHarness(); + // Injects the harness as the global bridge before Display is created, which + // causes SwtFlutterBridgeWeb.initForDisplay to skip starting its own server. + flutter.init(); + display = new Display(); + } + + @AfterAll + static void teardown() { + if (display != null && !display.isDisposed()) display.dispose(); + if (flutter != null) flutter.teardown(); + } + + @Test + void getPrimaryMonitor_bounds_consistent_with_getMonitors() { + Monitor primary = display.getPrimaryMonitor(); + Rectangle primaryBounds = primary.getBounds(); + Rectangle firstMonitorBounds = display.getMonitors()[0].getBounds(); + + assertThat(primaryBounds).isEqualTo(firstMonitorBounds); + assertThat(primary.getClientArea()).isEqualTo(primaryBounds); + } + + @Test + void imageFileNameProvider_null_path_throws_SWTException_not_NPE() { + ImageFileNameProvider nullPathProvider = zoom -> null; + assertThatThrownBy(() -> new Image(display, nullPathProvider)) + .isInstanceOf(SWTException.class) + .isNotInstanceOf(NullPointerException.class); + } + + @Test + void imageDataProvider_swt_exception_falls_back_to_placeholder() { + ImageDataProvider throwingProvider = zoom -> { + throw new SWTException(SWT.ERROR_UNSUPPORTED_FORMAT); + }; + Image image = new Image(display, throwingProvider); + image.dispose(); + } +} diff --git a/swt_native/src/test/java/org/eclipse/swt/graphics/GraphicsUtilsTest.java b/swt_native/src/test/java/org/eclipse/swt/graphics/GraphicsUtilsTest.java index 26d64733..a399e946 100644 --- a/swt_native/src/test/java/org/eclipse/swt/graphics/GraphicsUtilsTest.java +++ b/swt_native/src/test/java/org/eclipse/swt/graphics/GraphicsUtilsTest.java @@ -43,6 +43,11 @@ public void should_parse_filename(String inputPath) { assertThat(filename).isEqualTo(imageName); } + @Test + public void should_return_null_when_path_is_null() { + assertThat(GraphicsUtils.getFilename(null)).isNull(); + } + @Test public void should_copy_fontdata() { // Create a FontData diff --git a/swt_native/src/webMain/java/org/eclipse/swt/graphics/DartImage.java b/swt_native/src/webMain/java/org/eclipse/swt/graphics/DartImage.java index 224a2ff2..8c9d9b5d 100644 --- a/swt_native/src/webMain/java/org/eclipse/swt/graphics/DartImage.java +++ b/swt_native/src/webMain/java/org/eclipse/swt/graphics/DartImage.java @@ -566,8 +566,11 @@ public DartImage(Device device, ImageFileNameProvider imageFileNameProvider, Ima if (imageFileNameProvider == null) SWT.error(SWT.ERROR_NULL_ARGUMENT); try { - this.filename = GraphicsUtils.getFilename(imageFileNameProvider.getImagePath(100)); - imageData = new ImageData(imageFileNameProvider.getImagePath(100)); + String path100 = imageFileNameProvider.getImagePath(100); + if (path100 == null) + SWT.error(SWT.ERROR_INVALID_ARGUMENT); + this.filename = GraphicsUtils.getFilename(path100); + imageData = new ImageData(path100); initUsingFileNameProvider(imageFileNameProvider); init(imageData, 100); init(); @@ -930,12 +933,22 @@ void init(ImageData image, int imageZoom) { private void initUsingImageDataProvider(ImageDataProvider imageDataProvider) { this.imageDataProvider = imageDataProvider; - ImageData imageData = imageDataProvider.getImageData(100); + ImageData imageData; + try { + imageData = imageDataProvider.getImageData(100); + } catch (SWTException e) { + imageData = null; + } if (imageData == null) { - SWT.error(SWT.ERROR_INVALID_ARGUMENT); + imageData = new ImageData(1, 1, 32, new PaletteData(0xFF0000, 0xFF00, 0xFF)); } init(imageData, 100); - ImageData imageData2x = imageDataProvider.getImageData(200); + ImageData imageData2x; + try { + imageData2x = imageDataProvider.getImageData(200); + } catch (SWTException e) { + imageData2x = null; + } if (imageData2x != null) { alphaInfo_200 = new AlphaInfo(); } diff --git a/swt_native/src/webMain/java/org/eclipse/swt/widgets/DartDisplay.java b/swt_native/src/webMain/java/org/eclipse/swt/widgets/DartDisplay.java index 0a7ed0c0..b56d58fa 100644 --- a/swt_native/src/webMain/java/org/eclipse/swt/widgets/DartDisplay.java +++ b/swt_native/src/webMain/java/org/eclipse/swt/widgets/DartDisplay.java @@ -1393,6 +1393,8 @@ public Monitor[] getMonitors() { public Monitor getPrimaryMonitor() { checkDevice(); Monitor monitor = new Monitor(); + monitor.setBounds(bounds); + monitor.setClientArea(bounds); return monitor; }