Skip to content

Conversation

@DenisUngemach
Copy link
Contributor

@DenisUngemach DenisUngemach commented Dec 19, 2025

On Mac.

My system:
Apple M3
16 GB
macOS Tahoe 26.1

With SWT: 3.133.0

In SWT is a bug, which harms the focus handling of embedded awt features.

The scenario is the following:
If we have two SWT_AWT-frames running with our AWT code, then if we switch the perspective, the focus handling of the AWT feature fails. Sometimes one of the two AWT applications no longer can get focus at all.

The reason for this behavior seems to be that the AWT activation will be executed a queue (see class SWT_AWT) and not in the SWT main thread, which means that there is a delay at the execution.
If the parent composite of SWT_AWT already lost the focus, then the AWT frame still can get focus, while the second AWT frame could request the focus at almost the same time. It seems this can break the focus handling of the AWT frame.

Since at a perspective change the focus changes happen very fast in a very short time, this can cause this bug.

As a solution we can synchronize the SWT main thread with the AWT thread.
This means:

  1. first check the focus state of the SWT parent composite and then block the main thread with a very short time
  2. then in the AWT thread execute the activation.
  • If the activation is done release both threads.
  • If the AWT activation freezes or needs more than 200 ms, just release the SWT main thread.

I will check whether I can provide a standalone snippet, which reproduces this bug.

@github-actions
Copy link
Contributor

github-actions bot commented Dec 19, 2025

Test Results (macos)

   54 files  ±0     54 suites  ±0   7m 1s ⏱️ - 1m 30s
4 518 tests ±0  4 275 ✅ ±0  243 💤 ±0  0 ❌ ±0 
  104 runs  ±0    104 ✅ ±0    0 💤 ±0  0 ❌ ±0 

Results for commit b126d65. ± Comparison against base commit 640c747.

♻️ This comment has been updated with latest results.

@akurtakov akurtakov added the macOS happens on macOS label Dec 19, 2025
@DenisUngemach
Copy link
Contributor Author

Not yet working flawlessly, there is still an NPE:

Exception in thread "main" org.eclipse.swt.SWTException: Failed to execute runnable (org.eclipse.swt.SWTException: Widget is disposed)
at org.eclipse.swt.SWT.error(SWT.java:4950)
at org.eclipse.swt.SWT.error(SWT.java:4865)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:135)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:4393)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:4016)
at org.eclipse.swt.awt.SWT_AWT$2.handleEvent(SWT_AWT.java:218)
at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:91)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4671)
at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4660)
at org.eclipse.swt.widgets.Display.release(Display.java:4071)
at org.eclipse.swt.graphics.Device.dispose(Device.java:241)
at org.eclipse.swt.examples.SnippetAwtFeatureFocusBug.main(SnippetAwtFeatureFocusBug.java:60)
Caused by: org.eclipse.swt.SWTException: Widget is disposed
at org.eclipse.swt.SWT.error(SWT.java:4950)
at org.eclipse.swt.SWT.error(SWT.java:4865)
at org.eclipse.swt.SWT.error(SWT.java:4836)
at org.eclipse.swt.widgets.Widget.error(Widget.java:854)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:633)
at org.eclipse.swt.widgets.Control.isFocusControl(Control.java:2305)
at org.eclipse.swt.awt.SWT_AWT$3.lambda$5(SWT_AWT.java:263)
at org.eclipse.swt.awt.SWT_AWT$3.lambda$7(SWT_AWT.java:294)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:40)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:132)
... 9 more

@DenisUngemach
Copy link
Contributor Author

DenisUngemach commented Dec 19, 2025

Snippet for reproduction. Execute the Snippet and click in the left awt TextArea. The focus does not work.
With my fix, it works.
I have tested multiple variantions of TEXT_FIELDS and FOCUS_CHANGES.

At 1000 FOCUS_CHANGES, also my fix can't prevent the focus bug.

By the way my system:
Chip Apple M3
macOS Tahoe 26.1


import java.awt.FlowLayout;
import java.awt.Frame;

