Merge pull request #67 from StableLlama/fix_64
release 2.2.1; Fix dynamic node inputs lost when loading workflows from images/videos
This commit is contained in:
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [2.2.1] - 2026-11-03
|
||||
|
||||
Fixed:
|
||||
- Dynamic input nodes (e.g. "create DICT"): clearing a key/value pair could
|
||||
leave the node with input names and widget names out of sync. The prompt was
|
||||
then built from the stale widget names, so the container was created empty
|
||||
and the connection was drawn next to the wrong row. Removed widgets are now
|
||||
also removed from ComfyUI's widget value store, which keeps both in sync.
|
||||
- Dynamic input nodes (e.g. "create DICT" and "create LIST") lost their extra
|
||||
key/value pairs when the workflow was recreated by dragging a produced image
|
||||
or video back into ComfyUI: the workflow that ComfyUI embeds into those files
|
||||
drops unconnected widget inputs, and for these nodes that slot is what keeps
|
||||
a pair alive, so the values ended up on the wrong rows and the container was
|
||||
created with only its first entry. The dynamic inputs are now kept in that
|
||||
embedded workflow, also for workflows that were saved before this fix.
|
||||
|
||||
## [2.2.0] - 2026-10-16
|
||||
|
||||
Added:
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "basic_data_handling"
|
||||
version = "2.2.0"
|
||||
version = "2.2.1"
|
||||
description = """Basic Python functions for manipulating data that every programmer is used to, lightweight with no additional dependencies.
|
||||
|
||||
Supported data types:
|
||||
|
||||
+24
-1
@@ -266,6 +266,11 @@ app.registerExtension({
|
||||
if (isWidgetFlag) {
|
||||
addStandardWidget.call(this, name, widgetGuiType, widgetDefaultVal, widgetConfOpts);
|
||||
this.addInput(name, comfyInputType, { shape, widget: { name } });
|
||||
// ComfyUI drops widget inputs that are not connected from the workflow it
|
||||
// embeds into saved images/videos (compressWidgetInputSlots) unless the slot
|
||||
// carries a label. For dynamic inputs the slot is what keeps the whole
|
||||
// key/value pair alive, so label it with its own name to survive the round trip.
|
||||
this.inputs[this.inputs.length - 1].label = name;
|
||||
} else {
|
||||
this.addInput(name, comfyInputType, { shape });
|
||||
}
|
||||
@@ -312,10 +317,12 @@ app.registerExtension({
|
||||
const widget = this.widgets.find(w => w.name === widgetName);
|
||||
if (widget) {
|
||||
widget.name = newName;
|
||||
if (widget.label) widget.label = newName;
|
||||
}
|
||||
if (inputRef.widget) inputRef.widget.name = newName;
|
||||
}
|
||||
inputRef.name = newName;
|
||||
if (inputRef.label) inputRef.label = newName;
|
||||
}
|
||||
updateSlotIndices(this);
|
||||
};
|
||||
@@ -500,7 +507,7 @@ app.registerExtension({
|
||||
this.setDirtyCanvas(true, true);
|
||||
};
|
||||
|
||||
// --- Event Handlers (onConnectionsChange, onConnectInput, onRemoved, onWidgetChanged) ---
|
||||
// --- Event Handlers (onConnectionsChange, onConnectInput, onConfigure, onRemoved, onWidgetChanged) ---
|
||||
const onConnectionsChange = nodeType.prototype.onConnectionsChange;
|
||||
nodeType.prototype.onConnectionsChange = function (type, slotIndex, isConnected, link, ioSlot) {
|
||||
const originalReturn = onConnectionsChange?.apply(this, arguments);
|
||||
@@ -532,6 +539,22 @@ app.registerExtension({
|
||||
return result;
|
||||
}
|
||||
|
||||
const onConfigure = nodeType.prototype.onConfigure;
|
||||
nodeType.prototype.onConfigure = function () {
|
||||
const originalReturn = onConfigure?.apply(this, arguments);
|
||||
// Inputs restored from a workflow may not carry the label yet, e.g. when the
|
||||
// workflow was saved before it was introduced. Without the label ComfyUI
|
||||
// drops the slot again when the workflow is embedded into an image/video, so
|
||||
// stamp it here for every dynamic widget input.
|
||||
for (const input of this.inputs ?? []) {
|
||||
if (!input.widget || input.label || !isDynamicInput(input.name)) continue;
|
||||
input.label = input.name;
|
||||
const widget = this.widgets?.find((w) => w.name === input.widget.name);
|
||||
if (widget && !widget.label) widget.label = input.name;
|
||||
}
|
||||
return originalReturn;
|
||||
};
|
||||
|
||||
const onRemoved = nodeType.prototype.onRemoved;
|
||||
nodeType.prototype.onRemoved = function () {
|
||||
if(!isProcessingConnection){
|
||||
|
||||
Reference in New Issue
Block a user