From 0da7b8681741b33d2d1cf7339d9dbbf54b994a9e Mon Sep 17 00:00:00 2001 From: peter Date: Tue, 2 May 2017 13:31:40 +0200 Subject: [PATCH] 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 --- .../openapi/wm/ex/ProgressIndicatorEx.java | 2 - .../util/AbstractProgressIndicatorExBase.java | 52 ------------------- .../openapi/progress/util/ProgressDialog.java | 5 ++ .../openapi/progress/util/ProgressWindow.java | 16 ++++++ .../progress/impl/ProgressIndicatorTest.java | 5 -- 5 files changed, 21 insertions(+), 59 deletions(-) diff --git a/platform/core-impl/src/com/intellij/openapi/wm/ex/ProgressIndicatorEx.java b/platform/core-impl/src/com/intellij/openapi/wm/ex/ProgressIndicatorEx.java index 5c85e6230f98..4128ea353b12 100644 --- a/platform/core-impl/src/com/intellij/openapi/wm/ex/ProgressIndicatorEx.java +++ b/platform/core-impl/src/com/intellij/openapi/wm/ex/ProgressIndicatorEx.java @@ -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); diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java index 24c8f58efbf5..4de0bfd0abec 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/AbstractProgressIndicatorExBase.java @@ -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 myStateDelegates; private volatile WeakList 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; diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressDialog.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressDialog.java index b38a2d276e05..65c9620a39bb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressDialog.java @@ -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(); } diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java index 8404c0b9e994..ce6de9bc5acb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/ProgressWindow.java @@ -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 = ""; @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()); diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/progress/impl/ProgressIndicatorTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/progress/impl/ProgressIndicatorTest.java index 39bbce3c812f..3379f2dde24a 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/progress/impl/ProgressIndicatorTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/progress/impl/ProgressIndicatorTest.java @@ -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) { }