[Cocoa] NPE in Text.shouldChangeTextInRange_replacementString when the press-and-hold accent menu inserts text

Abierto
#3,819 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@Jm6CnDDXBwFTakS ya está trabajando en esto.

Desde el 4/11/2026.

  • #3820 de @Jm6CnDDXBwFTakS — abierto

Evaluación

Dificultad
1/5
Tiempo estimado
Menos de una hora
Aptitud para principiantes
25/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Estancado
Stack tecnológico
java
Área
desktop, frontend

Línea de trabajo

The stack trace points to Text.shouldChangeTextInRange_replacementString in the Cocoa Text implementation. Read the null-event handling shown in the issue and check the surrounding VerifyListener path; reproduce with the provided press-and-hold snippet. Done when selecting an accent after waiting inserts it without throwing a NullPointerException; a linked pull request is already open.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Describe the bug
In a Text with a VerifyListener, picking an accent from macOS's press-and-hold menu (è é ê ë ...) more than about 0.2 s after letting go of the key inserts nothing, and SWT throws a NullPointerException:

java.lang.NullPointerException: Cannot invoke "org.eclipse.swt.internal.cocoa.NSEvent.type()" because "currentEvent" is null
	at org.eclipse.swt.widgets.Text.shouldChangeTextInRange_replacementString(Text.java:2375)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:6685)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSendSuper(Native Method)
	at org.eclipse.swt.widgets.Widget.callSuper(Widget.java:239)
	at org.eclipse.swt.widgets.Widget.insertText(Widget.java:1114)
	at org.eclipse.swt.widgets.Control.insertText(Control.java:2102)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:6433)
	at org.eclipse.swt.internal.cocoa.OS.objc_msgSend_bool(Native Method)
	at org.eclipse.swt.internal.cocoa.NSRunLoop.runMode(NSRunLoop.java:40)
	at org.eclipse.swt.widgets.Display.sleep(Display.java:5214)
	at PressAndHoldVerifySnippet.main(PressAndHoldVerifySnippet.java:18)

In a standalone program the exception is not caught, so it ends the event loop and the program exits. In the Eclipse workbench it is logged and the "e" stays.

Cause: insertText arrives from the run loop while Display.sleep runs, so NSApplication.currentEvent() returns null. Text.shouldChangeTextInRange_replacementString (Cocoa) then calls type() on it without a null check:

if (hooks (SWT.Verify)) {
	NSEvent currentEvent = display.application.currentEvent();
	long type = currentEvent.type();          // currentEvent is null here
	if (type != OS.NSKeyDown && type != OS.NSKeyUp) currentEvent = null;
	newText = verifyText(text, (int)range.location, (int)(range.location+range.length),  currentEvent);
}

A click within about 0.2 s works because the key-up is then still the current event. A Text without a VerifyListener never runs this code and takes every click.

To Reproduce
Run with -XstartOnFirstThread. Hold E until the accent menu appears, let go of E, wait about a second, then click an accent such as é.

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class PressAndHoldVerifySnippet {
	public static void main(String[] args) {
		Display display = new Display();
		Shell shell = new Shell(display);
		shell.setLayout(new FillLayout());
		Text text = new Text(shell, SWT.SINGLE | SWT.BORDER);
		text.addVerifyListener(e -> { }); // any verify listener triggers the bug
		shell.setSize(300, 80);
		shell.open();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		display.dispose();
	}
}

Without the addVerifyListener line, every click inserts the accent.

Expected behavior
The accent replaces the "e", as it does in a Text without a VerifyListener and in native macOS text views such as TextEdit.

Screenshots
None.

Environment:

  1. Select the platform(s) on which the behavior is seen:
    • All OS
    • Windows
    • Linux
    • macOS
  1. Additional OS info (e.g. OS version, Linux Desktop, etc)
    macOS 27.2 (26B123), Apple silicon (arm64), "ABC" input source, press-and-hold enabled (the default; ApplePressAndHoldEnabled not set).

  2. JRE/JDK version
    OpenJDK 25

Version since
Seen on SWT 3.135.0.v20260819-1952 (org.eclipse.swt.cocoa.macosx.aarch64). The same code, without a null check, is still on master.

Workaround (or) Additional context
Suggested fix: check for null before calling type(), so a missing event is treated like a non-key event:

NSEvent currentEvent = display.application.currentEvent();
if (currentEvent != null) {
	long type = currentEvent.type();
	if (type != OS.NSKeyDown && type != OS.NSKeyUp) currentEvent = null;
}

I'd be happy to open a pull request with this change.

Lenguaje dominante
Java
Estrellas
202
Forks
206
Merge medio
1 d 14 h
PR fusionados (30 d)
103

Preparar el entorno

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de eclipse-platform/eclipse.platform.swt

Todos los issues de eclipse-platform/eclipse.platform.swt

Issues similares

Más issues de Java

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.