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

Đang mở
#3,819 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@Jm6CnDDXBwFTakS đang làm issue này rồi.

Từ ngày 4/11/2026.

  • #3820 của @Jm6CnDDXBwFTakS — đang mở

Đánh giá

Độ khó
1/5
Thời gian dự kiến
Dưới một giờ
Mức phù hợp với người mới
25/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
java
Lĩnh vực
desktop, frontend

Hướng nghiên cứu

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.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.

Ngôn ngữ chính
Java
Star
202
Fork
206
Merge trung bình
1 ngày 17 giờ
Pull request đã merge (30 ngày)
109

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của eclipse-platform/eclipse.platform.swt

Tất cả issue của eclipse-platform/eclipse.platform.swt

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.