Fix chatbox losing focus during automated workflows (#4574)

- Add preserveFocus option to openFile() function to prevent focus theft
- Implement automated workflow detection based on task streaming state and auto-approval settings
- Preserve chat focus when AI is actively processing to prevent accidental text insertion
- Update file mention handling to respect automated workflow state
- Add comments to clarify user-initiated vs automated file opening

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
hannesrudolph 2025-06-11 19:56:33 -06:00
parent 395f55b31f
commit 91158c07be
3 changed files with 38 additions and 2 deletions

View file

@ -10,6 +10,7 @@ import { getCommitInfo, getWorkingState } from "../../utils/git"
import { getWorkspacePath } from "../../utils/path"
import { openFile } from "../../integrations/misc/open-file"
import { ClineProvider } from "../webview/ClineProvider"
import { extractTextFromFile } from "../../integrations/misc/extract-text"
import { diagnosticsToProblemsString } from "../../integrations/diagnostics"
@ -36,7 +37,21 @@ export async function openMention(mention?: string): Promise<void> {
if (mention.endsWith("/")) {
vscode.commands.executeCommand("revealInExplorer", vscode.Uri.file(absPath))
} else {
openFile(absPath)
// Check if we're in an automated workflow when opening file mentions
const visibleProvider = ClineProvider.getVisibleInstance()
const currentCline = visibleProvider?.getCurrentCline()
const autoApprovalEnabled = visibleProvider?.contextProxy.getValue("autoApprovalEnabled")
// Detect automated workflow: AI is actively processing, streaming, or auto-approval is enabled
// and there's an active task that hasn't completed reading/processing
const isInAutomatedWorkflow =
currentCline &&
(currentCline.isStreaming ||
currentCline.isWaitingForFirstChunk ||
(autoApprovalEnabled && !currentCline.didCompleteReadingStream) ||
(autoApprovalEnabled && currentCline.presentAssistantMessageLocked))
openFile(absPath, { preserveFocus: !!isInAutomatedWorkflow })
}
} else if (mention === "problems") {
vscode.commands.executeCommand("workbench.actions.view.problems")

View file

@ -426,7 +426,23 @@ export const webviewMessageHandler = async (
openImage(message.text!)
break
case "openFile":
openFile(message.text!, message.values as { create?: boolean; content?: string; line?: number })
// Check if we're in an automated workflow (AI is streaming/processing)
const currentCline = provider.getCurrentCline()
const autoApprovalEnabled = getGlobalState("autoApprovalEnabled")
// Detect automated workflow: AI is actively processing, streaming, or auto-approval is enabled
// and there's an active task that hasn't completed reading/processing
const isInAutomatedWorkflow =
currentCline &&
(currentCline.isStreaming ||
currentCline.isWaitingForFirstChunk ||
(autoApprovalEnabled && !currentCline.didCompleteReadingStream) ||
(autoApprovalEnabled && currentCline.presentAssistantMessageLocked))
openFile(message.text!, {
...(message.values as { create?: boolean; content?: string; line?: number }),
preserveFocus: !!isInAutomatedWorkflow,
})
break
case "openMention":
openMention(message.text)
@ -481,6 +497,7 @@ export const webviewMessageHandler = async (
const customModesFilePath = await provider.customModesManager.getCustomModesFilePath()
if (customModesFilePath) {
// User-initiated settings opening, keep focus
openFile(customModesFilePath)
}
@ -490,6 +507,7 @@ export const webviewMessageHandler = async (
const mcpSettingsFilePath = await provider.getMcpHub()?.getMcpSettingsFilePath()
if (mcpSettingsFilePath) {
// User-initiated settings opening, keep focus
openFile(mcpSettingsFilePath)
}
@ -513,6 +531,7 @@ export const webviewMessageHandler = async (
await fs.writeFile(mcpPath, JSON.stringify({ mcpServers: {} }, null, 2))
}
// User-initiated settings opening, keep focus
await openFile(mcpPath)
} catch (error) {
vscode.window.showErrorMessage(t("mcp:errors.create_json", { error: `${error}` }))

View file

@ -24,6 +24,7 @@ interface OpenFileOptions {
create?: boolean
content?: string
line?: number
preserveFocus?: boolean
}
export async function openFile(filePath: string, options: OpenFileOptions = {}) {
@ -148,6 +149,7 @@ export async function openFile(filePath: string, options: OpenFileOptions = {})
await vscode.window.showTextDocument(document, {
preview: false,
selection,
preserveFocus: options.preserveFocus,
})
} catch (error) {
if (error instanceof Error) {