From 1c5b5f9f7bdf8ab7c13fc31b7201e7252ed16b54 Mon Sep 17 00:00:00 2001 From: Bart van Helvert Date: Sat, 11 Oct 2025 20:13:07 +0200 Subject: [PATCH] [tests] Don't steal focus when automatically rerunning tests Prevents the build toolwindow from stealing the focus when an automatic build is triggered by the automatic test runner when the code is uncompilable. #IDEA-335769 Fixed GitOrigin-RevId: d6bd1f9fade4fab3c91b25bbe788f870aaf123bc --- .../compiler/progress/BuildOutputService.java | 17 ++++++++++++++++- .../compiler/progress/CompilerTask.java | 4 ++-- .../compiler/options/CompileStepBeforeRun.java | 8 ++++++-- platform/execution/api-dump.txt | 3 +++ .../execution/runners/ExecutionEnvironment.java | 16 ++++++++++++++-- .../intellij/build/DefaultBuildDescriptor.java | 4 +++- .../autotest/AbstractAutoTestManager.java | 6 +++++- 7 files changed, 49 insertions(+), 9 deletions(-) diff --git a/java/compiler/impl/src/com/intellij/compiler/progress/BuildOutputService.java b/java/compiler/impl/src/com/intellij/compiler/progress/BuildOutputService.java index 618c1f2427a1..0bb9a81adae2 100644 --- a/java/compiler/impl/src/com/intellij/compiler/progress/BuildOutputService.java +++ b/java/compiler/impl/src/com/intellij/compiler/progress/BuildOutputService.java @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.compiler.progress; import com.intellij.build.*; @@ -52,11 +52,21 @@ public class BuildOutputService implements BuildViewService { private final @NotNull Project myProject; private final @NotNull BuildProgress myBuildProgress; private final @NotNull @NlsContexts.TabTitle String myContentName; + private final boolean myCompilationStartedAutomatically; private final ConsolePrinter myConsolePrinter; public BuildOutputService(@NotNull Project project, @NotNull @NlsContexts.TabTitle String contentName) { + this(project, contentName, false); + } + + public BuildOutputService( + @NotNull Project project, + @NotNull @NlsContexts.TabTitle String contentName, + boolean compilationStartedAutomatically + ) { myProject = project; myContentName = contentName; + myCompilationStartedAutomatically = compilationStartedAutomatically; myBuildProgress = BuildViewManager.createBuildProgress(project); myConsolePrinter = new ConsolePrinter(myBuildProgress); } @@ -101,6 +111,11 @@ public class BuildOutputService implements BuildViewService { }) .withContextActions(contextActions.toArray(AnAction.EMPTY_ARRAY)); + if (myCompilationStartedAutomatically) { + // When compilation is triggered automatically (e.g., by auto test run), avoid stealing focus + buildDescriptor.setActivateToolWindowWhenFailed(false); + } + myBuildProgress.start(new BuildProgressDescriptor() { @Override public @NotNull String getTitle() { diff --git a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java index d8b7b49ca6b8..650625c602d4 100644 --- a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java +++ b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.compiler.progress; import com.intellij.compiler.CompilerManagerImpl; @@ -67,7 +67,7 @@ public final class CompilerTask extends Task.Backgroundable { mySessionId = myContentId; // by default sessionID should be unique, just as content ID if (SystemProperties.getBooleanProperty("ide.jps.use.build.tool.window", true)) { - myBuildViewService = new BuildOutputService(project, contentName); + myBuildViewService = new BuildOutputService(project, contentName, myCompilationStartedAutomatically); } else { myBuildViewService = new CompilerMessagesService(project, myContentId, contentName, headlessMode); } diff --git a/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java b/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java index ccd0a1fe0bbb..8ab57b9eef23 100644 --- a/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java +++ b/java/execution/impl/src/com/intellij/compiler/options/CompileStepBeforeRun.java @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.compiler.options; import com.intellij.execution.*; @@ -181,7 +181,11 @@ public final class CompileStepBeforeRun extends BeforeRunTaskProvider(context, projectTask); }).expireWith(myProject).executeSynchronously(); diff --git a/platform/execution/api-dump.txt b/platform/execution/api-dump.txt index 4674abc4ca47..041e63a54840 100644 --- a/platform/execution/api-dump.txt +++ b/platform/execution/api-dump.txt @@ -180,6 +180,9 @@ com.intellij.execution.filters.Filter - a:applyFilter(java.lang.String,I):com.intellij.execution.filters.Filter$Result a:com.intellij.execution.rmi.RemoteProcessSupport - p:publishPort(I,java.lang.Object):I +f:com.intellij.execution.runners.ExecutionEnvironment +- isAutoTriggered():Z +- setAutoTriggered(Z):V com.intellij.execution.runners.ProcessProxy - a:attach(com.intellij.execution.process.ProcessHandler):V - canSendBreak():Z diff --git a/platform/execution/src/com/intellij/execution/runners/ExecutionEnvironment.java b/platform/execution/src/com/intellij/execution/runners/ExecutionEnvironment.java index d898c37bba92..ce7159b8477a 100644 --- a/platform/execution/src/com/intellij/execution/runners/ExecutionEnvironment.java +++ b/platform/execution/src/com/intellij/execution/runners/ExecutionEnvironment.java @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.execution.runners; import com.intellij.execution.*; @@ -13,6 +13,7 @@ import com.intellij.openapi.actionSystem.PlatformCoreDataKeys; import com.intellij.openapi.module.Module; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.UserDataHolderBase; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -27,6 +28,8 @@ import java.util.concurrent.atomic.AtomicLong; * @see Execution (IntelliJ Platform Docs) */ public final class ExecutionEnvironment extends UserDataHolderBase implements Disposable { + private static final Key AUTO_TRIGGERED = Key.create("AUTO_TRIGGERED"); + private static final AtomicLong myIdHolder = new AtomicLong(1L); private final @NotNull Project myProject; @@ -102,7 +105,6 @@ public final class ExecutionEnvironment extends UserDataHolderBase implements Di myRunnerAndConfigurationSettings = settings; myRunner = runner; - this.callback = callback; } @@ -298,4 +300,14 @@ public final class ExecutionEnvironment extends UserDataHolderBase implements Di public void setRunningCurrentFile(boolean runningCurrentFile) { myRunningCurrentFile = runningCurrentFile; } + + /// Indicates that the run was triggered automatically (e.g., by Auto Test). + public boolean isAutoTriggered() { + return Boolean.TRUE.equals(getCopyableUserData(AUTO_TRIGGERED)); + } + + /// Set whether the run was triggered automatically (e.g., by Auto Test). + public void setAutoTriggered(boolean autoTriggered) { + putCopyableUserData(AUTO_TRIGGERED, autoTriggered); + } } diff --git a/platform/lang-impl/src/com/intellij/build/DefaultBuildDescriptor.java b/platform/lang-impl/src/com/intellij/build/DefaultBuildDescriptor.java index 521357c6cec9..924936c03ab1 100644 --- a/platform/lang-impl/src/com/intellij/build/DefaultBuildDescriptor.java +++ b/platform/lang-impl/src/com/intellij/build/DefaultBuildDescriptor.java @@ -1,4 +1,4 @@ -// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.build; import com.intellij.build.events.BuildEventsNls; @@ -142,10 +142,12 @@ public class DefaultBuildDescriptor implements BuildDescriptor { myActivateToolWindowWhenAdded = activateToolWindowWhenAdded; } + /// Return whether the build toolwindow should be activated when the build failed. public boolean isActivateToolWindowWhenFailed() { return myActivateToolWindowWhenFailed; } + /// Set whether the build toolwindow should be activated when the build failed. public void setActivateToolWindowWhenFailed(boolean activateToolWindowWhenFailed) { myActivateToolWindowWhenFailed = activateToolWindowWhenFailed; } diff --git a/platform/testRunner/src/com/intellij/execution/testframework/autotest/AbstractAutoTestManager.java b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AbstractAutoTestManager.java index 046aac74666e..a130587ee75b 100644 --- a/platform/testRunner/src/com/intellij/execution/testframework/autotest/AbstractAutoTestManager.java +++ b/platform/testRunner/src/com/intellij/execution/testframework/autotest/AbstractAutoTestManager.java @@ -68,7 +68,11 @@ public abstract class AbstractAutoTestManager implements PersistentStateComponen private static void restart(@NotNull RunContentDescriptor descriptor) { descriptor.setActivateToolWindowWhenAdded(false); descriptor.setReuseToolWindowActivation(true); - ExecutionUtil.restart(descriptor); + ExecutionEnvironment env = getCurrentEnvironment(descriptor); + if (env != null) { + env.setAutoTriggered(true); + ExecutionUtil.restart(env); + } } private static void saveConfigurationState(@NotNull State state, @NotNull RunProfile profile) {