From f7b835e6a5b6277cc65dd0d0ce8676bf8c5ca7f8 Mon Sep 17 00:00:00 2001 From: Terry Jia Date: Tue, 10 Feb 2026 20:13:03 -0500 Subject: [PATCH] fix: disable control after generate during partial execution (#8774) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Passes an isPartialExecution flag through widget beforeQueued/afterQueued callbacks so control-after-generate widgets skip value modifications (randomize, increment, decrement) when the user queues selected output nodes via partial execution. requested by @christian-byrne in notion ## Screenshots (if applicable) before https://github.com/user-attachments/assets/3e723087-8849-457b-9f95-b8b5fceab0ed after https://github.com/user-attachments/assets/d9816667-51e0-4538-a012-9c84d0944019 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8774-fix-disable-control-after-generate-during-partial-execution-3036d73d365081688ca3d6b0506d69ca) by [Unito](https://www.unito.io) --- src/scripts/app.ts | 8 ++++++-- src/scripts/widgets.ts | 8 ++++---- src/types/litegraph-augmentation.d.ts | 4 ++-- src/utils/litegraphUtil.ts | 5 +++-- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/scripts/app.ts b/src/scripts/app.ts index e750d24adc..8b154fd878 100644 --- a/src/scripts/app.ts +++ b/src/scripts/app.ts @@ -1389,11 +1389,13 @@ export class ComfyApp { 'Comfy.Execution.PreviewMethod' ) + const isPartialExecution = !!queueNodeIds?.length for (let i = 0; i < batchCount; i++) { // Allow widgets to run callbacks before a prompt has been queued // e.g. random seed before every gen forEachNode(this.rootGraph, (node) => { - for (const widget of node.widgets ?? []) widget.beforeQueued?.() + for (const widget of node.widgets ?? []) + widget.beforeQueued?.({ isPartialExecution }) }) const p = await this.graphToPrompt(this.rootGraph) @@ -1449,7 +1451,9 @@ export class ComfyApp { // Allow widgets to run callbacks after a prompt has been queued // e.g. random seed after every gen - executeWidgetsCallback(queuedNodes, 'afterQueued') + executeWidgetsCallback(queuedNodes, 'afterQueued', { + isPartialExecution + }) this.canvas.draw(true, true) await this.ui.queue.update() } diff --git a/src/scripts/widgets.ts b/src/scripts/widgets.ts index e2c5d797d8..071ebff3ee 100644 --- a/src/scripts/widgets.ts +++ b/src/scripts/widgets.ts @@ -273,8 +273,8 @@ export function addValueControlWidgets( } } - valueControl.beforeQueued = () => { - if (controlValueRunBefore()) { + valueControl.beforeQueued = ({ isPartialExecution } = {}) => { + if (!isPartialExecution && controlValueRunBefore()) { // Don't run on first execution if (valueControl[HAS_EXECUTED]) { applyWidgetControl() @@ -283,8 +283,8 @@ export function addValueControlWidgets( valueControl[HAS_EXECUTED] = true } - valueControl.afterQueued = () => { - if (!controlValueRunBefore()) { + valueControl.afterQueued = ({ isPartialExecution } = {}) => { + if (!isPartialExecution && !controlValueRunBefore()) { applyWidgetControl() } } diff --git a/src/types/litegraph-augmentation.d.ts b/src/types/litegraph-augmentation.d.ts index 4912867c21..bdc71ce666 100644 --- a/src/types/litegraph-augmentation.d.ts +++ b/src/types/litegraph-augmentation.d.ts @@ -47,8 +47,8 @@ declare module '@/lib/litegraph/src/types/widgets' { interface IBaseWidget { onRemove?(): void - beforeQueued?(): unknown - afterQueued?(): unknown + beforeQueued?(options?: { isPartialExecution?: boolean }): unknown + afterQueued?(options?: { isPartialExecution?: boolean }): unknown serializeValue?(node: LGraphNode, index: number): Promise | unknown /** diff --git a/src/utils/litegraphUtil.ts b/src/utils/litegraphUtil.ts index c5f9d49fd9..0e96416fca 100644 --- a/src/utils/litegraphUtil.ts +++ b/src/utils/litegraphUtil.ts @@ -83,11 +83,12 @@ export const getItemsColorOption = (items: unknown[]): ColorOption | null => { export function executeWidgetsCallback( nodes: LGraphNode[], - callbackName: 'onRemove' | 'beforeQueued' | 'afterQueued' + callbackName: 'onRemove' | 'beforeQueued' | 'afterQueued', + options?: { isPartialExecution?: boolean } ) { for (const node of nodes) { for (const widget of node.widgets ?? []) { - widget[callbackName]?.() + widget[callbackName]?.(options) } } }