Skip to content

Commit 4b06a77

Browse files
authored
Fix hover stuttering. (#11675)
* Fix hover stuttering. * Review feedback
1 parent bd22b95 commit 4b06a77

File tree

2 files changed

+27
-10
lines changed

2 files changed

+27
-10
lines changed

news/2 Fixes/11422.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Hover on notebooks or interactive window seems to stutter.

src/datascience-ui/react-common/monacoEditor.tsx

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -713,14 +713,18 @@ export class MonacoEditor extends React.Component<IMonacoEditorProps, IMonacoEdi
713713
}
714714
};
715715

716-
private onHoverLeave = () => {
716+
private onHoverLeave = (e: MouseEvent) => {
717717
// If the hover is active, make sure to hide it.
718718
if (this.state.editor && this.widgetParent) {
719719
this.enteredHover = false;
720-
// tslint:disable-next-line: no-any
721-
const hover = this.state.editor.getContribution('editor.contrib.hover') as any;
722-
if (hover._hideWidgets) {
723-
hover._hideWidgets();
720+
721+
// Hide only if not still inside the same editor. Monaco will handle closing otherwise
722+
if (!this.coordsInsideEditor(e.clientX, e.clientY)) {
723+
// tslint:disable-next-line: no-any
724+
const hover = this.state.editor.getContribution('editor.contrib.hover') as any;
725+
if (hover._hideWidgets) {
726+
hover._hideWidgets();
727+
}
724728
}
725729
}
726730
};
@@ -732,25 +736,37 @@ export class MonacoEditor extends React.Component<IMonacoEditorProps, IMonacoEdi
732736
}
733737
};
734738

735-
private outermostParentLeave = () => {
739+
// tslint:disable-next-line: no-any
740+
private outermostParentLeave = (e: any) => {
736741
// Have to bounce this because the leave for the cell is the
737742
// enter for the hover
738743
if (this.leaveTimer) {
739744
clearTimeout(this.leaveTimer);
740745
}
741-
this.leaveTimer = window.setTimeout(this.outermostParentLeaveBounced, 0);
746+
this.leaveTimer = window.setTimeout(() => this.outermostParentLeaveBounced(e), 0);
742747
};
743748

744-
private outermostParentLeaveBounced = () => {
745-
if (this.state.editor && !this.enteredHover) {
749+
// tslint:disable-next-line: no-any
750+
private outermostParentLeaveBounced = (e: MouseEvent) => {
751+
if (this.state.editor && !this.enteredHover && !this.coordsInsideEditor(e.clientX, e.clientY)) {
746752
// If we haven't already entered hover, then act like it shuts down
747-
this.onHoverLeave();
753+
this.onHoverLeave(e);
748754
// Possible user is viewing the parameter hints, wait before user moves the mouse.
749755
// Waiting for 1s is too long to move the mouse and hide the hints (100ms seems like a good fit).
750756
setTimeout(() => this.hideParameterWidget(), 100);
751757
}
752758
};
753759

760+
private coordsInsideEditor(x: number, y: number): boolean {
761+
if (this.monacoContainer) {
762+
const clientRect = this.monacoContainer.getBoundingClientRect();
763+
if (x >= clientRect.left && x <= clientRect.right && y >= clientRect.top && y <= clientRect.bottom) {
764+
return true;
765+
}
766+
}
767+
return false;
768+
}
769+
754770
/**
755771
* This will hide the parameter widget if the user is not hovering over
756772
* the parameter widget for this monaco editor.

0 commit comments

Comments
 (0)