From 690afe56f2b9adaaf2a11c81036dcdf7e9f4216e Mon Sep 17 00:00:00 2001 From: Vladimir Krivosheev Date: Fri, 26 Jul 2019 14:54:35 +0200 Subject: [PATCH] =?UTF-8?q?do=20not=20violate=20modality=20policy=20?= =?UTF-8?q?=E2=80=94=20invoke=20later=20from=20pooled=20task=20to=20ensure?= =?UTF-8?q?=20that=20correct=20modality=20will=20be=20used?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No need to use any modality hack. GitOrigin-RevId: b336a9cc8661f7e43f289a5db9d687a91232cff0 --- .../intellij/diagnostic/startUpMeasurer.kt | 21 ++++++ .../src/com/intellij/idea/IdeaApplication.kt | 17 +---- .../openapi/wm/impl/WindowManagerImpl.java | 23 +++--- .../platform/ProjectFrameAllocator.kt | 71 +++++++++++-------- .../ui/mac/MacMainFrameDecorator.java | 3 +- 5 files changed, 72 insertions(+), 63 deletions(-) create mode 100644 platform/platform-impl/src/com/intellij/diagnostic/startUpMeasurer.kt diff --git a/platform/platform-impl/src/com/intellij/diagnostic/startUpMeasurer.kt b/platform/platform-impl/src/com/intellij/diagnostic/startUpMeasurer.kt new file mode 100644 index 000000000000..1640c73f7ea7 --- /dev/null +++ b/platform/platform-impl/src/com/intellij/diagnostic/startUpMeasurer.kt @@ -0,0 +1,21 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.diagnostic + +inline fun Activity.runChild(name: String, task: () -> Unit) { + val activity = startChild(name) + task() + activity.end() +} + +inline fun ParallelActivity.run(name: String, task: () -> Unit) { + val activity = start(name) + task() + activity.end() +} + +inline fun runActivity(name: String, task: () -> T): T { + val activity = StartUpMeasurer.start(name) + val result = task() + activity.end() + return result +} \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.kt b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.kt index f2759076cc66..2c54ce1ba6a8 100644 --- a/platform/platform-impl/src/com/intellij/idea/IdeaApplication.kt +++ b/platform/platform-impl/src/com/intellij/idea/IdeaApplication.kt @@ -1,10 +1,7 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.idea -import com.intellij.diagnostic.Activity -import com.intellij.diagnostic.LoadingPhase -import com.intellij.diagnostic.ParallelActivity -import com.intellij.diagnostic.StartUpMeasurer +import com.intellij.diagnostic.* import com.intellij.diagnostic.StartUpMeasurer.Phases import com.intellij.featureStatistics.fusCollectors.LifecycleUsageTriggerCollector import com.intellij.icons.AllIcons @@ -429,18 +426,6 @@ open class IdeStarter : ApplicationStarter { } } -inline fun Activity.runChild(name: String, task: () -> Unit) { - val activity = startChild(name) - task() - activity.end() -} - -inline fun ParallelActivity.run(name: String, task: () -> Unit) { - val activity = start(name) - task() - activity.end() -} - /** * Method looks for `-Dkey=value` program arguments and stores some of them in system properties. * We should use it for a limited number of safe keys. diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowManagerImpl.java index bc990b02c549..ec95435328dc 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/WindowManagerImpl.java @@ -479,13 +479,14 @@ public final class WindowManagerImpl extends WindowManagerEx implements Persiste */ @NotNull @ApiStatus.Internal - public IdeFrameImpl showFrame(@NotNull OpenProjectTask options) { + public IdeFrameImpl createFrame(@NotNull OpenProjectTask options) { LOG.assertTrue(!myProjectToFrame.containsKey(null)); IdeFrameImpl frame = new IdeFrameImpl(); if (options.getSendFrameBack()) { frame.setAutoRequestFocus(false); } + if (options.getProjectWorkspaceId() != null && Registry.is("ide.project.loading.show.last.state")) { try { frame.setProjectWorkspaceId(options.getProjectWorkspaceId()); @@ -496,20 +497,6 @@ public final class WindowManagerImpl extends WindowManagerEx implements Persiste } } } - - FrameInfo frameInfo = options.getFrame(); - if (frameInfo == null || frameInfo.getBounds() == null) { - frameInfo = defaultFrameInfoHelper.getInfo(); - } - if (frameInfo != null) { - // set bounds even if maximized because on unmaximize we must restore previous frame bounds - setFrameBoundsFromDeviceSpace(frame, frameInfo); - } - - if (frameInfo != null) { - setFrameExtendedState(frame, frameInfo); - } - frame.setVisible(true); return frame; } @@ -710,6 +697,12 @@ public final class WindowManagerImpl extends WindowManagerEx implements Persiste return defaultFrameInfoHelper.getModificationCount() + myLayout.getStateModificationCount(); } + @Nullable + @ApiStatus.Internal + public FrameInfo getDefaultFrameInfo() { + return defaultFrameInfoHelper.getInfo(); + } + @Override public Element getState() { Element state = new Element("state"); diff --git a/platform/platform-impl/src/com/intellij/platform/ProjectFrameAllocator.kt b/platform/platform-impl/src/com/intellij/platform/ProjectFrameAllocator.kt index b5f6cab3dc31..e465153dfd66 100644 --- a/platform/platform-impl/src/com/intellij/platform/ProjectFrameAllocator.kt +++ b/platform/platform-impl/src/com/intellij/platform/ProjectFrameAllocator.kt @@ -1,12 +1,11 @@ // Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.platform -import com.intellij.diagnostic.StartUpMeasurer +import com.intellij.diagnostic.runActivity import com.intellij.ide.RecentProjectsManager import com.intellij.ide.RecentProjectsManagerBase import com.intellij.ide.impl.OpenProjectTask import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.application.ModalityState import com.intellij.openapi.application.TransactionGuard import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.project.Project @@ -14,8 +13,8 @@ import com.intellij.openapi.wm.WindowManager import com.intellij.openapi.wm.impl.IdeFrameImpl import com.intellij.openapi.wm.impl.ProjectFrameBounds import com.intellij.openapi.wm.impl.WindowManagerImpl +import org.jetbrains.annotations.CalledInAwt import java.nio.file.Path -import javax.swing.JComponent internal open class ProjectFrameAllocator { open fun run(task: Runnable, file: Path): Boolean { @@ -40,18 +39,43 @@ internal class ProjectUiFrameAllocator(private var options: OpenProjectTask) : P override fun run(task: Runnable, file: Path): Boolean { var completed = false TransactionGuard.getInstance().submitTransactionAndWait { - val component = showFrame(file) + val frame = createFrame(file) completed = ProgressManager.getInstance() - .runProcessWithProgressSynchronously(task, "Loading Project...", true, null, component) + .runProcessWithProgressSynchronously( + { + ApplicationManager.getApplication().invokeLater { + runActivity("init frame") { + initFrame(frame) + } + } + task.run() + }, "Loading Project...", true, null, frame.component) } return completed } - private fun showFrame(file: Path): JComponent { + @CalledInAwt + private fun initFrame(frame: IdeFrameImpl) { + val windowManager = WindowManager.getInstance() as WindowManagerImpl + var frameInfo = options.frame + if (frameInfo?.bounds == null) { + frameInfo = windowManager.defaultFrameInfo + } + if (frameInfo != null) { + // set bounds even if maximized because on unmaximize we must restore previous frame bounds + WindowManagerImpl.setFrameBoundsFromDeviceSpace(frame, frameInfo) + windowManager.setFrameExtendedState(frame, frameInfo) + } + frame.isVisible = true + + frame.init() + } + + private fun createFrame(file: Path): IdeFrameImpl { val windowManager = WindowManager.getInstance() as WindowManagerImpl val freeRootFrame = windowManager.rootFrame if (freeRootFrame != null) { - return freeRootFrame.component + return freeRootFrame } if (options.frame?.bounds == null) { @@ -64,24 +88,20 @@ internal class ProjectUiFrameAllocator(private var options: OpenProjectTask) : P } } - val showFrameActivity = StartUpMeasurer.start("show frame") - val frame = windowManager.showFrame(options) - ideFrame = frame - showFrameActivity.end() - // runProcessWithProgressSynchronously still processes EDT events - invokeLaterWithAnyModality { - val activity = StartUpMeasurer.start("init frame") - if (frame.isDisplayable) { - frame.init() - } - activity.end() + val frame = runActivity("create frame") { + windowManager.createFrame(options) } - return frame.component + ideFrame = frame + return frame } override fun projectLoaded(project: Project) { - invokeLaterWithAnyModality(project) { - val frame = ideFrame ?: return@invokeLaterWithAnyModality + ApplicationManager.getApplication().invokeLater { + if (project.isDisposed) { + return@invokeLater + } + + val frame = ideFrame ?: return@invokeLater val windowManager = WindowManager.getInstance() as WindowManagerImpl if (options.frame?.bounds == null) { @@ -101,13 +121,4 @@ internal class ProjectUiFrameAllocator(private var options: OpenProjectTask) : P ideFrame?.isAutoRequestFocus = true } } -} - -private inline fun invokeLaterWithAnyModality(project: Project? = null, crossinline runnable: () -> Unit) { - ApplicationManager.getApplication().invokeLater( - { - if (project == null || !project.isDisposed) { - runnable() - } - }, ModalityState.any()) } \ No newline at end of file diff --git a/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java b/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java index e1806c2d0d98..2e34752fd5bf 100644 --- a/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java +++ b/platform/platform-impl/src/com/intellij/ui/mac/MacMainFrameDecorator.java @@ -5,7 +5,6 @@ import com.apple.eawt.*; import com.intellij.ide.ui.UISettings; import com.intellij.ide.ui.UISettingsListener; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.TransactionGuard; import com.intellij.openapi.application.impl.ApplicationInfoImpl; import com.intellij.openapi.diagnostic.Logger; @@ -58,7 +57,7 @@ public final class MacMainFrameDecorator extends IdeFrameDecorator implements UI enqueue(runnable); } else { - ApplicationManager.getApplication().invokeLater(runnable, ModalityState.any()); + ApplicationManager.getApplication().invokeLater(runnable); waitingForAppKit = true; } }