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:
parent
5edf8dc306
commit
718e6712c5
1 changed files with 17 additions and 8 deletions
25
chrome.html
25
chrome.html
|
|
@ -522,7 +522,22 @@
|
||||||
<script>
|
<script>
|
||||||
const $ = (id) => document.getElementById(id);
|
const $ = (id) => document.getElementById(id);
|
||||||
const T = window.theseus;
|
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
|
// 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
|
// 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
|
// 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
|
// 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;
|
// and buttons). Grow the view to fit the box while a prompt is open;
|
||||||
// done() calls syncHeight() to shrink it back.
|
// done() calls syncHeight() to shrink it back.
|
||||||
function growForPrompt(mask) {
|
function growForPrompt() { syncHeight(); }
|
||||||
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 inPrompt(label, initial) {
|
function inPrompt(label, initial) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const mask = document.createElement("div"); mask.className = "promptmask";
|
const mask = document.createElement("div"); mask.className = "promptmask";
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue