diff --git a/src/vs/workbench/services/hover/browser/hover.ts b/src/vs/workbench/services/hover/browser/hover.ts index eadb80f2df715..d5b60af62625a 100644 --- a/src/vs/workbench/services/hover/browser/hover.ts +++ b/src/vs/workbench/services/hover/browser/hover.ts @@ -126,6 +126,11 @@ export interface IHoverOptions { * - If there are elements in the hover to focus, focus stays inside of the hover when tabbing */ trapFocus?: boolean; + + /** + * The container to render the hover in. + */ + container?: HTMLElement; } export interface IHoverAction { diff --git a/src/vs/workbench/services/hover/browser/hoverService.ts b/src/vs/workbench/services/hover/browser/hoverService.ts index f945c707f126e..c6fbd3a8d87c8 100644 --- a/src/vs/workbench/services/hover/browser/hoverService.ts +++ b/src/vs/workbench/services/hover/browser/hoverService.ts @@ -59,7 +59,10 @@ export class HoverService implements IHoverService { hoverDisposables.dispose(); }); const provider = this._contextViewService as IContextViewProvider; - provider.showContextView(new HoverContextViewDelegate(hover, focus)); + provider.showContextView( + new HoverContextViewDelegate(hover, focus), + options.container + ); hover.onRequestLayout(() => provider.layout()); if ('targetElements' in options.target) { for (const element of options.target.targetElements) { @@ -70,16 +73,10 @@ export class HoverService implements IHoverService { } const focusedElement = document.activeElement; if (focusedElement) { - hoverDisposables.add(addDisposableListener(focusedElement, EventType.KEY_DOWN, e => this._keyDown(e, hover))); - hoverDisposables.add(addDisposableListener(document, EventType.KEY_DOWN, e => this._keyDown(e, hover))); + hoverDisposables.add(addDisposableListener(focusedElement, EventType.KEY_DOWN, e => this._keyDown(e, hover, !!options.hideOnKeyDown))); + hoverDisposables.add(addDisposableListener(document, EventType.KEY_DOWN, e => this._keyDown(e, hover, !!options.hideOnKeyDown))); hoverDisposables.add(addDisposableListener(focusedElement, EventType.KEY_UP, e => this._keyUp(e, hover))); hoverDisposables.add(addDisposableListener(document, EventType.KEY_UP, e => this._keyUp(e, hover))); - if (options.hideOnKeyDown) { - hoverDisposables.add(addDisposableListener(focusedElement, EventType.KEY_DOWN, () => { - this.hideHover(); - this._lastFocusedElementBeforeOpen?.focus(); - })); - } } if ('IntersectionObserver' in window) { @@ -110,7 +107,7 @@ export class HoverService implements IHoverService { } } - private _keyDown(e: KeyboardEvent, hover: HoverWidget) { + private _keyDown(e: KeyboardEvent, hover: HoverWidget, hideOnKeyDown: boolean) { if (e.key === 'Alt') { hover.isLocked = true; return; @@ -120,7 +117,7 @@ export class HoverService implements IHoverService { if (keybinding.getSingleModifierDispatchChords().some(value => !!value) || this._keybindingService.softDispatch(event, event.target)) { return; } - if (!this._currentHoverOptions?.trapFocus || e.key !== 'Tab') { + if (hideOnKeyDown && (!this._currentHoverOptions?.trapFocus || e.key !== 'Tab')) { this.hideHover(); this._lastFocusedElementBeforeOpen?.focus(); } @@ -129,7 +126,7 @@ export class HoverService implements IHoverService { private _keyUp(e: KeyboardEvent, hover: HoverWidget) { if (e.key === 'Alt') { hover.isLocked = false; - // Hide if alt is released while the mouse os not over hover/target + // Hide if alt is released while the mouse is not over hover/target if (!hover.isMouseIn) { this.hideHover(); this._lastFocusedElementBeforeOpen?.focus();