mirror of
https://github.com/JetBrains/JetBrainsRuntime.git
synced 2025-12-06 09:29:38 +01:00
JBR-4362 [mac] system menu opens with duplicated items
(cherry picked from commit e32defe49d)
This commit is contained in:
@@ -306,19 +306,24 @@ public class AWTThreading {
|
||||
|
||||
@Override
|
||||
public void dispatch() {
|
||||
completeIfNotYet(super::dispatch);
|
||||
futureResult.complete(null);
|
||||
// Should not complete if competion has already started.
|
||||
if (completeIfNotYet(super::dispatch)) {
|
||||
futureResult.complete(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void dispose(String reason) {
|
||||
completeIfNotYet(() -> AWTAccessor.getInvocationEventAccessor().dispose(this));
|
||||
// Should complete exceptionally regardless of whether completetion has alredy started or hasn't.
|
||||
futureResult.completeExceptionally(new Throwable(reason));
|
||||
}
|
||||
|
||||
private void completeIfNotYet(Runnable competeRunnable) {
|
||||
private boolean completeIfNotYet(Runnable competeRunnable) {
|
||||
if (!isCompletionStarted.getAndSet(true)) {
|
||||
competeRunnable.run();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.Arrays;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import sun.lwawt.macosx.CThreading;
|
||||
@@ -59,18 +60,24 @@ public class AWTThreadingTest {
|
||||
|
||||
testCase().
|
||||
withCaption("certain threads superposition").
|
||||
withRunnable(AWTThreadingTest::test, false).
|
||||
withRunnable(AWTThreadingTest::test1, false).
|
||||
run();
|
||||
|
||||
testCase().
|
||||
withCaption("random threads superposition").
|
||||
withRunnable(AWTThreadingTest::test, false).
|
||||
withRunnable(AWTThreadingTest::test1, false).
|
||||
run();
|
||||
|
||||
testCase().
|
||||
withCaption("JBR-4362").
|
||||
withRunnable(AWTThreadingTest::test2, false).
|
||||
withCompletionTimeout(3).
|
||||
run();
|
||||
|
||||
System.out.println("Test PASSED");
|
||||
}
|
||||
|
||||
static void test() {
|
||||
static void test1() {
|
||||
ITER_COUNTER.set(0);
|
||||
|
||||
var timer = new TestTimer(TIMEOUT_SECONDS * 3, TimeUnit.SECONDS);
|
||||
@@ -145,6 +152,53 @@ public class AWTThreadingTest {
|
||||
THREAD.start();
|
||||
}
|
||||
|
||||
static void test2() {
|
||||
var invocations = new CountDownLatch(1);
|
||||
var invokeAndWaitCompleted = new AtomicBoolean(false);
|
||||
|
||||
var log = new Consumer<String>() {
|
||||
public void accept(String msg) {
|
||||
System.out.println(msg);
|
||||
System.out.flush();
|
||||
}
|
||||
};
|
||||
|
||||
CThreading.executeOnAppKit(() -> {
|
||||
log.accept("executeOnAppKit - entered");
|
||||
|
||||
//
|
||||
// It's expected that LWCToolkit.invokeAndWait() does not exit before its invocation completes.
|
||||
//
|
||||
tryRun(() -> LWCToolkit.invokeAndWait(() -> {
|
||||
log.accept("\tinvokeAndWait - entered");
|
||||
|
||||
AWTThreading.executeWaitToolkit(() -> {
|
||||
log.accept("\t\texecuteWaitToolkit - entered");
|
||||
|
||||
LWCToolkit.performOnMainThreadAndWait(() -> log.accept("\t\t\tperformOnMainThreadAndWait - entered"));
|
||||
|
||||
log.accept("\t\t\tperformOnMainThreadAndWait - exited");
|
||||
});
|
||||
|
||||
invokeAndWaitCompleted.set(true);
|
||||
log.accept("\t\texecuteWaitToolkit - exited");
|
||||
}, FRAME));
|
||||
|
||||
log.accept("\tinvokeAndWait - exited");
|
||||
|
||||
if (!invokeAndWaitCompleted.get()) {
|
||||
TEST_CASE_RESULT.completeExceptionally(new Throwable("Premature exit from invokeAndWait"));
|
||||
}
|
||||
|
||||
invocations.countDown();
|
||||
});
|
||||
|
||||
await(invocations, TIMEOUT_SECONDS * 2);
|
||||
log.accept("executeOnAppKit + await - exited");
|
||||
|
||||
TEST_CASE_RESULT.complete(true);
|
||||
}
|
||||
|
||||
static void dumpAllThreads() {
|
||||
Thread.getAllStackTraces().keySet().forEach(t -> {
|
||||
System.out.printf("%s\t%s\t%d\t%s\n", t.getName(), t.getState(), t.getPriority(), t.isDaemon() ? "Daemon" : "Normal");
|
||||
|
||||
@@ -39,8 +39,8 @@ import static helper.ToolkitTestHelper.TestCase.*;
|
||||
* @summary Tests different scenarios for LWCToolkit.invokeAndWait().
|
||||
* @requires (os.family == "mac")
|
||||
* @modules java.desktop/sun.lwawt.macosx java.desktop/sun.awt
|
||||
* @run main/othervm -Dsun.lwawt.macosx.LWCToolkit.invokeAndWait.disposeOnEDTFree=true LWCToolkitInvokeAndWaitTest
|
||||
* @run main/othervm -Dlog.level.FINER=true -Dsun.lwawt.macosx.LWCToolkit.invokeAndWait.disposeOnEDTFree=true LWCToolkitInvokeAndWaitTest
|
||||
* @run main LWCToolkitInvokeAndWaitTest
|
||||
* @run main/othervm -Dlog.level.FINER=true LWCToolkitInvokeAndWaitTest
|
||||
* @author Anton Tarasov
|
||||
*/
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@@ -53,6 +53,8 @@ public class LWCToolkitInvokeAndWaitTest {
|
||||
static volatile CountDownLatch EDT_FAST_FREE_LATCH;
|
||||
|
||||
static {
|
||||
System.setProperty("sun.lwawt.macosx.LWCToolkit.invokeAndWait.disposeOnEDTFree", "true");
|
||||
|
||||
AWTThreading.setAWTThreadingFactory(edt -> new AWTThreading(edt) {
|
||||
@Override
|
||||
public CompletableFuture<Void> onEventDispatchThreadFree(Runnable runnable) {
|
||||
|
||||
@@ -29,6 +29,8 @@ import sun.lwawt.macosx.LWCToolkit;
|
||||
import javax.swing.*;
|
||||
import javax.swing.Timer;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.util.Optional;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Callable;
|
||||
@@ -86,6 +88,7 @@ public class ToolkitTestHelper {
|
||||
handler.uncaughtException(t, e);
|
||||
});
|
||||
|
||||
CountDownLatch showLatch = new CountDownLatch(1);
|
||||
tryRun(() -> EventQueue.invokeAndWait(() -> {
|
||||
FRAME = new JFrame(testClass.getSimpleName());
|
||||
LABEL = new JLabel("0");
|
||||
@@ -96,8 +99,16 @@ public class ToolkitTestHelper {
|
||||
FRAME.setLocationRelativeTo(null);
|
||||
FRAME.setSize(200, 200);
|
||||
FRAME.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
|
||||
FRAME.addComponentListener(new ComponentAdapter() {
|
||||
@Override
|
||||
public void componentShown(ComponentEvent e) {
|
||||
showLatch.countDown();
|
||||
}
|
||||
});
|
||||
FRAME.setVisible(true);
|
||||
}));
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
tryRun(() -> showLatch.await(1, TimeUnit.SECONDS));
|
||||
|
||||
Timer timer = new Timer(100, e -> UPDATE_LABEL.run());
|
||||
timer.setRepeats(true);
|
||||
|
||||
3
test/jdk/jbA11yProblemList.txt
Normal file
3
test/jdk/jbA11yProblemList.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
java/awt/Toolkit/LWCToolkitInvokeAndWaitTest.java nobug macosx-all,linux-all,windows-all
|
||||
java/awt/Toolkit/AWTThreadingTest.java nobug macosx-all,linux-all,windows-all
|
||||
java/awt/Toolkit/AWTThreadingCMenuTest.java nobug macosx-all,linux-all,windows-all
|
||||
Reference in New Issue
Block a user