From 8cd160ee4f807fd7817ff0dfc198efc17d21d4d8 Mon Sep 17 00:00:00 2001 From: Devanarayanan Date: Fri, 6 Mar 2026 12:44:26 +0530 Subject: [PATCH 1/4] fix(scroll): normalize wheel delta for Firefox Linux snap scrolling - convert wheel delta from line/page modes to pixel units before snap logic - use normalized delta for direction and accumulator checks - extract snap threshold into WHEEL_SNAP_THRESHOLD_PX constant - bump version to 1.1.4 in package metadata and docs --- README.md | 4 ++-- SECURITY.md | 2 +- app/page.tsx | 35 +++++++++++++++++++++++++++++++---- package-lock.json | 4 ++-- package.json | 2 +- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d507804..9cb3275 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Where code meets conscience.** A brutalist × cyberpunk portfolio built with Next.js 16. -[![Version](https://img.shields.io/badge/version-1.1.3-cyan?logo=github)](package.json) +[![Version](https://img.shields.io/badge/version-1.1.4-cyan?logo=github)](package.json) [![Security: SLSA Level 3](https://img.shields.io/badge/SLSA-Level%203-brightgreen)](https://github.com/devakesu/devakesu-web/attestations) [![Security Scan: Trivy](https://img.shields.io/badge/Security-Trivy%20Scanned-blue)](.github/workflows/deploy.yml) [![Attestations](https://img.shields.io/badge/Attestations-Enabled-success)](https://github.com/devakesu/devakesu-web/attestations) @@ -414,4 +414,4 @@ _Love is the only way to rescue humanity from all evils._ --- **Last Updated**: March 02, 2026 -**Version**: 1.1.3 +**Version**: 1.1.4 diff --git a/SECURITY.md b/SECURITY.md index 2022565..c8b1035 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -149,4 +149,4 @@ We appreciate security researchers who responsibly disclose vulnerabilities. --- **Last Updated**: March 02, 2026 -**Version**: 1.1.3 +**Version**: 1.1.4 diff --git a/app/page.tsx b/app/page.tsx index b6ee957..67e06a0 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -28,6 +28,7 @@ import { import { FaXTwitter } from "react-icons/fa6"; const SCROLL_LOCK_DURATION = 800; +const WHEEL_SNAP_THRESHOLD_PX = 50; // Throttle utility for performance optimization const throttle = void>( @@ -650,7 +651,33 @@ export default function Home() { }, SCROLL_LOCK_DURATION); }; + const getNormalizedWheelDeltaY = (event: WheelEvent): number => { + // Firefox on Linux often reports wheel deltas in lines/pages instead of + // pixels. Normalize to px so threshold checks stay consistent. + if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) { + const rootLineHeight = Number.parseFloat( + window.getComputedStyle(document.documentElement).lineHeight, + ); + const lineHeight = Number.isFinite(rootLineHeight) && rootLineHeight > 0 + ? rootLineHeight + : 16; + return event.deltaY * lineHeight; + } + + if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) { + return event.deltaY * window.innerHeight; + } + + return event.deltaY; + }; + const handleWheel = (event: WheelEvent) => { + const normalizedDeltaY = getNormalizedWheelDeltaY(event); + + if (normalizedDeltaY === 0) { + return; + } + // Setup scrolling ends detector to reset inertia blocking if (scrollEndTimeoutRef.current) { clearTimeout(scrollEndTimeoutRef.current); @@ -666,12 +693,12 @@ export default function Home() { // but only if it's not a modifying shortcut or inside a scrollable div if ( event.ctrlKey || - allowNativeScroll(event.target, event.deltaY > 0 ? 1 : -1) + allowNativeScroll(event.target, normalizedDeltaY > 0 ? 1 : -1) ) { return; } - const direction = event.deltaY > 0 ? 1 : -1; + const direction = normalizedDeltaY > 0 ? 1 : -1; // Allow free native scrolling within sections taller than the viewport if (canScrollWithinSection(direction)) { @@ -705,7 +732,7 @@ export default function Home() { // Trackpads fire hundreds of tiny wheel events. We use an accumulator // to ensure a deliberate swipe happens, ignoring delicate resting finger movements - wheelAccumulatorRef.current += event.deltaY; + wheelAccumulatorRef.current += normalizedDeltaY; if (wheelLockTimeoutRef.current) { clearTimeout(wheelLockTimeoutRef.current); @@ -717,7 +744,7 @@ export default function Home() { }, 50); // Require a larger accumulation for trackpads to trigger the next section - if (Math.abs(wheelAccumulatorRef.current) < 50) { + if (Math.abs(wheelAccumulatorRef.current) < WHEEL_SNAP_THRESHOLD_PX) { return; } diff --git a/package-lock.json b/package-lock.json index 19193d7..f7620ca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "devakesu-web", - "version": "1.1.3", + "version": "1.1.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "devakesu-web", - "version": "1.1.3", + "version": "1.1.4", "dependencies": { "next": "16.1.6", "react": "19.2.4", diff --git a/package.json b/package.json index f707308..02be7df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "devakesu-web", - "version": "1.1.3", + "version": "1.1.4", "private": true, "engines": { "node": ">=20.19.0" From b941b23bdf0642f636161ac235c9eb5d481dd9fa Mon Sep 17 00:00:00 2001 From: Devanarayanan Date: Fri, 6 Mar 2026 12:49:23 +0530 Subject: [PATCH 2/4] Update app/page.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Devanarayanan --- app/page.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 67e06a0..e911aac 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -651,17 +651,18 @@ export default function Home() { }, SCROLL_LOCK_DURATION); }; + const rootLineHeight = Number.parseFloat( + window.getComputedStyle(document.documentElement).lineHeight, + ); + const cachedLineHeight = Number.isFinite(rootLineHeight) && rootLineHeight > 0 + ? rootLineHeight + : 16; + const getNormalizedWheelDeltaY = (event: WheelEvent): number => { // Firefox on Linux often reports wheel deltas in lines/pages instead of // pixels. Normalize to px so threshold checks stay consistent. if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) { - const rootLineHeight = Number.parseFloat( - window.getComputedStyle(document.documentElement).lineHeight, - ); - const lineHeight = Number.isFinite(rootLineHeight) && rootLineHeight > 0 - ? rootLineHeight - : 16; - return event.deltaY * lineHeight; + return event.deltaY * cachedLineHeight; } if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) { From 40eab65c6aee9fc5f447fe6fbdcdf5234ee82acd Mon Sep 17 00:00:00 2001 From: Devanarayanan Date: Fri, 6 Mar 2026 12:52:43 +0530 Subject: [PATCH 3/4] Update app/page.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Devanarayanan --- app/page.tsx | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index e911aac..9ae86f2 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -651,13 +651,21 @@ export default function Home() { }, SCROLL_LOCK_DURATION); }; - const rootLineHeight = Number.parseFloat( - window.getComputedStyle(document.documentElement).lineHeight, - ); - const cachedLineHeight = Number.isFinite(rootLineHeight) && rootLineHeight > 0 - ? rootLineHeight - : 16; + const rootComputedStyle = window.getComputedStyle(document.documentElement); + const rawLineHeight = rootComputedStyle.lineHeight; + + let cachedLineHeight: number; + const parsedLineHeight = Number.parseFloat(rawLineHeight); + if (Number.isFinite(parsedLineHeight) && parsedLineHeight > 0) { + cachedLineHeight = parsedLineHeight; + } else { + const fontSize = Number.parseFloat(rootComputedStyle.fontSize); + const derivedFromFontSize = Number.isFinite(fontSize) && fontSize > 0 + ? fontSize * 1.2 + : 16; + cachedLineHeight = derivedFromFontSize; + } const getNormalizedWheelDeltaY = (event: WheelEvent): number => { // Firefox on Linux often reports wheel deltas in lines/pages instead of // pixels. Normalize to px so threshold checks stay consistent. From b20f2613de679611a43461c0536881e061687c99 Mon Sep 17 00:00:00 2001 From: Devanarayanan Date: Fri, 6 Mar 2026 12:57:47 +0530 Subject: [PATCH 4/4] Update app/page.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Devanarayanan --- app/page.tsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/app/page.tsx b/app/page.tsx index 9ae86f2..a865169 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -654,18 +654,17 @@ export default function Home() { const rootComputedStyle = window.getComputedStyle(document.documentElement); const rawLineHeight = rootComputedStyle.lineHeight; - let cachedLineHeight: number; const parsedLineHeight = Number.parseFloat(rawLineHeight); - - if (Number.isFinite(parsedLineHeight) && parsedLineHeight > 0) { - cachedLineHeight = parsedLineHeight; - } else { + const cachedLineHeight: number = (() => { + if (Number.isFinite(parsedLineHeight) && parsedLineHeight > 0) { + return parsedLineHeight; + } const fontSize = Number.parseFloat(rootComputedStyle.fontSize); const derivedFromFontSize = Number.isFinite(fontSize) && fontSize > 0 ? fontSize * 1.2 : 16; - cachedLineHeight = derivedFromFontSize; - } + return derivedFromFontSize; + })(); const getNormalizedWheelDeltaY = (event: WheelEvent): number => { // Firefox on Linux often reports wheel deltas in lines/pages instead of // pixels. Normalize to px so threshold checks stay consistent.