From cdada2986b236e6f5d1412751599ca2ba7dfaa54 Mon Sep 17 00:00:00 2001 From: vineyardbovines Date: Tue, 9 Jun 2026 09:39:38 -0400 Subject: [PATCH] Fix composer horizontal swipe triggering browser back/forward Two-finger horizontal trackpad swipes over the composer were escaping to the page's history-nav gesture, especially obvious when a quote post was attached. Mirror the carousel fix: `overscroll-behavior-x: contain` on the composer's ScrollView for Chrome/Firefox, plus a wheel listener that preventDefaults horizontal-dominant wheels for Safari (which ignores overscroll-behavior). --- src/view/com/composer/Composer.tsx | 32 +++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index ab8f4d9cc5..25ed831c3c 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -134,7 +134,14 @@ import * as Prompt from '#/components/Prompt' import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' -import {IS_ANDROID, IS_IOS, IS_LIQUID_GLASS, IS_NATIVE, IS_WEB} from '#/env' +import { + IS_ANDROID, + IS_IOS, + IS_LIQUID_GLASS, + IS_NATIVE, + IS_WEB, + IS_WEB_SAFARI, +} from '#/env' import {type Gif} from '#/features/gifPicker/types' import {BottomSheetPortalProvider} from '../../../../modules/bottom-sheet' import { @@ -1219,6 +1226,24 @@ export const ComposePost = ({ } }, [composerState]) + useEffect(() => { + // Safari ignores `overscroll-behavior`, so horizontal trackpad swipes over + // the composer (e.g. on a quote post) can still trigger the browser's + // back/forward navigation gesture. Suppress predominantly-horizontal wheel + // events so the history-nav gesture never fires. Chrome and Firefox are + // covered by the `overscrollBehaviorX: 'contain'` style on the ScrollView. + if (!IS_WEB_SAFARI) return + const el = + scrollViewRef.current?.getScrollableNode() as unknown as HTMLElement | null + if (!el) return + const onWheel = (e: WheelEvent) => { + if (Math.abs(e.deltaX) <= Math.abs(e.deltaY)) return + e.preventDefault() + } + el.addEventListener('wheel', onWheel, {passive: false}) + return () => el.removeEventListener('wheel', onWheel) + }, [scrollViewRef]) + const isLastThreadedPost = thread.posts.length > 1 && nextPost === undefined const { scrollHandler, @@ -1324,6 +1349,11 @@ export const ComposePost = ({ web({ scrollbarGutter: 'stable', scrollbarColor: `${t.palette.contrast_200} transparent`, + // Prevent horizontal trackpad swipes from triggering the + // browser's back/forward overscroll-navigation gesture. + // Handles Chrome and Firefox; Safari is handled separately + // via a wheel listener since it ignores overscroll-behavior. + overscrollBehaviorX: 'contain', }), ]} keyboardShouldPersistTaps="always"