Support renaming widgets (#6752)

![widget-rename_00002](https://github.com/user-attachments/assets/65205d3e-2c03-480d-916e-0dae89ddbdd9)

Widget labels are saved by serializing the value on inputs. This
requires minor changes to ensure widgets inputs are serialized when
required.

Currently only exposed by right clicking on widgets directly. Should
probably be added to the subgraph config panel in the future.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6752-Support-renaming-widgets-2b06d73d36508196bff2e511c6e7b89b)
by [Unito](https://www.unito.io)

---------

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
AustinMroz
2025-11-19 18:49:03 -08:00
committed by GitHub
parent d1f0211b61
commit a832141a45
7 changed files with 28 additions and 6 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 106 KiB

View File

@@ -835,6 +835,9 @@ export class LGraphNode
for (const w of this.widgets) {
if (!w) continue
const input = this.inputs.find((i) => i.widget?.name === w.name)
if (input?.label) w.label = input.label
if (
w.options?.property &&
this.properties[w.options.property] != undefined

View File

@@ -402,6 +402,7 @@
"Copy Image": "Copy Image",
"Save Image": "Save Image",
"Rename": "Rename",
"RenameWidget": "Rename Widget",
"Copy": "Copy",
"Duplicate": "Duplicate",
"Paste": "Paste",

View File

@@ -33,6 +33,7 @@ import { useToastStore } from '@/platform/updates/common/toastStore'
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
import type { NodeId } from '@/platform/workflow/validation/schemas/workflowSchema'
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
import { useDialogService } from '@/services/dialogService'
import { transformInputSpecV2ToV1 } from '@/schemas/nodeDef/migration'
import type {
ComfyNodeDef as ComfyNodeDefV2,
@@ -822,14 +823,31 @@ export const useLitegraphService = () => {
}
)
}
if (this.graph && !this.graph.isRootGraph) {
const [x, y] = canvas.graph_mouse
const overWidget = this.getWidgetOnPos(x, y, true)
if (overWidget) {
const [x, y] = canvas.graph_mouse
const overWidget = this.getWidgetOnPos(x, y, true)
if (overWidget) {
const input = this.inputs.find(
(inp) => inp.widget?.name === overWidget.name
)
if (input)
options.unshift({
content: `${t('contextMenu.RenameWidget')}: ${overWidget.label ?? overWidget.name}`,
callback: async () => {
const newLabel = await useDialogService().prompt({
title: t('g.rename'),
message: t('g.enterNewName') + ':',
defaultValue: overWidget.label ?? overWidget.name
})
if (!newLabel) return
overWidget.label = newLabel
input.label = newLabel
useCanvasStore().canvas?.setDirty(true)
}
})
if (this.graph && !this.graph.isRootGraph) {
addWidgetPromotionOptions(options, overWidget, this)
}
}
return []
}
}

View File

@@ -204,7 +204,7 @@ export function compressWidgetInputSlots(graph: ISerialisedGraph) {
}
function matchesLegacyApi(input: ISerialisableNodeInput) {
return !(input.widget && input.link === null)
return !(input.widget && input.link === null && !input.label)
}
/**