import org.eclipse.swt.SWT;
import org.eclipse.swt.awt.SWT_AWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class SnippetAwtFocusBug {


    private static final int TEXT_FIELDS = 1;
    private static final int FOCUS_CHANGES = 0;

    public static void main(String[] args) {
	Display display = new Display();
	Shell shell = new Shell(display);
	shell.setText("SWT-AWT Integration");
	shell.setLayout(new org.eclipse.swt.layout.FillLayout(SWT.HORIZONTAL));

	var c1 = createEmbedding(shell, 0);
	var c2 = createEmbedding(shell, 1);

	c1.addListener(SWT.FocusIn, (e) -> {
	    System.out.println("c1 FocusIn");
	});
	c1.addListener(SWT.FocusOut, (e) -> {
	    System.out.println("c1 FocusOut");
	});

	c2.addListener(SWT.FocusIn, (e) -> {
	    System.out.println("c2 FocusIn");
	});
	c2.addListener(SWT.FocusOut, (e) -> {
	    System.out.println("c2 FocusOut");
	});

	shell.setSize(1000, 800);
	shell.open();


	for (int i = 0; i < FOCUS_CHANGES; i++) {

	    System.out.println("Iteration: " + i);
	    display.readAndDispatch();
	    c1.setFocus();
	    display.readAndDispatch();
	    c2.setFocus();
	    display.readAndDispatch();

	}

	while (!shell.isDisposed()) {
	    if (!display.readAndDispatch())
		display.sleep();
	}

	display.dispose();
    }

    private static Composite createEmbedding(Shell s, int i) {

	Composite c = new Composite(s, SWT.EMBEDDED );

	Frame frame = SWT_AWT.new_Frame(c);

	frame.setLayout(new FlowLayout());

	for (int k = 0; k < TEXT_FIELDS; k++) {
	    var awtButton = new java.awt.TextArea("I am an AWT TextArea");
	    frame.add(awtButton);
	    awtButton.setSize(20, 20);
	}

	return c;

    }

}

@DenisUngemach DenisUngemach marked this pull request as ready for review January 7, 2026 12:41
@DenisUngemach DenisUngemach force-pushed the swt_awt_fix branch 2 times, most recently from 5ba12c5 to 2076c3a Compare January 9, 2026 12:00
@DenisUngemach
Copy link
Contributor Author

Potential NPEs are fixed.

@akurtakov
Copy link
Member

@Phillipus It would be nice if you can take a look at this PR.

@DenisUngemach
Copy link
Contributor Author

Probably the actual bug is caused by the simultaneous activation and deactivation of awt embeddings.

@Phillipus
Copy link
Contributor

Phillipus commented Jan 15, 2026

@Phillipus It would be nice if you can take a look at this PR.

I tested on Mac. I get the same FocusIn and FocusOut messages before the PR and after the PR, but with the PR the caret is visible in c2 when it has the focus.

@DenisUngemach
Copy link
Contributor Author

@Phillipus It would be nice if you can take a look at this PR.

I tested on Mac. I get the same FocusIn and FocusOut messages before the PR and after the PR, but with the PR the caret is visible in c2 when it has the focus.

But without the PR, if you set the focus to the second embedding, it does not work. Can you confirm?

@DenisUngemach
Copy link
Contributor Author

One more point. If both AWT embeddings still work, set the variable

private static final int FOCUS_CHANGES = 0;

to 10

private static final int FOCUS_CHANGES = 10;

or to 100 or 1000.

Then it should definitely break and one side doesn't work anymore.

@Phillipus
Copy link
Contributor

But without the PR, if you set the focus to the second embedding, it does not work. Can you confirm?

With the PR the caret is visible when the second composite gets the focus. Is that the aim?

@DenisUngemach
Copy link
Contributor Author

But without the PR, if you set the focus to the second embedding, it does not work. Can you confirm?

With the PR the caret is visible when the second composite gets the focus. Is that the aim?

With the PR it is the aim, that both textfields can get focus.

Without the PR, you can try to write in both textfields, one of them won't work, because one can't get focus.
Here I clicked on the first textfield and I write 'aaaaa', then I clicked in the second textfield and I write 'aaaaa'.
Only one of them works:

Screenshot 2026-01-16 at 10 28 13

With my PR I can set the focus in both textfields and write in them:
Screenshot 2026-01-16 at 10 33 23

@Phillipus
Copy link
Contributor

Without the PR, you can try to write in both textfields, one of them won't work, because one can't get focus.

Yes, I can confirm the PR allows you to write in both text fields.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macOS happens on macOS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants