From 1d618b2df1cf08f0e3ab706353f0a8f6f1424795 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Thu, 17 Feb 2022 20:12:09 -0800 Subject: [PATCH] Don't cache the state from focusTracker. Check activeElement directly when you need to know the current focus state. Fix #141676 --- .../notebook/browser/notebookEditorWidget.ts | 68 +++++-------------- 1 file changed, 18 insertions(+), 50 deletions(-) diff --git a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts index cf6f48912b1..3bec30006e2 100644 --- a/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts +++ b/src/vs/workbench/contrib/notebook/browser/notebookEditorWidget.ts @@ -233,41 +233,6 @@ export function getDefaultNotebookCreationOptions() { }; } -class NotebookEditorWidgetFocusTracker extends Disposable { - - private _hasFocus: boolean; - private readonly _domFocusTracker: DOM.IFocusTracker; - - private readonly _onChange: Emitter = this._register(new Emitter()); - public readonly onChange: Event = this._onChange.event; - - constructor(domElement: HTMLElement) { - super(); - - this._hasFocus = false; - this._domFocusTracker = this._register(DOM.trackFocus(domElement)); - - this._register(this._domFocusTracker.onDidFocus(() => { - this._hasFocus = true; - this._onChange.fire(undefined); - })); - this._register(this._domFocusTracker.onDidBlur(() => { - this._hasFocus = false; - this._onChange.fire(undefined); - })); - } - - public hasFocus(): boolean { - return this._hasFocus; - } - - public refreshState(): void { - if (this._domFocusTracker.refreshState) { - this._domFocusTracker.refreshState(); - } - } -} - export class NotebookEditorWidget extends Disposable implements INotebookEditorDelegate, INotebookEditor { //#region Eventing private readonly _onDidChangeCellState = this._register(new Emitter()); @@ -337,7 +302,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD private _cellContextKeyManager: CellContextKeyManager | null = null; private _isVisible = false; private readonly _uuid = generateUuid(); - private _widgetFocusTracker!: NotebookEditorWidgetFocusTracker; + private _focusTracker!: DOM.IFocusTracker; private _webviewFocused: boolean = false; private _isDisposed: boolean = false; @@ -1049,17 +1014,16 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD } })); - this._widgetFocusTracker = this._register(new NotebookEditorWidgetFocusTracker(this.getDomNode())); - this._register(this._widgetFocusTracker.onChange(() => { - const focused = this._widgetFocusTracker.hasFocus(); - this._editorFocus.set(focused); - this.viewModel?.setEditorFocus(focused); - - if (focused) { - this._onDidFocusEmitter.fire(); - } else { - this._onDidBlurEmitter.fire(); - } + this._focusTracker = this._register(DOM.trackFocus(this.getDomNode())); + this._register(this._focusTracker.onDidBlur(() => { + this._editorFocus.set(false); + this.viewModel?.setEditorFocus(false); + this._onDidBlurEmitter.fire(); + })); + this._register(this._focusTracker.onDidFocus(() => { + this._editorFocus.set(true); + this.viewModel?.setEditorFocus(true); + this._onDidFocusEmitter.fire(); })); this._registerNotebookActionsToolbar(); @@ -1863,11 +1827,15 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD this._notebookTopToolbarContainer.style.display = 'none'; } + private editorHasDomFocus(): boolean { + return DOM.isAncestor(document.activeElement, this.getDomNode()); + } + updateEditorFocus() { // Note - focus going to the webview will fire 'blur', but the webview element will be // a descendent of the notebook editor root. - this._widgetFocusTracker.refreshState(); - const focused = this._widgetFocusTracker.hasFocus(); + this._focusTracker.refreshState(); + const focused = this.editorHasDomFocus(); this._editorFocus.set(focused); this.viewModel?.setEditorFocus(focused); } @@ -1876,7 +1844,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD // _editorFocus is driven by the FocusTracker, which is only guaranteed to _eventually_ fire blur. // If we need to know whether we have focus at this instant, we need to check the DOM manually. this.updateEditorFocus(); - return this._widgetFocusTracker.hasFocus(); + return this.editorHasDomFocus(); } hasWebviewFocus() {