PotemkinProgress: don't walk Swing hierarchy too often

This commit is contained in:
peter
2018-10-08 09:07:27 +02:00
parent 5c2efff944
commit bb5f074e2c
@@ -2,6 +2,7 @@
package com.intellij.openapi.progress.util;
import com.intellij.ide.IdeEventQueue;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressManager;
@@ -26,6 +27,7 @@ import java.util.concurrent.TimeUnit;
* @author peter
*/
public class PotemkinProgress extends ProgressWindow implements PingProgress {
private final Application myApp = ApplicationManager.getApplication();
private long myLastUiUpdate = System.currentTimeMillis();
private final LinkedBlockingQueue<InputEvent> myInputEvents = new LinkedBlockingQueue<>();
private final LinkedBlockingQueue<InvocationEvent> myInvocationEvents = new LinkedBlockingQueue<>();
@@ -33,7 +35,7 @@ public class PotemkinProgress extends ProgressWindow implements PingProgress {
public PotemkinProgress(@NotNull String title, @Nullable Project project, @Nullable JComponent parentComponent, @Nullable String cancelText) {
super(cancelText != null,false, project, parentComponent, cancelText);
setTitle(title);
ApplicationManager.getApplication().assertIsDispatchThread();
myApp.assertIsDispatchThread();
startStealingInputEvents();
}
@@ -67,15 +69,21 @@ public class PotemkinProgress extends ProgressWindow implements PingProgress {
return Objects.requireNonNull(super.getDialog());
}
private long myLastInteraction;
@Override
public void interact() {
if (ApplicationManager.getApplication().isDispatchThread()) {
long now = System.currentTimeMillis();
if (shouldDispatchAwtEvents(now)) {
dispatchAwtEventsWithoutModelAccess(0);
}
updateUI(now);
if (!myApp.isDispatchThread()) return;
long now = System.currentTimeMillis();
if (now == myLastInteraction) return;
myLastInteraction = now;
if (getDialog().getPanel().isShowing()) {
dispatchAwtEventsWithoutModelAccess(0);
}
updateUI(now);
}
private void dispatchAwtEventsWithoutModelAccess(int timeoutMs) {
@@ -95,14 +103,6 @@ public class PotemkinProgress extends ProgressWindow implements PingProgress {
}
}
private long myLastShouldDispatchCheck;
private boolean shouldDispatchAwtEvents(long now) {
if (now == myLastShouldDispatchCheck) return false;
myLastShouldDispatchCheck = now;
return getDialog().getPanel().isShowing();
}
private void dispatchInputEvent(@NotNull InputEvent e) {
if (isCancellationEvent(e)) {
cancel();
@@ -121,7 +121,7 @@ public class PotemkinProgress extends ProgressWindow implements PingProgress {
}
private void updateUI(long now) {
if (ApplicationManager.getApplication().isUnitTestMode()) return;
if (myApp.isUnitTestMode()) return;
JRootPane rootPane = getDialog().getPanel().getRootPane();
if (rootPane == null) {
rootPane = considerShowingDialog(now);
@@ -178,7 +178,7 @@ public class PotemkinProgress extends ProgressWindow implements PingProgress {
/** Executes the action in EDT, paints itself inside checkCanceled calls. */
public void runInSwingThread(@NotNull Runnable action) {
ApplicationManager.getApplication().assertIsDispatchThread();
myApp.assertIsDispatchThread();
try {
ProgressManager.getInstance().runProcess(action, this);
}
@@ -190,7 +190,7 @@ public class PotemkinProgress extends ProgressWindow implements PingProgress {
/** Executes the action in a background thread, block Swing thread, handles selected input events and paints itself periodically. */
public void runInBackground(@NotNull Runnable action) {
ApplicationManager.getApplication().assertIsDispatchThread();
myApp.assertIsDispatchThread();
enterModality();
try {
@@ -210,7 +210,7 @@ public class PotemkinProgress extends ProgressWindow implements PingProgress {
private void ensureBackgroundThreadStarted(@NotNull Runnable action) {
Semaphore started = new Semaphore();
started.down();
ApplicationManager.getApplication().executeOnPooledThread(() -> ProgressManager.getInstance().runProcess(() -> {
myApp.executeOnPooledThread(() -> ProgressManager.getInstance().runProcess(() -> {
started.up();
action.run();
}, this));