fix: docked window re-fits on canvas change, preserves manual resize otherwise

This commit is contained in:
Hermes Agent committed 2026-09-16 12:58:35 +02:00
1 parent cd8b4a5a0d
commit 8b35cef414
1 file changed
+20 -13
+20 -13
View File
@@ -165,24 +165,31 @@ export default function () {
let lastNativePosKey = '' // canvas-space key of last native-drag position (to detect titlebar drags) let lastNativePosKey = '' // canvas-space key of last native-drag position (to detect titlebar drags)
const dockInterval = setInterval(function () { const dockInterval = setInterval(function () {
if (dockedPosition !== null) { if (dockedPosition !== null) {
// Keep the docked window pinned to its edge, adapting BOTH position and size // Keep the docked window pinned to its edge. Two concerns, handled separately:
// to the current visible canvas. Recompute from figma.viewport.bounds every // 1) SIZE — re-fit to the viewport only when the visible canvas actually
// tick so a Figma UI panel resize (which may not change viewport.bounds, but // changed (zoom/pan/panel resize). Full-fit (canonical=true) means the
// does shift the window) is caught — re-pin position on drift and re-apply the // window always fills its axis (top/bottom = full width, side = full
// bounds-derived size when the viewport shrinks/grows (e.g. top/bottom dock // height), so it tracks the panel in BOTH directions and never stays
// width = full viewport width, side dock height = full viewport height). // stuck at a clamped width. When bounds are stable we keep the current
const state = computeDock(dockedPosition, lastSize.width, lastSize.height, false) // (possibly manually resized) size so the poller doesn't fight a resize.
// 2) POSITION — re-pin whenever the window has drifted (Figma shifts it on
// panel resize even if viewport.bounds is unchanged), via drift detect.
const b = figma.viewport.bounds const b = figma.viewport.bounds
const boundsKey = `${b.x}|${b.y}|${b.width}|${b.height}`
const zoom = figma.viewport.zoom || 1 const zoom = figma.viewport.zoom || 1
const maxW = Math.round(b.width * zoom) const maxW = Math.round(b.width * zoom)
const maxH = Math.round(b.height * zoom) - PLUGIN_HEADER_PX const maxH = Math.round(b.height * zoom) - PLUGIN_HEADER_PX
// Never overflow the visible canvas (e.g. a very wide side panel). if (boundsKey !== lastBoundsKey) {
state.width = Math.min(state.width, Math.max(1, maxW)) lastBoundsKey = boundsKey
state.height = Math.min(state.height, Math.max(1, maxH)) const fit = computeDock(dockedPosition, lastSize.width, lastSize.height, true)
if (state.width !== lastSize.width || state.height !== lastSize.height) { const fw = Math.min(fit.width, Math.max(1, maxW))
figma.ui.resize(Math.max(1, state.width), Math.max(1, state.height)) const fh = Math.min(fit.height, Math.max(1, maxH))
lastSize = { width: state.width, height: state.height } if (fw !== lastSize.width || fh !== lastSize.height) {
figma.ui.resize(Math.max(1, fw), Math.max(1, fh))
lastSize = { width: fw, height: fh }
}
} }
const state = computeDock(dockedPosition, lastSize.width, lastSize.height, false)
let drift = Infinity let drift = Infinity
try { try {
const pos = (figma.ui as any).getPosition() const pos = (figma.ui as any).getPosition()