#246

Cell measurement is wrong under an ancestor CSS transform

Openbuntecopened 11d ago

Summary

Inside an ancestor with a CSS transform: scale(), wterm measures scaled cells. It writes them to --term-cell-width and --term-row-height, so rows render at the wrong size in the unscaled layout and the fitted grid is wrong. We hit this with live terminal thumbnails (a grid of scaled-down terminals).

Cause

_measureCharSize() and _setRowHeight() read getBoundingClientRect(), which includes ancestor transforms, while layout (and clientWidth/clientHeight) is in untransformed CSS pixels.

Repro (@wterm/dom 0.5.4, @wterm/ghostty core, Chrome)

async function mount(scale) {
  const parent = document.createElement("div");
  parent.style.cssText = `position:fixed;left:0;top:0;transform:scale(${scale});transform-origin:0 0`;
  const el = document.createElement("div");
  el.style.cssText = "width:800px;height:400px;padding:0";
  parent.appendChild(el);
  document.body.appendChild(parent);
  const term = new WTerm(el, { core: await GhosttyCore.load() });
  await term.init();
  const s = getComputedStyle(el);
  return [s.getPropertyValue("--term-cell-width"), s.getPropertyValue("--term-row-height"), term.cols, term.rows];
}
console.log(await mount(1));   // ["8.4375px", "17px", 94, 23]
console.log(await mount(0.5)); // ["4.21875px", "8.5px", 94, 47]; expected the same as scale 1

Possible fix

Divide the measured sizes by the element's scale, e.g. el.getBoundingClientRect().width / el.offsetWidth (when offsetWidth > 0). We work around it by wrapping both private methods this way, which fixes it.

Activity

0

No activity yet.