diff --git a/src/main.ts b/src/main.ts index e044e19..17e9e6c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -165,24 +165,31 @@ export default function () { let lastNativePosKey = '' // canvas-space key of last native-drag position (to detect titlebar drags) const dockInterval = setInterval(function () { if (dockedPosition !== null) { - // Keep the docked window pinned to its edge, adapting BOTH position and size - // to the current visible canvas. Recompute from figma.viewport.bounds every - // tick so a Figma UI panel resize (which may not change viewport.bounds, but - // does shift the window) is caught — re-pin position on drift and re-apply the - // bounds-derived size when the viewport shrinks/grows (e.g. top/bottom dock - // width = full viewport width, side dock height = full viewport height). - const state = computeDock(dockedPosition, lastSize.width, lastSize.height, false) + // Keep the docked window pinned to its edge. Two concerns, handled separately: + // 1) SIZE — re-fit to the viewport only when the visible canvas actually + // changed (zoom/pan/panel resize). Full-fit (canonical=true) means the + // window always fills its axis (top/bottom = full width, side = full + // height), so it tracks the panel in BOTH directions and never stays + // stuck at a clamped width. When bounds are stable we keep the current + // (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 boundsKey = `${b.x}|${b.y}|${b.width}|${b.height}` const zoom = figma.viewport.zoom || 1 const maxW = Math.round(b.width * zoom) const maxH = Math.round(b.height * zoom) - PLUGIN_HEADER_PX - // Never overflow the visible canvas (e.g. a very wide side panel). - state.width = Math.min(state.width, Math.max(1, maxW)) - state.height = Math.min(state.height, Math.max(1, maxH)) - if (state.width !== lastSize.width || state.height !== lastSize.height) { - figma.ui.resize(Math.max(1, state.width), Math.max(1, state.height)) - lastSize = { width: state.width, height: state.height } + if (boundsKey !== lastBoundsKey) { + lastBoundsKey = boundsKey + const fit = computeDock(dockedPosition, lastSize.width, lastSize.height, true) + const fw = Math.min(fit.width, Math.max(1, maxW)) + const fh = Math.min(fit.height, Math.max(1, maxH)) + 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 try { const pos = (figma.ui as any).getPosition()