From 6491db6f685bc988befad66da421352539c11713 Mon Sep 17 00:00:00 2001 From: AustinMroz Date: Thu, 30 Oct 2025 18:06:10 -0700 Subject: [PATCH] Further subgraph improvements (#6466) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Prune disconnected widgets on config panel open - Fix breakage of DOMWidgets on double nest - Fix self clipping of proxied DOMWidget nodes - Blacklist cloning of promtoed widget prop ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6466-Further-subgraph-improvements-29c6d73d365081c8b63dda068486805c) by [Unito](https://www.unito.io) --- src/components/graph/widgets/DomWidget.vue | 4 ++-- src/core/graph/subgraph/SubgraphNode.vue | 2 ++ src/core/graph/subgraph/proxyWidget.ts | 7 +++++-- src/core/graph/subgraph/proxyWidgetUtils.ts | 11 +++++++++++ src/lib/litegraph/src/subgraph/SubgraphNode.ts | 1 + src/lib/litegraph/src/widgets/BaseWidget.ts | 1 + 6 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/components/graph/widgets/DomWidget.vue b/src/components/graph/widgets/DomWidget.vue index e28920018..f20aac370 100644 --- a/src/components/graph/widgets/DomWidget.vue +++ b/src/components/graph/widgets/DomWidget.vue @@ -143,8 +143,8 @@ onMounted(() => { widget.options.selectOn ?? ['focus', 'click'], () => { const lgCanvas = canvasStore.canvas - lgCanvas?.selectNode(widget.node) - lgCanvas?.bringToFront(widget.node) + lgCanvas?.selectNode(widgetState.widget.node) + lgCanvas?.bringToFront(widgetState.widget.node) } ) }) diff --git a/src/core/graph/subgraph/SubgraphNode.vue b/src/core/graph/subgraph/SubgraphNode.vue index 9c74eb13b..7be5246f2 100644 --- a/src/core/graph/subgraph/SubgraphNode.vue +++ b/src/core/graph/subgraph/SubgraphNode.vue @@ -17,6 +17,7 @@ import { matchesPropertyItem, matchesWidgetItem, promoteWidget, + pruneDisconnected, widgetItemToProperty } from '@/core/graph/subgraph/proxyWidgetUtils' import type { WidgetItem } from '@/core/graph/subgraph/proxyWidgetUtils' @@ -235,6 +236,7 @@ watchDebounced( ) onMounted(() => { setDraggableState() + if (activeNode.value) pruneDisconnected(activeNode.value) }) onBeforeUnmount(() => { draggableList.value?.dispose() diff --git a/src/core/graph/subgraph/proxyWidget.ts b/src/core/graph/subgraph/proxyWidget.ts index 5d54eb628..ef04bd76b 100644 --- a/src/core/graph/subgraph/proxyWidget.ts +++ b/src/core/graph/subgraph/proxyWidget.ts @@ -48,9 +48,12 @@ type Overlay = Partial & { * on the linked widget */ type ProxyWidget = IBaseWidget & { _overlay: Overlay } -function isProxyWidget(w: IBaseWidget): w is ProxyWidget { +export function isProxyWidget(w: IBaseWidget): w is ProxyWidget { return (w as { _overlay?: Overlay })?._overlay?.isProxyWidget ?? false } +export function isDisconnectedWidget(w: ProxyWidget) { + return w instanceof disconnectedWidget.constructor +} export function registerProxyWidgets(canvas: LGraphCanvas) { //NOTE: canvasStore hasn't been initialized yet @@ -167,7 +170,7 @@ function resolveLinkedWidget( if (!n) return [undefined, undefined] const widget = n.widgets?.find((w: IBaseWidget) => w.name === widgetName) //Slightly hacky. Force recursive resolution of nested widgets - if (widget instanceof disconnectedWidget.constructor && isProxyWidget(widget)) + if (widget && isProxyWidget(widget) && isDisconnectedWidget(widget)) widget.computedHeight = 20 return [n, widget] } diff --git a/src/core/graph/subgraph/proxyWidgetUtils.ts b/src/core/graph/subgraph/proxyWidgetUtils.ts index 4f1b20108..27961e54d 100644 --- a/src/core/graph/subgraph/proxyWidgetUtils.ts +++ b/src/core/graph/subgraph/proxyWidgetUtils.ts @@ -1,5 +1,9 @@ import { parseProxyWidgets } from '@/core/schemas/proxyWidget' import type { ProxyWidgetsProperty } from '@/core/schemas/proxyWidget' +import { + isProxyWidget, + isDisconnectedWidget +} from '@/core/graph/subgraph/proxyWidget' import { t } from '@/i18n' import type { IContextMenuValue, @@ -163,3 +167,10 @@ export function promoteRecommendedWidgets(subgraphNode: SubgraphNode) { subgraphNode.properties.proxyWidgets = proxyWidgets subgraphNode.computeSize(subgraphNode.size) } + +export function pruneDisconnected(subgraphNode: SubgraphNode) { + subgraphNode.properties.proxyWidgets = subgraphNode.widgets + .filter(isProxyWidget) + .filter((w) => !isDisconnectedWidget(w)) + .map((w) => [w._overlay.nodeId, w._overlay.widgetName]) +} diff --git a/src/lib/litegraph/src/subgraph/SubgraphNode.ts b/src/lib/litegraph/src/subgraph/SubgraphNode.ts index 08349dee0..cb0b10200 100644 --- a/src/lib/litegraph/src/subgraph/SubgraphNode.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphNode.ts @@ -546,6 +546,7 @@ export class SubgraphNode extends LGraphNode implements BaseLGraph { // Clean up all promoted widgets for (const widget of this.widgets) { + if ('isProxyWidget' in widget && widget.isProxyWidget) continue this.subgraph.events.dispatch('widget-demoted', { widget, subgraphNode: this diff --git a/src/lib/litegraph/src/widgets/BaseWidget.ts b/src/lib/litegraph/src/widgets/BaseWidget.ts index 966a6f486..b5fc11984 100644 --- a/src/lib/litegraph/src/widgets/BaseWidget.ts +++ b/src/lib/litegraph/src/widgets/BaseWidget.ts @@ -140,6 +140,7 @@ export abstract class BaseWidget displayValue, // @ts-expect-error Prevent naming conflicts with custom nodes. labelBaseline, + promoted, ...safeValues } = widget