Skip to content

Commit f71af63

Browse files
authored
Merge pull request microsoft#189199 from microsoft/merogge/cherry-hover
correctly handle focus on escape of accessible view / hover
2 parents fcccf48 + 98d227f commit f71af63

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

src/vs/workbench/services/hover/browser/hover.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ export interface IHoverOptions {
145145
* Whether to trap focus in the following ways:
146146
* - When the hover closes, focus goes to the element that had focus before the hover opened
147147
* - If there are elements in the hover to focus, focus stays inside of the hover when tabbing
148+
* Note that this is overridden to true when in screen reader optimized mode.
148149
*/
149150
trapFocus?: boolean;
150151

src/vs/workbench/services/hover/browser/hoverService.ts

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { addDisposableListener, EventType } from 'vs/base/browser/dom';
1717
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
1818
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
1919
import { ResultKind } from 'vs/platform/keybinding/common/keybindingResolver';
20+
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
2021

2122
export class HoverService implements IHoverService {
2223
declare readonly _serviceBrand: undefined;
@@ -31,23 +32,27 @@ export class HoverService implements IHoverService {
3132
@IInstantiationService private readonly _instantiationService: IInstantiationService,
3233
@IContextViewService private readonly _contextViewService: IContextViewService,
3334
@IContextMenuService contextMenuService: IContextMenuService,
34-
@IKeybindingService private readonly _keybindingService: IKeybindingService
35+
@IKeybindingService private readonly _keybindingService: IKeybindingService,
36+
@IAccessibilityService private readonly _accessibilityService: IAccessibilityService
3537
) {
3638
contextMenuService.onDidShowContextMenu(() => this.hideHover());
3739
}
3840

39-
showHover(options: IHoverOptions, focus?: boolean): IHoverWidget | undefined {
41+
showHover(options: IHoverOptions, focus?: boolean, skipLastFocusedUpdate?: boolean): IHoverWidget | undefined {
4042
if (getHoverOptionsIdentity(this._currentHoverOptions) === getHoverOptionsIdentity(options)) {
4143
return undefined;
4244
}
4345
this._currentHoverOptions = options;
4446
this._lastHoverOptions = options;
45-
if (options.trapFocus && document.activeElement) {
46-
this._lastFocusedElementBeforeOpen = document.activeElement as HTMLElement;
47-
} else {
48-
this._lastFocusedElementBeforeOpen = undefined;
47+
const trapFocus = options.trapFocus || this._accessibilityService.isScreenReaderOptimized();
48+
// HACK, remove this check when #189076 is fixed
49+
if (!skipLastFocusedUpdate) {
50+
if (trapFocus && document.activeElement) {
51+
this._lastFocusedElementBeforeOpen = document.activeElement as HTMLElement;
52+
} else {
53+
this._lastFocusedElementBeforeOpen = undefined;
54+
}
4955
}
50-
5156
const hoverDisposables = new DisposableStore();
5257
const hover = this._instantiationService.createInstance(HoverWidget, options);
5358
hover.onDispose(() => {
@@ -114,7 +119,7 @@ export class HoverService implements IHoverService {
114119
if (!this._lastHoverOptions) {
115120
return;
116121
}
117-
this.showHover(this._lastHoverOptions, true);
122+
this.showHover(this._lastHoverOptions, true, true);
118123
}
119124

120125
private _keyDown(e: KeyboardEvent, hover: HoverWidget, hideOnKeyDown: boolean) {

0 commit comments

Comments
 (0)