Don't cache the state from focusTracker. Check activeElement directly when you need to know the current focus state.

Fix #141676
This commit is contained in:
Rob Lourens 2022-02-17 20:12:09 -08:00
parent 7181933eab
commit 1d618b2df1

View file

@ -233,41 +233,6 @@ export function getDefaultNotebookCreationOptions() {
};
}
class NotebookEditorWidgetFocusTracker extends Disposable {
private _hasFocus: boolean;
private readonly _domFocusTracker: DOM.IFocusTracker;
private readonly _onChange: Emitter<void> = this._register(new Emitter<void>());
public readonly onChange: Event<void> = 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<NotebookCellStateChangedEvent>());
@ -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() {