[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
This commit is contained in:
Bart van Helvert
2025-10-27 16:22:47 +00:00
committed by intellij-monorepo-bot
parent 5e2fb82872
commit 1c5b5f9f7b
7 changed files with 49 additions and 9 deletions
@@ -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<BuildProgressDescriptor> 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() {
@@ -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);
}
@@ -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<CompileSte
projectTask = new EmptyCompileScopeBuildTaskImpl(true);
}
}
ProjectTaskContext context = new ProjectTaskContext(ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.get(env), configuration);
ProjectTaskContext context = new ProjectTaskContext(
ExecutionManagerImpl.EXECUTION_SESSION_ID_KEY.get(env),
configuration,
env.isAutoTriggered()
);
env.copyUserDataTo(context);
return new Pair<>(context, projectTask);
}).expireWith(myProject).executeSynchronously();
+3
View File
@@ -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
@@ -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 <a href="https://plugins.jetbrains.com/docs/intellij/execution.html">Execution (IntelliJ Platform Docs)</a>
*/
public final class ExecutionEnvironment extends UserDataHolderBase implements Disposable {
private static final Key<Boolean> 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);
}
}
@@ -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;
}
@@ -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) {