-
Notifications
You must be signed in to change notification settings - Fork 180
Description
Describe the bug
On Windows, if JavaFX currently owns the system clipboard (e.g., content set via javafx.scene.input.Clipboard#setContent
), reading the clipboard from an SWT Display
FocusIn
event filter triggers a native crash (access violation in msvcrt.dll
) when a second shell is opened and its Text
control receives certain events (e.g., a key press). This is reproducible with a minimal SWT+JavaFX snippet (below).
In our Eclipse-based product, the regression surfaced when EGit introduced a clipboard property tester (see: eclipse-egit/egit#48): The tester runs during focus activation, causing the clipboard to be read in FocusIn
. The clipboard property tester was deactivated by default (eclipse-egit/egit#83), which solves the crash in our product for now, but the issue still exists in SWT/JavaFX.
Steps to reproduce
- Start the following snippet (requires JavaFX)
import java.util.Collections;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import javafx.application.Platform;
import javafx.scene.input.Clipboard;
import javafx.scene.input.DataFormat;
public final class SwtSnippet {
public static void main(String[] args) {
// Start JavaFX runtime and set clipboard content
Platform.startup(() -> Clipboard.getSystemClipboard()
.setContent(Collections.singletonMap(DataFormat.PLAIN_TEXT, "JavaFX Clipboard Content")));
Display display = new Display();
Shell shell = new Shell(display);
// Query the clipboard contents on FocusIn events
display.addFilter(SWT.FocusIn, a -> {
org.eclipse.swt.dnd.Clipboard clipboard = new org.eclipse.swt.dnd.Clipboard(display);
clipboard.getContents(TextTransfer.getInstance());
clipboard.dispose();
});
shell.open();
// Open another shell which displays a text field
Shell dlg = new Shell(shell, SWT.NONE);
dlg.setLayout(new FillLayout());
new Text(dlg, SWT.NONE);
dlg.open();
while (!dlg.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
}
}
- The second shell appears.
- Type any character on the keyboard. Result: the JVM crashes.
--------------- T H R E A D ---------------
Current thread (0x000001c8311ffce0): JavaThread "main" [_thread_in_native, id=17476, stack(0x0000006a22200000,0x0000006a22300000) (1024K)]
Stack: [0x0000006a22200000,0x0000006a22300000], sp=0x0000006a222fe188, free space=1016k
Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
C [msvcrt.dll+0x74414]
C [COMCTL32.dll+0x12f7f]
C [COMCTL32.dll+0x407a5]
C [COMCTL32.dll+0x3fa49]
C [COMCTL32.dll+0x11c79]
C [COMCTL32.dll+0x110ca]
C [USER32.dll+0xef5c]
C [USER32.dll+0xe9de]
C 0x000001c83e3a0736
The last pc belongs to native method entry point (kind = native) (printed below).
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
j org.eclipse.swt.internal.win32.OS.CallWindowProc(JJIJJ)J+0
j org.eclipse.swt.widgets.Text.callWindowProc(JIJJ)J+1111
j org.eclipse.swt.widgets.Control.windowProc(JIJJ)J+2062
j org.eclipse.swt.widgets.Text.windowProc(JIJJ)J+395
j org.eclipse.swt.widgets.Display.windowProc(JJJJ)J+21
v ~StubRoutines::call_stub 0x000001c83e39100d
j org.eclipse.swt.internal.win32.OS.DispatchMessage(Lorg/eclipse/swt/internal/win32/MSG;)J+0
j org.eclipse.swt.widgets.Display.readAndDispatch()Z+64
j SwtSnippet.main([Ljava/lang/String;)V+78
v ~StubRoutines::call_stub 0x000001c83e39100d
siginfo: EXCEPTION_ACCESS_VIOLATION (0xc0000005), writing address 0x0000000000000000
Environment:
- Windows
- Java 21 to 23
- JavaFX 19 to 23
- recent SWT (2024 and later)