From c87c1bf4ffcd005b8f725b8c1a44d2f150fa4085 Mon Sep 17 00:00:00 2001 From: bymyself Date: Mon, 11 Aug 2025 10:19:37 -0700 Subject: [PATCH] [bugfix] Fix multiple links creating separate slots on SubgraphOutputNode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When dropping multiple links from a legacy reroute onto a SubgraphOutputNode, each link was creating a new slot instead of connecting to the same slot. This fix tracks the created slot and reuses it for subsequent connections when they have the same type, mimicking the behavior of normal nodes. Links with different types will still create separate slots as expected. Fixes #4850 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- src/lib/litegraph/src/canvas/LinkConnector.ts | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/lib/litegraph/src/canvas/LinkConnector.ts b/src/lib/litegraph/src/canvas/LinkConnector.ts index 8dea4c7a0e..ea57a3a6f9 100644 --- a/src/lib/litegraph/src/canvas/LinkConnector.ts +++ b/src/lib/litegraph/src/canvas/LinkConnector.ts @@ -17,6 +17,8 @@ import type { INodeInputSlot, INodeOutputSlot } from '@/lib/litegraph/src/interfaces' +import { EmptySubgraphInput } from '@/lib/litegraph/src/subgraph/EmptySubgraphInput' +import { EmptySubgraphOutput } from '@/lib/litegraph/src/subgraph/EmptySubgraphOutput' import { Subgraph } from '@/lib/litegraph/src/subgraph/Subgraph' import type { SubgraphInput } from '@/lib/litegraph/src/subgraph/SubgraphInput' import { SubgraphInputNode } from '@/lib/litegraph/src/subgraph/SubgraphInputNode' @@ -640,8 +642,27 @@ export class LinkConnector { const output = ioNode.getSlotInPosition(canvasX, canvasY) if (!output) throw new Error('No output slot found for link.') + // Track the actual slot to use for all connections + let targetSlot = output + for (const link of renderLinks) { - link.connectToSubgraphOutput(output, this.events) + link.connectToSubgraphOutput(targetSlot, this.events) + + // If we just connected to an EmptySubgraphOutput, check if we should reuse the slot + if (output instanceof EmptySubgraphOutput && ioNode.slots.length > 0) { + // Get the last created slot (newest one) + const createdSlot = ioNode.slots[ioNode.slots.length - 1] + + // Only reuse the slot if the next link's type would be compatible + // Otherwise, keep using EmptySubgraphOutput to create a new slot + const nextLink = renderLinks[renderLinks.indexOf(link) + 1] + if (nextLink && link.fromSlot.type === nextLink.fromSlot.type) { + targetSlot = createdSlot + } else { + // Reset to EmptySubgraphOutput for different types + targetSlot = output + } + } } } else if ( connectingTo === 'output' && @@ -650,8 +671,27 @@ export class LinkConnector { const input = ioNode.getSlotInPosition(canvasX, canvasY) if (!input) throw new Error('No input slot found for link.') + // Same logic for SubgraphInputNode if needed + let targetSlot = input + for (const link of renderLinks) { - link.connectToSubgraphInput(input, this.events) + link.connectToSubgraphInput(targetSlot, this.events) + + // If we just connected to an EmptySubgraphInput, check if we should reuse the slot + if (input instanceof EmptySubgraphInput && ioNode.slots.length > 0) { + // Get the last created slot (newest one) + const createdSlot = ioNode.slots[ioNode.slots.length - 1] + + // Only reuse the slot if the next link's type would be compatible + // Otherwise, keep using EmptySubgraphInput to create a new slot + const nextLink = renderLinks[renderLinks.indexOf(link) + 1] + if (nextLink && link.fromSlot.type === nextLink.fromSlot.type) { + targetSlot = createdSlot + } else { + // Reset to EmptySubgraphInput for different types + targetSlot = input + } + } } } else { console.error(