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 @@ -627,6 +627,17 @@ LRESULT WM_CHAR (long wParam, long lParam) {
return result;
}

@Override
LRESULT WM_ERASEBKGND (long wParam, long lParam) {
LRESULT result = super.WM_ERASEBKGND (wParam, lParam);
if (result != null) return result;
/*
* Feature in Windows. The SysLink control flashes when resized.
* The fix is to prevent the background from being erased.
*/
return LRESULT.ONE;
}

@Override
LRESULT WM_GETDLGCODE (long wParam, long lParam) {
long code = callWindowProc (handle, OS.WM_GETDLGCODE, wParam, lParam);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package org.eclipse.swt.tests.win32.widgets;

import static org.junit.jupiter.api.Assertions.*;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Shell;
import org.junit.jupiter.api.Test;

public class Test_org_eclipse_swt_widgets_Link {

@Test
public void test_LinkRendersCorrectlyAfterResize() {
Display display = new Display();
try {
Shell shell = new Shell(display);
shell.setSize(400, 300);
Link link = new Link(shell, SWT.NONE);
link.setText("Visit <a href=\"https://eclipse.org\">Eclipse</a> website");
link.setBounds(10, 10, 200, 50);

shell.open();

// Force initial paint
while (display.readAndDispatch()) {
// loop until no more events
}

// Resize multiple times rapidly (stress test for flicker)
for (int i = 0; i < 10; i++) {
link.setSize(200 + (i * 10), 50 + (i * 5));
while (display.readAndDispatch()) {
// loop until no more events
}
}

// Verify link is still functional and sized correctly
Point size = link.getSize();
assertTrue(size.x > 0 && size.y > 0, "Link should have valid size after resize");
assertEquals("Visit <a href=\"https://eclipse.org\">Eclipse</a> website",
link.getText(), "Link text should be preserved after resize");

// Verify the link is still visible and has proper bounds
Rectangle bounds = link.getBounds();
assertTrue(bounds.width > 0 && bounds.height > 0,
"Link should have valid bounds after multiple resizes");

shell.close();
} finally {
display.dispose();
}
}

@Test
public void test_LinkBackgroundNotErasedDuringPaint() {
Display display = new Display();
try {
Shell shell = new Shell(display);
Link link = new Link(shell, SWT.NONE);
link.setText("Test <a>link</a>");

final int[] paintCount = {0};
final int[] eraseCount = {0};

// Monitor paint events
link.addListener(SWT.Paint, e -> paintCount[0]++);
link.addListener(SWT.EraseItem, e -> eraseCount[0]++);

shell.setSize(300, 200);
shell.open();

// Trigger redraws
for (int i = 0; i < 5; i++) {
link.redraw();
while (display.readAndDispatch()) {
// loop until no more events
}
}

// We should see paints, but minimal erase operations
assertTrue(paintCount[0] > 0, "Link should have been painted");
// Note: EraseItem may not fire for Link widget, this is platform-specific

shell.close();
} finally {
display.dispose();
}
}

@Test
public void test_LinkMaintainsContentDuringRapidResize() {
Display display = new Display();
try {
Shell shell = new Shell(display);
shell.setSize(400, 300);
Link link = new Link(shell, SWT.NONE);
String testText = "Click <a href=\"page1\">here</a> or <a href=\"page2\">there</a>";
link.setText(testText);
link.setBounds(10, 10, 300, 100);

shell.open();
while (display.readAndDispatch()) {
// loop until no more events
}

// Rapidly resize - this would cause flickering in the old implementation
for (int i = 0; i < 20; i++) {
int newWidth = 200 + (i % 2) * 100;
int newHeight = 50 + (i % 2) * 30;
link.setSize(newWidth, newHeight);

// Process events but don't wait for full redraw
display.readAndDispatch();

// Content should remain intact
assertEquals(testText, link.getText(),
"Link text should remain unchanged during resize iteration " + i);
}

shell.close();
} finally {
display.dispose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Link;
import org.junit.jupiter.api.BeforeEach;
Expand Down Expand Up @@ -62,6 +65,7 @@ public void test_ConstructorLorg_eclipse_swt_widgets_CompositeI() {
fail("No exception thrown for parent == null");
}
catch (IllegalArgumentException e) {
// expected
}
}

Expand All @@ -82,6 +86,7 @@ public void widgetDefaultSelected(SelectionEvent e) {
link.addSelectionListener(null);
fail("No exception thrown for addSelectionListener with null argument");
} catch (IllegalArgumentException e) {
// expected
}

link.addSelectionListener(listener);
Expand All @@ -92,6 +97,7 @@ public void widgetDefaultSelected(SelectionEvent e) {
link.removeSelectionListener(null);
fail("No exception thrown for removeSelectionListener with null argument");
} catch (IllegalArgumentException e) {
// expected
}
listenerCalled = false;
link.removeSelectionListener(listener);
Expand Down Expand Up @@ -172,6 +178,7 @@ public void test_setTextLjava_lang_String() {
link.setText(null);
fail("No exception thrown for text == null");
} catch (IllegalArgumentException e) {
// expected
}
}

Expand All @@ -184,4 +191,90 @@ public void test_setLinkForegroundLorg_eclipse_swt_graphics_Color() {
link.setLinkForeground(null);
assertNotEquals(color, link.getForeground());
}


@Test
public void test_LinkRendersCorrectlyAfterResize() {
shell.setSize(400, 300);
link.setText("Visit <a href=\"https://eclipse.org\">Eclipse</a> website");
link.setBounds(10, 10, 200, 50);

shell.open();

Display display = shell.getDisplay();
// Force initial paint
while (display.readAndDispatch()) {
// loop until no more events
}

// Resize multiple times rapidly (stress test for flicker)
for (int i = 0; i < 10; i++) {
link.setSize(200 + (i * 10), 50 + (i * 5));
while (display.readAndDispatch()) {
// loop until no more events
}
}

// Verify link is still functional and sized correctly
Point size = link.getSize();
assertTrue(size.x > 0 && size.y > 0, "Link should have valid size after resize");
assertEquals("Visit <a href=\"https://eclipse.org\">Eclipse</a> website",
link.getText(), "Link text should be preserved after resize");

// Verify the link is still visible and has proper bounds
Rectangle bounds = link.getBounds();
assertTrue(bounds.width > 0 && bounds.height > 0,
"Link should have valid bounds after multiple resizes");
}

@Test
public void test_LinkBackgroundNotErasedDuringPaint() {
link.setText("Test <a>link</a>");

shell.setSize(300, 200);
link.setVisible(true);
shell.open();

Display display = shell.getDisplay();
// Trigger redraws and ensure no crashes or obvious rendering failure
for (int i = 0; i < 10; i++) {
link.redraw();
link.update();
while (display.readAndDispatch()) {
// loop until no more events
}
}

// Verify the link is still valid and has correct text
assertFalse(link.isDisposed(), "Link should not be disposed after multiple redraws");
assertEquals("Test <a>link</a>", link.getText(), "Link text should be intact");
}

@Test
public void test_LinkMaintainsContentDuringRapidResize() {
shell.setSize(400, 300);
String testText = "Click <a href=\"page1\">here</a> or <a href=\"page2\">there</a>";
link.setText(testText);
link.setBounds(10, 10, 300, 100);

shell.open();
Display display = shell.getDisplay();
while (display.readAndDispatch()) {
// loop until no more events
}

// Rapidly resize - this would cause flickering in the old implementation
for (int i = 0; i < 20; i++) {
int newWidth = 200 + (i % 2) * 100;
int newHeight = 50 + (i % 2) * 30;
link.setSize(newWidth, newHeight);

// Process events but don't wait for full redraw
display.readAndDispatch();

// Content should remain intact
assertEquals(testText, link.getText(),
"Link text should remain unchanged during resize iteration " + i);
}
}
}
Loading