From 54df917ffdd69c4f7ffaeccf2d161261ca80d84e Mon Sep 17 00:00:00 2001 From: Caleb Allen Date: Sun, 15 Mar 2026 09:11:36 -0400 Subject: [PATCH] fix: preserve scroll position in cached grid views display:none discards scrollTop in WebKitGTK, so navigating away from album/artist/genre grids and back reset scroll to top. Replace inline style.display toggling with a CSS class that uses visibility:hidden + height:0 + overflow:hidden. This collapses the element visually while keeping the DOM alive with its scroll state intact. contain:strict on hidden views ensures zero layout cost while collapsed. --- frontend/index.css | 11 +++++++++++ frontend/index.ts | 11 ++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/frontend/index.css b/frontend/index.css index 87be6ce..e6edb7e 100644 --- a/frontend/index.css +++ b/frontend/index.css @@ -152,3 +152,14 @@ body div.sidebar { height: 100%; contain: layout style paint; } + +/* Hidden cached views: use visibility+size collapse instead of + display:none so scroll containers preserve their scrollTop. + display:none discards scroll state in WebKitGTK. */ +.main-panel > .view-hidden { + visibility: hidden !important; + height: 0 !important; + overflow: hidden !important; + pointer-events: none !important; + contain: strict !important; +} diff --git a/frontend/index.ts b/frontend/index.ts index 223bd43..cb39c47 100644 --- a/frontend/index.ts +++ b/frontend/index.ts @@ -92,15 +92,16 @@ document.addEventListener('navigate', (e: Event) => { target = document.createElement(VIEW_TAGS[view]); viewCache.set(view, target); // Start hidden — we'll un-hide below - target.style.display = 'none'; + target.classList.add('view-hidden'); mainContent.appendChild(target); } - // Hide current, show target + // Hide current, show target. Uses CSS class instead of + // display:none so scroll containers preserve scrollTop. if (currentViewEl && currentViewEl !== target) { - currentViewEl.style.display = 'none'; + currentViewEl.classList.add('view-hidden'); } - target.style.display = ''; + target.classList.remove('view-hidden'); currentViewEl = target; return; } @@ -108,7 +109,7 @@ document.addEventListener('navigate', (e: Event) => { // --- Detail (ephemeral) views ----------------------------------------- // Hide the current primary view if (currentViewEl) { - currentViewEl.style.display = 'none'; + currentViewEl.classList.add('view-hidden'); } // Remove any prior detail element if (currentDetailEl) {