mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-24 14:45:36 +00:00
fix: resync slot layouts when switching between app mode and graph mode (#10273)
## Summary Fix broken link rendering (noodles disappearing or going to wrong positions) when switching between app mode and graph mode tabs. ## Changes - **What**: When the graph canvas is hidden via `display: none` in app mode, slot elements lose valid DOM measurements. On switching back, links rendered at stale coordinates or disappeared. This PR rekeys `LGraphNode` components by workflow path, adds measurability guards to skip hidden slots, clears stale layouts, and watches `linearMode` to trigger a full slot layout resync on mode transitions. ## Review Focus - The `isSlotElementMeasurable` guard skips elements that are disconnected or have zero-size rects — verify this doesn't inadvertently skip slots during normal graph rendering. - The `linearMode` watcher clears all slot layouts when entering app mode and requests a full resync when leaving — confirm no flicker or race with the RAF-based sync scheduler. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-10273-fix-resync-slot-layouts-when-switching-between-app-mode-and-graph-mode-3276d73d3650812f9366dae53c7b2d37) by [Unito](https://www.unito.io) --------- Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -164,9 +164,11 @@ import { useWorkflowAutoSave } from '@/platform/workflow/persistence/composables
|
||||
import { useWorkflowPersistenceV2 as useWorkflowPersistence } from '@/platform/workflow/persistence/composables/useWorkflowPersistenceV2'
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
import { useCanvasInteractions } from '@/renderer/core/canvas/useCanvasInteractions'
|
||||
import { layoutStore } from '@/renderer/core/layout/store/layoutStore'
|
||||
import TransformPane from '@/renderer/core/layout/transform/TransformPane.vue'
|
||||
import MiniMap from '@/renderer/extensions/minimap/MiniMap.vue'
|
||||
import LGraphNode from '@/renderer/extensions/vueNodes/components/LGraphNode.vue'
|
||||
import { requestSlotLayoutSyncForAllNodes } from '@/renderer/extensions/vueNodes/composables/useSlotElementTracking'
|
||||
import { UnauthorizedError } from '@/scripts/api'
|
||||
import { app as comfyApp } from '@/scripts/app'
|
||||
import { ChangeTracker } from '@/scripts/changeTracker'
|
||||
@@ -207,6 +209,7 @@ const workspaceStore = useWorkspaceStore()
|
||||
const { isBuilderMode } = useAppMode()
|
||||
const canvasStore = useCanvasStore()
|
||||
const workflowStore = useWorkflowStore()
|
||||
const { linearMode } = storeToRefs(canvasStore)
|
||||
const executionStore = useExecutionStore()
|
||||
const executionErrorStore = useExecutionErrorStore()
|
||||
const toastStore = useToastStore()
|
||||
@@ -279,6 +282,22 @@ watch(
|
||||
const allNodes = computed((): VueNodeData[] =>
|
||||
Array.from(vueNodeLifecycle.nodeManager.value?.vueNodeData?.values() ?? [])
|
||||
)
|
||||
watch(
|
||||
() => linearMode.value,
|
||||
(isLinearMode) => {
|
||||
if (!shouldRenderVueNodes.value) return
|
||||
|
||||
if (isLinearMode) {
|
||||
layoutStore.clearAllSlotLayouts()
|
||||
} else {
|
||||
// App mode hides the graph canvas with `display: none`, so slot connectors
|
||||
// need a fresh DOM measurement pass before links can render correctly.
|
||||
requestSlotLayoutSyncForAllNodes()
|
||||
}
|
||||
|
||||
layoutStore.setPendingSlotSync(true)
|
||||
}
|
||||
)
|
||||
|
||||
function onLinkOverlayReady(el: HTMLCanvasElement) {
|
||||
if (!canvasStore.canvas) return
|
||||
|
||||
Reference in New Issue
Block a user