Skip to content

Commit

Permalink
Cancel pending hover on mouse exit (#14533)
Browse files Browse the repository at this point in the history
If the mouse exits before the HoverService has rendered its pop-up,
cancel the pending presentation of that pop-up.

Also fix the problem of it being difficult to mouse over to the pop-up
itself after it is shown to interact with it (it being necessary to
carefully track over the bottom triangle). This is accomplished by
cancelling only after a short delay that allows the mouse to reach
either the pop-up or the original hover target.

Fixes #14532

Signed-off-by: Christian W. Damus <[email protected]>
  • Loading branch information
cdamus authored Dec 12, 2024
1 parent 53c09a8 commit e2c9011
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions packages/core/src/browser/hover-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ import '../../src/browser/style/hover-service.css';

export type HoverPosition = 'left' | 'right' | 'top' | 'bottom';

// Threshold, in milliseconds, over which a mouse movement is not considered
// quick enough as to be ignored
const quickMouseThresholdMillis = 200;

export namespace HoverPosition {
export function invertIfNecessary(position: HoverPosition, target: DOMRect, host: DOMRect, totalWidth: number, totalHeight: number): HoverPosition {
if (position === 'left') {
Expand Down Expand Up @@ -100,11 +104,13 @@ export class HoverService {
if (request.target !== this.hoverTarget) {
this.cancelHover();
this.pendingTimeout = disposableTimeout(() => this.renderHover(request), this.getHoverDelay());
this.hoverTarget = request.target;
this.listenForMouseOut();
}
}

protected getHoverDelay(): number {
return Date.now() - this.lastHidHover < 200
return Date.now() - this.lastHidHover < quickMouseThresholdMillis
? 0
: this.preferences.get('workbench.hover.delay', isOSX ? 1500 : 500);
}
Expand All @@ -116,7 +122,6 @@ export class HoverService {
if (cssClasses) {
host.classList.add(...cssClasses);
}
this.hoverTarget = target;
if (content instanceof HTMLElement) {
host.appendChild(content);
firstChild = content;
Expand Down Expand Up @@ -155,8 +160,6 @@ export class HoverService {
}
}
});

this.listenForMouseOut();
}

protected setHostPosition(target: HTMLElement, host: HTMLElement, position: HoverPosition): HoverPosition {
Expand Down Expand Up @@ -197,7 +200,11 @@ export class HoverService {
protected listenForMouseOut(): void {
const handleMouseMove = (e: MouseEvent) => {
if (e.target instanceof Node && !this.hoverHost.contains(e.target) && !this.hoverTarget?.contains(e.target)) {
this.cancelHover();
this.disposeOnHide.push(disposableTimeout(() => {
if (!this.hoverHost.matches(':hover') && !this.hoverTarget?.matches(':hover')) {
this.cancelHover();
}
}, quickMouseThresholdMillis));
}
};
document.addEventListener('mousemove', handleMouseMove);
Expand Down

0 comments on commit e2c9011

Please sign in to comment.