do not violate modality policy — invoke later from pooled task to ensure that correct modality will be used

No need to use any modality hack.

GitOrigin-RevId: b336a9cc8661f7e43f289a5db9d687a91232cff0
This commit is contained in:
Vladimir Krivosheev
2019-07-26 16:03:45 +03:00
committed by intellij-monorepo-bot
parent 1886ff716b
commit 690afe56f2
5 changed files with 72 additions and 63 deletions
@@ -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 <T> runActivity(name: String, task: () -> T): T {
val activity = StartUpMeasurer.start(name)
val result = task()
activity.end()
return result
}
@@ -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.
@@ -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");
@@ -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())
}
@@ -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;
}
}