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)
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()