Fix browser focus stealing (#303647)

This commit is contained in:
Kyle Cutler
2026-03-20 17:53:04 -07:00
committed by GitHub
parent 8c3724e8d1
commit 7c45bc769a

View File

@@ -479,10 +479,16 @@ export class BrowserEditor extends EditorPane {
// When the browser container gets focus, make sure the browser view also gets focused.
// But only if focus was already in the workbench (and not e.g. clicking back into the workbench from the browser view).
if (event.relatedTarget && this._model && this.shouldShowView) {
void this._model.focus();
this.requestFocus();
}
}));
this._register(addDisposableListener(this._browserContainer, EventType.BLUR, () => {
// If the container becomes blurred, cancel any scheduled focus call.
// This can happen when e.g. a menu closes and focus shifts back to the browser, then immediately focuses another element.
this.cancelFocus();
}));
// Register external focus checker so that cross-window focus logic knows when
// this browser view has focus (since it's outside the normal DOM tree).
// Include window info so that UI like dialogs appear in the correct window.
@@ -494,12 +500,33 @@ export class BrowserEditor extends EditorPane {
override focus(): void {
if (this._model?.url && !this._model.error) {
void this._model.focus();
this.requestFocus();
} else {
this.focusUrlInput();
}
}
private _focusTimeout: ReturnType<typeof setTimeout> | undefined;
private requestFocus(): void {
this.ensureBrowserFocus();
if (this._focusTimeout) {
return;
}
this._focusTimeout = setTimeout(() => {
this._focusTimeout = undefined;
if (this._model) {
void this._model.focus();
}
}, 0);
}
private cancelFocus(): void {
if (this._focusTimeout) {
clearTimeout(this._focusTimeout);
this._focusTimeout = undefined;
}
}
override async setInput(input: BrowserEditorInput, options: IEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken): Promise<void> {
await super.setInput(input, options, context, token);
if (token.isCancellationRequested) {
@@ -643,7 +670,7 @@ export class BrowserEditor extends EditorPane {
this._browserContainer.ownerDocument.activeElement === this._browserContainer
) {
// If the editor is focused, ensure the browser view also gets focus
void this._model.focus();
this.requestFocus();
}
} else {
this.doScreenshot();
@@ -1031,8 +1058,9 @@ export class BrowserEditor extends EditorPane {
override clearInput(): void {
this._inputDisposables.clear();
// Cancel any scheduled screenshots
// Cancel any scheduled timers
this.cancelScheduledScreenshot();
this.cancelFocus();
void this._model?.setVisible(false);
this._model = undefined;