Skip to content

Commit

Permalink
Auto queue on change (comfyanonymous#2542)
Browse files Browse the repository at this point in the history
* Add toggle to enable auto queue when graph is changed

* type fix

* better

* better alignment

* Change undoredo to not ignore inputs when autoqueue in change mode
  • Loading branch information
pythongosssss authored and HorusElohim committed Feb 17, 2024
1 parent 1062467 commit eb52a33
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 11 deletions.
31 changes: 25 additions & 6 deletions web/extensions/core/undoRedo.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { app } from "../../scripts/app.js";
import { api } from "../../scripts/api.js"

const MAX_HISTORY = 50;

Expand All @@ -15,6 +16,7 @@ function checkState() {
}
activeState = clone(currentState);
redo.length = 0;
api.dispatchEvent(new CustomEvent("graphChanged", { detail: activeState }));
}
}

Expand Down Expand Up @@ -92,7 +94,7 @@ const undoRedo = async (e) => {
};

const bindInput = (activeEl) => {
if (activeEl?.tagName !== "CANVAS" && activeEl?.tagName !== "BODY") {
if (activeEl && activeEl.tagName !== "CANVAS" && activeEl.tagName !== "BODY") {
for (const evt of ["change", "input", "blur"]) {
if (`on${evt}` in activeEl) {
const listener = () => {
Expand All @@ -111,12 +113,16 @@ window.addEventListener(
"keydown",
(e) => {
requestAnimationFrame(async () => {
const activeEl = document.activeElement;
if (activeEl?.tagName === "INPUT" || activeEl?.type === "textarea") {
// Ignore events on inputs, they have their native history
return;
let activeEl;
// If we are auto queue in change mode then we do want to trigger on inputs
if (!app.ui.autoQueueEnabled || app.ui.autoQueueMode === "instant") {
activeEl = document.activeElement;
if (activeEl?.tagName === "INPUT" || activeEl?.type === "textarea") {
// Ignore events on inputs, they have their native history
return;
}
}

keyIgnored = e.key === "Control" || e.key === "Shift" || e.key === "Alt" || e.key === "Meta";
if (keyIgnored) return;

Expand All @@ -143,6 +149,11 @@ window.addEventListener("mouseup", () => {
checkState();
});

// Handle prompt queue event for dynamic widget changes
api.addEventListener("promptQueued", () => {
checkState();
});

// Handle litegraph clicks
const processMouseUp = LGraphCanvas.prototype.processMouseUp;
LGraphCanvas.prototype.processMouseUp = function (e) {
Expand All @@ -156,3 +167,11 @@ LGraphCanvas.prototype.processMouseDown = function (e) {
checkState();
return v;
};

// Handle litegraph context menu for COMBO widgets
const close = LiteGraph.ContextMenu.prototype.close;
LiteGraph.ContextMenu.prototype.close = function(e) {
const v = close.apply(this, arguments);
checkState();
return v;
}
1 change: 1 addition & 0 deletions web/scripts/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -2062,6 +2062,7 @@ export class ComfyApp {
} finally {
this.#processingQueue = false;
}
api.dispatchEvent(new CustomEvent("promptQueued", { detail: { number, batchCount } }));
}

/**
Expand Down
42 changes: 37 additions & 5 deletions web/scripts/ui.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { api } from "./api.js";
import { ComfyDialog as _ComfyDialog } from "./ui/dialog.js";
import { toggleSwitch } from "./ui/toggleSwitch.js";
import { ComfySettingsDialog } from "./ui/settings.js";

export const ComfyDialog = _ComfyDialog;
Expand Down Expand Up @@ -368,6 +369,31 @@ export class ComfyUI {
},
});

const autoQueueModeEl = toggleSwitch(
"autoQueueMode",
[
{ text: "instant", tooltip: "A new prompt will be queued as soon as the queue reaches 0" },
{ text: "change", tooltip: "A new prompt will be queued when the queue is at 0 and the graph is/has changed" },
],
{
onChange: (value) => {
this.autoQueueMode = value.item.value;
},
}
);
autoQueueModeEl.style.display = "none";

api.addEventListener("graphChanged", () => {
if (this.autoQueueMode === "change") {
if (this.lastQueueSize === 0) {
this.graphHasChanged = false;
app.queuePrompt(0, this.batchCount);
} else {
this.graphHasChanged = true;
}
}
});

this.menuContainer = $el("div.comfy-menu", {parent: document.body}, [
$el("div.drag-handle", {
style: {
Expand All @@ -394,6 +420,7 @@ export class ComfyUI {
document.getElementById("extraOptions").style.display = i.srcElement.checked ? "block" : "none";
this.batchCount = i.srcElement.checked ? document.getElementById("batchCountInputRange").value : 1;
document.getElementById("autoQueueCheckbox").checked = false;
this.autoQueueEnabled = false;
},
}),
]),
Expand Down Expand Up @@ -425,20 +452,22 @@ export class ComfyUI {
},
}),
]),

$el("div",[
$el("label",{
for:"autoQueueCheckbox",
innerHTML: "Auto Queue"
// textContent: "Auto Queue"
}),
$el("input", {
id: "autoQueueCheckbox",
type: "checkbox",
checked: false,
title: "Automatically queue prompt when the queue size hits 0",

onchange: (e) => {
this.autoQueueEnabled = e.target.checked;
autoQueueModeEl.style.display = this.autoQueueEnabled ? "" : "none";
}
}),
autoQueueModeEl
])
]),
$el("div.comfy-menu-btns", [
Expand Down Expand Up @@ -572,10 +601,13 @@ export class ComfyUI {
if (
this.lastQueueSize != 0 &&
status.exec_info.queue_remaining == 0 &&
document.getElementById("autoQueueCheckbox").checked &&
! app.lastExecutionError
this.autoQueueEnabled &&
(this.autoQueueMode === "instant" || this.graphHasChanged) &&
!app.lastExecutionError
) {
app.queuePrompt(0, this.batchCount);
status.exec_info.queue_remaining += this.batchCount;
this.graphHasChanged = false;
}
this.lastQueueSize = status.exec_info.queue_remaining;
}
Expand Down
60 changes: 60 additions & 0 deletions web/scripts/ui/toggleSwitch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { $el } from "../ui.js";

/**
* @typedef { { text: string, value?: string, tooltip?: string } } ToggleSwitchItem
*/
/**
* Creates a toggle switch element
* @param { string } name
* @param { Array<string | ToggleSwitchItem } items
* @param { Object } [opts]
* @param { (e: { item: ToggleSwitchItem, prev?: ToggleSwitchItem }) => void } [opts.onChange]
*/
export function toggleSwitch(name, items, { onChange } = {}) {
let selectedIndex;
let elements;

function updateSelected(index) {
if (selectedIndex != null) {
elements[selectedIndex].classList.remove("comfy-toggle-selected");
}
onChange?.({ item: items[index], prev: selectedIndex == null ? undefined : items[selectedIndex] });
selectedIndex = index;
elements[selectedIndex].classList.add("comfy-toggle-selected");
}

elements = items.map((item, i) => {
if (typeof item === "string") item = { text: item };
if (!item.value) item.value = item.text;

const toggle = $el(
"label",
{
textContent: item.text,
title: item.tooltip ?? "",
},
$el("input", {
name,
type: "radio",
value: item.value ?? item.text,
checked: item.selected,
onchange: () => {
updateSelected(i);
},
})
);
if (item.selected) {
updateSelected(i);
}
return toggle;
});

const container = $el("div.comfy-toggle-switch", elements);

if (selectedIndex == null) {
elements[0].children[0].checked = true;
updateSelected(0);
}

return container;
}
38 changes: 38 additions & 0 deletions web/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ body {
width: 100%;
}

.comfy-toggle-switch,
.comfy-btn,
.comfy-menu > button,
.comfy-menu-btns button,
Expand Down Expand Up @@ -434,6 +435,43 @@ dialog::backdrop {
margin-left: 5px;
}

.comfy-toggle-switch {
border-width: 2px;
display: flex;
background-color: var(--comfy-input-bg);
margin: 2px 0;
white-space: nowrap;
}

.comfy-toggle-switch label {
padding: 2px 0px 3px 6px;
flex: auto;
border-radius: 8px;
align-items: center;
display: flex;
justify-content: center;
}

.comfy-toggle-switch label:first-child {
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
}
.comfy-toggle-switch label:last-child {
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
}

.comfy-toggle-switch .comfy-toggle-selected {
background-color: var(--comfy-menu-bg);
}

#extraOptions {
padding: 4px;
background-color: var(--bg-color);
margin-bottom: 4px;
border-radius: 4px;
}

/* Search box */

.litegraph.litesearchbox {
Expand Down

0 comments on commit eb52a33

Please sign in to comment.