Fix user menu clipping at scaled UI (110%+)

Menu primitive uses position:fixed inside a CSS-transformed container
(#surfaceInner scale). getBoundingClientRect() returns scaled coords
but fixed positioning uses the transform container's coordinate space.

Divide anchor rect and viewport dimensions by sw.shell.getScale() to
convert to the correct coordinate space. Menu now positions and clamps
correctly at any UI scale setting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-30 15:11:53 +00:00
parent 6e68c41d5a
commit aae1f6ecf2

View File

@@ -17,13 +17,20 @@ export function Menu({ items = [], anchor, open, direction = 'down-right', onSel
const selectableItems = items.filter(i => !i.divider && !i.disabled);
// Position relative to anchor
// When the surface uses CSS transform: scale(), getBoundingClientRect()
// returns scaled coordinates but position:fixed uses viewport coordinates.
// Dividing by the scale factor converts back to true viewport pixels.
useEffect(() => {
if (!open || !anchor) return;
const rect = typeof anchor.getBoundingClientRect === 'function'
const scale = window.sw?.shell?.getScale?.() || 1;
const raw = typeof anchor.getBoundingClientRect === 'function'
? anchor.getBoundingClientRect()
: anchor;
const vw = window.innerWidth;
const vh = window.innerHeight;
const rect = scale !== 1
? { top: raw.top / scale, bottom: raw.bottom / scale, left: raw.left / scale, right: raw.right / scale }
: raw;
const vw = window.innerWidth / scale;
const vh = window.innerHeight / scale;
let top, left;
const [vDir, hDir] = direction.split('-');