fix(theseus): chrome height sync must not wait for an animation frame

syncHeight queued its measurement in requestAnimationFrame, and frames
stop whenever the window is occluded — so a prompt closing, or a row
hiding, while another window covered Theseus left the chrome at its
old height until the window came back. A zero timeout coalesces the
same way and always runs. The open-prompt allowance now lives in
syncHeight itself, so any re-measure while a prompt is up keeps its
room, and the growth helper simply defers to it.
This commit is contained in:
Local Dev 2026-09-25 08:34:44 +02:00
parent 5edf8dc306
commit 718e6712c5

View file

@ -522,7 +522,22 @@
<script>
const $ = (id) => document.getElementById(id);
const T = window.theseus;
function syncHeight() { requestAnimationFrame(() => T.setChromeHeight(document.body.scrollHeight)); }
// Every caller (tab events, window resize, prompts) funnels through here,
// so an open prompt keeps its room no matter what else re-measures the
// chrome while it is up — a fixed mask never counts toward scrollHeight.
// Coalesced with a zero timeout, not requestAnimationFrame: frames stop
// whenever the window is occluded, and a height change queued then (a
// prompt closing, a row hiding) would only land when the window came back.
let syncHeightTimer = 0;
function syncHeight() {
clearTimeout(syncHeightTimer);
syncHeightTimer = setTimeout(() => {
let h = document.body.scrollHeight;
const box = document.querySelector(".promptmask .promptbox");
if (box) h = Math.max(h, Math.ceil(box.getBoundingClientRect().height) + 56);
T.setChromeHeight(h);
}, 0);
}
// Reserve room for the native window-controls overlay at the right of the
// tab row (Windows only — the frame is hidden there, see main.js). Use the
// overlay's real geometry when Chromium exposes it to this view; otherwise
@ -1111,13 +1126,7 @@
// cut off at the view's edge (the two-field favorites form lost its title
// and buttons). Grow the view to fit the box while a prompt is open;
// done() calls syncHeight() to shrink it back.
function growForPrompt(mask) {
try {
const box = mask.querySelector(".promptbox");
const need = box ? Math.ceil(box.getBoundingClientRect().height) + 56 : 0;
T.setChromeHeight(Math.max(document.body.scrollHeight, need));
} catch {}
}
function growForPrompt() { syncHeight(); }
function inPrompt(label, initial) {
return new Promise((resolve) => {
const mask = document.createElement("div"); mask.className = "promptmask";