Skip to content

Commit e679614

Browse files
authored
Extra scrolling logic to handle long tail of scroll events (microsoft#208341)
* special scrolling logic * longer comment
1 parent 7a8b6a8 commit e679614

File tree

1 file changed

+44
-9
lines changed

1 file changed

+44
-9
lines changed

src/vs/workbench/contrib/notebook/browser/view/renderers/webviewPreloads.ts

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -521,13 +521,49 @@ async function webviewPreloads(ctx: PreloadContext) {
521521
}
522522
};
523523

524+
let previousDelta: number | undefined;
524525
let scrollTimeout: any /* NodeJS.Timeout */ | undefined;
525526
let scrolledElement: Element | undefined;
526-
function flagRecentlyScrolled(node: Element) {
527+
let lastTimeScrolled: number | undefined;
528+
function flagRecentlyScrolled(node: Element, deltaY?: number) {
527529
scrolledElement = node;
528-
node.setAttribute('recentlyScrolled', 'true');
529-
clearTimeout(scrollTimeout);
530-
scrollTimeout = setTimeout(() => { scrolledElement?.removeAttribute('recentlyScrolled'); }, 300);
530+
if (!deltaY) {
531+
lastTimeScrolled = Date.now();
532+
previousDelta = undefined;
533+
node.setAttribute('recentlyScrolled', 'true');
534+
clearTimeout(scrollTimeout);
535+
scrollTimeout = setTimeout(() => { scrolledElement?.removeAttribute('recentlyScrolled'); }, 300);
536+
return true;
537+
}
538+
539+
if (node.hasAttribute('recentlyScrolled')) {
540+
if (lastTimeScrolled && Date.now() - lastTimeScrolled > 300) {
541+
// it has been a while since we actually scrolled
542+
// if scroll velocity increases, it's likely a new scroll event
543+
if (!!previousDelta && deltaY < 0 && deltaY < previousDelta - 2) {
544+
clearTimeout(scrollTimeout);
545+
scrolledElement?.removeAttribute('recentlyScrolled');
546+
return false;
547+
} else if (!!previousDelta && deltaY > 0 && deltaY > previousDelta + 2) {
548+
clearTimeout(scrollTimeout);
549+
scrolledElement?.removeAttribute('recentlyScrolled');
550+
return false;
551+
}
552+
553+
// the tail end of a smooth scrolling event (from a trackpad) can go on for a while
554+
// so keep swallowing it, but we can shorten the timeout since the events occur rapidly
555+
clearTimeout(scrollTimeout);
556+
scrollTimeout = setTimeout(() => { scrolledElement?.removeAttribute('recentlyScrolled'); }, 50);
557+
} else {
558+
clearTimeout(scrollTimeout);
559+
scrollTimeout = setTimeout(() => { scrolledElement?.removeAttribute('recentlyScrolled'); }, 300);
560+
}
561+
562+
previousDelta = deltaY;
563+
return true;
564+
}
565+
566+
return false;
531567
}
532568

533569
function eventTargetShouldHandleScroll(event: WheelEvent) {
@@ -536,11 +572,6 @@ async function webviewPreloads(ctx: PreloadContext) {
536572
return false;
537573
}
538574

539-
if (node.hasAttribute('recentlyScrolled') && scrolledElement === node) {
540-
flagRecentlyScrolled(node);
541-
return true;
542-
}
543-
544575
// scroll up
545576
if (event.deltaY < 0 && node.scrollTop > 0) {
546577
// there is still some content to scroll
@@ -565,6 +596,10 @@ async function webviewPreloads(ctx: PreloadContext) {
565596
flagRecentlyScrolled(node);
566597
return true;
567598
}
599+
600+
if (flagRecentlyScrolled(node, event.deltaY)) {
601+
return true;
602+
}
568603
}
569604

570605
return false;

0 commit comments

Comments
 (0)