mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-20 23:04:06 +00:00
fix: suppress link rendering during slot sync after graph reconfigure (#8367)
## Description Fixes link alignment issues after undo/redo operations in Vue Nodes 2.0. When multiple connections exist from the same output to different nodes, performing an undo would cause the connections to become misaligned with their inputs. ## Root Cause When undo triggers `loadGraphData`, the graph is reconfigured and Vue node components are destroyed and recreated. The new slot elements mount and schedule RAF-batched position syncs via `scheduleSlotLayoutSync`. However, links are drawn **before** the RAF batch completes, causing `getSlotPosition()` to return stale/missing positions. ## Solution - Export a new `flushPendingSlotLayoutSyncs()` function from `useSlotElementTracking.ts` - Create a `useGraphConfigureSlotSync` composable that flushes pending syncs after graph configuration - Integrate the flush into `addAfterConfigureHandler` in `app.ts`, called after `onAfterGraphConfigured` - Force canvas redraw after flushing to render links with correct positions ## Testing - Added unit tests for `flushPendingSlotLayoutSyncs` - Added unit tests for `useGraphConfigureSlotSync` composable - Manual verification: connections now align correctly after undo/redo operations ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8367-fix-flush-pending-slot-layout-syncs-after-graph-configure-2f66d73d365081a3a564fac96c44a048) by [Unito](https://www.unito.io) --------- Co-authored-by: Subagent 5 <subagent@example.com> Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -5,6 +5,8 @@ import { reactive, unref } from 'vue'
|
||||
import { shallowRef } from 'vue'
|
||||
|
||||
import { useCanvasPositionConversion } from '@/composables/element/useCanvasPositionConversion'
|
||||
import { layoutStore } from '@/renderer/core/layout/store/layoutStore'
|
||||
import { flushScheduledSlotLayoutSync } from '@/renderer/extensions/vueNodes/composables/useSlotElementTracking'
|
||||
import { registerProxyWidgets } from '@/core/graph/subgraph/proxyWidget'
|
||||
import { st, t } from '@/i18n'
|
||||
import type { IContextMenuValue } from '@/lib/litegraph/src/interfaces'
|
||||
@@ -734,17 +736,31 @@ export class ComfyApp {
|
||||
private addAfterConfigureHandler(graph: LGraph) {
|
||||
const { onConfigure } = graph
|
||||
graph.onConfigure = function (...args) {
|
||||
fixLinkInputSlots(this)
|
||||
// Set pending sync flag to suppress link rendering until slots are synced
|
||||
if (LiteGraph.vueNodesMode) {
|
||||
layoutStore.setPendingSlotSync(true)
|
||||
}
|
||||
|
||||
// Fire callbacks before the onConfigure, this is used by widget inputs to setup the config
|
||||
triggerCallbackOnAllNodes(this, 'onGraphConfigured')
|
||||
try {
|
||||
fixLinkInputSlots(this)
|
||||
|
||||
const r = onConfigure?.apply(this, args)
|
||||
// Fire callbacks before the onConfigure, this is used by widget inputs to setup the config
|
||||
triggerCallbackOnAllNodes(this, 'onGraphConfigured')
|
||||
|
||||
// Fire after onConfigure, used by primitives to generate widget using input nodes config
|
||||
triggerCallbackOnAllNodes(this, 'onAfterGraphConfigured')
|
||||
const r = onConfigure?.apply(this, args)
|
||||
|
||||
return r
|
||||
// Fire after onConfigure, used by primitives to generate widget using input nodes config
|
||||
triggerCallbackOnAllNodes(this, 'onAfterGraphConfigured')
|
||||
|
||||
return r
|
||||
} finally {
|
||||
// Flush pending slot layout syncs to fix link alignment after undo/redo
|
||||
// Using finally ensures links aren't permanently suppressed if an error occurs
|
||||
if (LiteGraph.vueNodesMode) {
|
||||
flushScheduledSlotLayoutSync()
|
||||
app.canvas?.setDirty(true, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user