diff --git a/static/js/cookbookServe.js b/static/js/cookbookServe.js index 8ee8c5c..e353950 100644 --- a/static/js/cookbookServe.js +++ b/static/js/cookbookServe.js @@ -949,9 +949,24 @@ function _rerenderCachedModels() { document.body.appendChild(popup); panel._gpuProbe.popup = popup; + // Position below the button using viewport coords (popup is + // position:fixed). Measure the popup AFTER it's in the DOM so + // we get the real rendered size, then clamp both axes so the + // popup stays fully visible — GPU buttons near the right edge + // of the modal previously anchored the popup mostly off-screen. const r = anchorBtn.getBoundingClientRect(); - popup.style.left = `${Math.max(8, r.left)}px`; - popup.style.top = `${r.bottom + 4 + window.scrollY}px`; + const vw = window.innerWidth || document.documentElement.clientWidth; + const vh = window.innerHeight || document.documentElement.clientHeight; + const pw = popup.offsetWidth || 320; + const ph = popup.offsetHeight || 200; + let left = r.left; + let top = r.bottom + 4; + // Push left so the popup doesn't overflow the right edge. + if (left + pw > vw - 8) left = Math.max(8, vw - pw - 8); + // If there isn't room below, render above the button instead. + if (top + ph > vh - 8) top = Math.max(8, r.top - ph - 4); + popup.style.left = `${left}px`; + popup.style.top = `${top}px`; popup.querySelector('.cookbook-gpu-popup-close')?.addEventListener('click', _closeProbePopup); popup.querySelectorAll('.cookbook-gpu-kill').forEach(btn => { diff --git a/static/style.css b/static/style.css index 52c7c70..cd36f2d 100644 --- a/static/style.css +++ b/static/style.css @@ -17773,8 +17773,12 @@ body.gallery-selecting .gallery-dl-btn, .cookbook-gpu-clear:disabled { opacity: 0.4; cursor: wait; } /* GPU probe popup — per-GPU process list with kill buttons */ .cookbook-gpu-popup { - position: absolute; - z-index: 240; + /* Fixed positioning (relative to viewport) so we never get pulled into + a scrolling/transform stacking context from an ancestor. Z-index has + to clear the cookbook modal (260) and the rest of the high-z UI + layers (themed-confirm and various overlays sit around 9000-10000). */ + position: fixed; + z-index: 10010; min-width: 280px; max-width: 420px; background: var(--panel, #1a1a1a);