diff --git a/src/main.ts b/src/main.ts index 52bb3c4..66ff526 100644 --- a/src/main.ts +++ b/src/main.ts @@ -165,11 +165,26 @@ export default function () { let lastNativePosKey = '' // canvas-space key of last native-drag position (to detect titlebar drags) const dockInterval = setInterval(function () { if (dockedPosition !== null) { - const b = figma.viewport.bounds - const key = `${b.x}|${b.y}|${b.width}|${b.height}` - if (key !== lastBoundsKey) { - lastBoundsKey = key - applyDock(dockedPosition, lastSize.width, lastSize.height, false) + // Keep the docked window pinned to its edge. Re-pin whenever it has drifted + // from the computed target — this catches zoom/pan (figma.viewport.bounds + // change) AND a Figma UI panel resize (Figma shifts the plugin window to + // stay visible, but viewport.bounds may not change, so a bounds-key check + // alone misses it). A docked window is meant to stay put, so snapping a + // stray drift back to the edge is the desired behaviour. + const target = computeDockPos(dockedPosition, lastSize.width, lastSize.height) + try { + const pos = (figma.ui as any).getPosition() + const drift = Math.abs(Math.round(pos.canvasSpace.x) - Math.round(target.x)) + + Math.abs(Math.round(pos.canvasSpace.y) - Math.round(target.y)) + if (drift > 2) figma.ui.reposition(target.x, target.y) + } catch (e) { + // getPosition unavailable — fall back to the bounds-key trigger. + const b = figma.viewport.bounds + const key = `${b.x}|${b.y}|${b.width}|${b.height}` + if (key !== lastBoundsKey) { + lastBoundsKey = key + applyDock(dockedPosition, lastSize.width, lastSize.height, false) + } } return }