mirror of
https://github.com/block/buzz.git
synced 2026-11-03 07:51:22 +00:00
Add compositor scrolling experiment
Co-authored-by: npub12gtutshhh76rx0jx697f32f9tffd4hhp3hx58fp4x6u4uemkm7sqf8f757 <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@sprout-oss.stage.blox.sqprod.co> Signed-off-by: npub12gtutshhh76rx0jx697f32f9tffd4hhp3hx58fp4x6u4uemkm7sqf8f757 <5217c5c2f7bfb4333e46d17c98a9255a52dadee18dcd43a43536b95e6776dfa0@sprout-oss.stage.blox.sqprod.co>
This commit is contained in:
parent
46613dccec
commit
56e3b8a146
@@ -96,7 +96,10 @@ const LazySettingsScreen = React.lazy(async () => {
|
||||
export function AppShell() {
|
||||
useWebviewZoomShortcuts();
|
||||
useTauriWindowDrag();
|
||||
useWebviewScrollBoundaryLock();
|
||||
const compositorTimelineScrollEnabled = useFeatureEnabled(
|
||||
"compositorTimelineScroll",
|
||||
);
|
||||
useWebviewScrollBoundaryLock(!compositorTimelineScrollEnabled);
|
||||
|
||||
const workspacesHook = useWorkspaces();
|
||||
const workspaceRailEnabled = useFeatureEnabled("workspaceRail");
|
||||
|
||||
@@ -80,8 +80,12 @@ function isConversationScroller(element: HTMLElement) {
|
||||
* remain; every other boundary — including all horizontal ones — is locked and
|
||||
* cannot chain to the viewport.
|
||||
*/
|
||||
export function useWebviewScrollBoundaryLock() {
|
||||
export function useWebviewScrollBoundaryLock(enabled = true) {
|
||||
React.useEffect(() => {
|
||||
if (!enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
function handleWheel(event: WheelEvent) {
|
||||
if (event.defaultPrevented || event.ctrlKey) {
|
||||
return;
|
||||
@@ -137,5 +141,5 @@ export function useWebviewScrollBoundaryLock() {
|
||||
return () => {
|
||||
window.removeEventListener("wheel", handleWheel, { capture: true });
|
||||
};
|
||||
}, []);
|
||||
}, [enabled]);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,38 @@ async function dispatchWheelPrevented(
|
||||
}
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await installMockBridge(page);
|
||||
// Boundary-lock contracts exercise the stable/default path. Most E2E suites
|
||||
// opt every preview feature in, but compositorTimelineScroll intentionally
|
||||
// removes this listener so trackpad scrolling can stay off the main thread.
|
||||
await installMockBridge(page, undefined, { seedPreviewFeatures: false });
|
||||
});
|
||||
|
||||
test("compositor timeline scrolling leaves timeline wheel events unhandled", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.addInitScript(() => {
|
||||
localStorage.setItem(
|
||||
"buzz-feature-overrides-v1",
|
||||
JSON.stringify({ compositorTimelineScroll: true }),
|
||||
);
|
||||
});
|
||||
await page.goto("/");
|
||||
await page.getByTestId("channel-general").click();
|
||||
await expect(page.getByTestId("message-timeline")).toBeVisible();
|
||||
|
||||
// The diagnostic path removes the global non-passive listener rather than
|
||||
// merely returning early for conversations. The fixed-height shell and CSS
|
||||
// overscroll backstop remain; JS no longer blocks timeline scrolling.
|
||||
await expect(
|
||||
dispatchWheelPrevented(page, '[data-testid="message-timeline"]', {
|
||||
deltaY: -120,
|
||||
}),
|
||||
).resolves.toBe(false);
|
||||
await expect(
|
||||
dispatchWheelPrevented(page, '[data-testid="message-timeline"]', {
|
||||
deltaX: -120,
|
||||
}),
|
||||
).resolves.toBe(false);
|
||||
});
|
||||
|
||||
test("locks viewport rubber-band outside conversation scrollers", async ({
|
||||
|
||||
@@ -40,6 +40,14 @@
|
||||
"platforms": [
|
||||
"desktop"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "compositorTimelineScroll",
|
||||
"name": "Compositor timeline scrolling",
|
||||
"description": "Lets the webview handle timeline trackpad gestures without a global blocking wheel listener",
|
||||
"platforms": [
|
||||
"desktop"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user