Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import java.util.*;
import java.util.List;
import java.util.function.*;
import java.util.stream.*;

import org.eclipse.swt.*;
Expand Down Expand Up @@ -494,9 +495,11 @@ public void copyArea (Image image, int x, int y) {
private abstract class ImageOperation extends Operation {
private Image image;

private final Consumer<Image> disposeCallback = this::setCopyOfImage;

ImageOperation(Image image) {
setImage(image);
image.addOnDisposeListener(this::setCopyOfImage);
image.addOnDisposeListener(disposeCallback);
}

private void setImage(Image image) {
Expand All @@ -515,6 +518,11 @@ protected Image getImage() {
return image;
}

@Override
void disposeAll() {
image.removeOnDisposeListener(disposeCallback);
super.disposeAll();
}
}

private class CopyAreaToImageOperation extends ImageOperation {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1020,10 +1020,18 @@ void addOnDisposeListener(Consumer<Image> onDisposeListener) {
onDisposeListeners.add(onDisposeListener);
}

void removeOnDisposeListener(Consumer<Image> onDisposeListener) {
if (onDisposeListeners == null) {
return;
}
onDisposeListeners.remove(onDisposeListener);
}

@Override
public void dispose() {
if (onDisposeListeners != null) {
onDisposeListeners.forEach(listener -> listener.accept(this));
onDisposeListeners.clear();
}
super.dispose();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import static org.junit.jupiter.api.Assumptions.assumeFalse;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.swt.SWT;
Expand Down Expand Up @@ -804,6 +805,24 @@ public void test_bug1288_createGCFromImageFromNonDisplayThread() throws Interrup
assertNull(exceptionReference.get(), "Creating a GC from an Image without a device threw an exception");
}

// Tests that a GC instance is cleaned from memory after it was disposed.
// Primarily supposed to test that the operations (currently only implemented for Windows) do not produce any leaks.
@Test
public void test_noMemoryLeakAfterDispose() {
GC testGC = new GC(display);
Image image = new Image(display, 1, 1);
testGC.setFont(display.getSystemFont());
testGC.setClipping(new Rectangle(0, 0, 2, 2));
testGC.drawImage(image, 0, 0);
testGC.drawText("Test", 0, 0);
testGC.drawLine(0, 0, 5, 5);
WeakReference<GC> testGCReference = new WeakReference<>(testGC);
testGC.dispose();
testGC = null;
System.gc();
assertNull(testGCReference.get());
}

/* custom */
Display display;
Shell shell;
Expand Down
Loading