mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
change modality deterministically in progress indicators
namely, on EDT, before ProgressWindow is started and whenever its dialog is closed previously, the modality was entered at some later moment (invokeLater from start() method), and some runnables could sneak before that
This commit is contained in:
@@ -22,8 +22,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
public interface ProgressIndicatorEx extends ProgressIndicatorStacked {
|
||||
void addStateDelegate(@NotNull ProgressIndicatorEx delegate);
|
||||
|
||||
boolean isModalityEntered();
|
||||
|
||||
void finish(@NotNull TaskInfo task);
|
||||
|
||||
boolean isFinished(@NotNull TaskInfo task);
|
||||
|
||||
-52
@@ -15,13 +15,10 @@
|
||||
*/
|
||||
package com.intellij.openapi.progress.util;
|
||||
|
||||
import com.intellij.openapi.application.*;
|
||||
import com.intellij.openapi.application.impl.LaterInvocator;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.TaskInfo;
|
||||
import com.intellij.openapi.wm.ex.ProgressIndicatorEx;
|
||||
import com.intellij.ui.GuiUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.WeakList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -31,7 +28,6 @@ import java.util.List;
|
||||
public class AbstractProgressIndicatorExBase extends AbstractProgressIndicatorBase implements ProgressIndicatorEx {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.progress.util.ProgressIndicatorBase");
|
||||
private final boolean myReusable;
|
||||
private volatile boolean myModalityEntered;
|
||||
private volatile List<ProgressIndicatorEx> myStateDelegates;
|
||||
private volatile WeakList<TaskInfo> myFinished;
|
||||
private volatile boolean myWasStarted;
|
||||
@@ -52,48 +48,13 @@ public class AbstractProgressIndicatorExBase extends AbstractProgressIndicatorBa
|
||||
delegateRunningChange(ProgressIndicator::start);
|
||||
}
|
||||
myWasStarted = true;
|
||||
|
||||
enterModality();
|
||||
}
|
||||
|
||||
protected final void enterModality() {
|
||||
if (myModalityProgress == this) {
|
||||
ModalityState modalityState = ModalityState.defaultModalityState();
|
||||
if (!myModalityEntered &&
|
||||
!ApplicationManager.getApplication().isDispatchThread() &&
|
||||
!((TransactionGuardImpl)TransactionGuard.getInstance()).isWriteSafeModality(modalityState)) {
|
||||
// exceptions here should be assigned to Peter
|
||||
LOG.error("Non-modal progress should be started in a write-safe context: an action or modality-aware invokeLater. See also TransactionGuard documentation.");
|
||||
}
|
||||
GuiUtils.invokeLaterIfNeeded(this::doEnterModality, modalityState);
|
||||
}
|
||||
}
|
||||
|
||||
private void doEnterModality() {
|
||||
if (!myModalityEntered) {
|
||||
LaterInvocator.enterModal(this);
|
||||
myModalityEntered = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop();
|
||||
delegateRunningChange(ProgressIndicator::stop);
|
||||
exitModality();
|
||||
}
|
||||
|
||||
protected final void exitModality() {
|
||||
if (myModalityProgress == this) {
|
||||
GuiUtils.invokeLaterIfNeeded(this::doExitModality, ModalityState.defaultModalityState());
|
||||
}
|
||||
}
|
||||
|
||||
private void doExitModality() {
|
||||
if (myModalityEntered) {
|
||||
myModalityEntered = false;
|
||||
LaterInvocator.leaveModal(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -246,19 +207,6 @@ public class AbstractProgressIndicatorExBase extends AbstractProgressIndicatorBa
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalityEntered() {
|
||||
return myModalityEntered;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void initStateFrom(@NotNull final ProgressIndicator indicator) {
|
||||
super.initStateFrom(indicator);
|
||||
if (indicator instanceof ProgressIndicatorEx) {
|
||||
myModalityEntered = ((ProgressIndicatorEx)indicator).isModalityEntered();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasStarted() {
|
||||
return myWasStarted;
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.intellij.openapi.progress.util;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.impl.LaterInvocator;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.DialogWrapperDialog;
|
||||
@@ -25,6 +27,7 @@ import com.intellij.openapi.ui.DialogWrapperPeer;
|
||||
import com.intellij.openapi.ui.impl.DialogWrapperPeerImpl;
|
||||
import com.intellij.openapi.ui.impl.FocusTrackbackProvider;
|
||||
import com.intellij.openapi.ui.impl.GlassPaneDialogWrapperPeer;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.openapi.wm.ex.WindowManagerEx;
|
||||
@@ -322,6 +325,8 @@ class ProgressDialog implements Disposable {
|
||||
}
|
||||
});
|
||||
|
||||
Disposer.register(myPopup.getDisposable(), () -> myProgressWindow.exitModality());
|
||||
|
||||
myPopup.show();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.intellij.openapi.progress.util;
|
||||
import com.intellij.ide.IdeEventQueue;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.impl.LaterInvocator;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
@@ -62,6 +63,7 @@ public class ProgressWindow extends ProgressIndicatorBase implements BlockingPro
|
||||
private String myProcessId = "<unknown>";
|
||||
@Nullable private volatile Runnable myBackgroundHandler;
|
||||
protected int myDelayInMillis = DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS;
|
||||
private boolean myModalityEntered;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Listener {
|
||||
@@ -181,6 +183,20 @@ public class ProgressWindow extends ProgressIndicatorBase implements BlockingPro
|
||||
timer.start();
|
||||
}
|
||||
|
||||
final void enterModality() {
|
||||
if (myModalityProgress == this && !myModalityEntered) {
|
||||
LaterInvocator.enterModal(this);
|
||||
myModalityEntered = true;
|
||||
}
|
||||
}
|
||||
|
||||
final void exitModality() {
|
||||
if (myModalityProgress == this && myModalityEntered) {
|
||||
myModalityEntered = false;
|
||||
LaterInvocator.leaveModal(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startBlocking() {
|
||||
startBlocking(EmptyRunnable.getInstance());
|
||||
|
||||
-5
@@ -422,11 +422,6 @@ public class ProgressIndicatorTest extends LightPlatformTestCase {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isModalityEntered() {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void finish(@NotNull TaskInfo task) {
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user