fix bypass hotkey in vue nodes and fix node data instrumentation setup issue when switching to Vue nodes after initial load (#5715)

## Summary

Fixed Vue node keybinding target element ID to enable
bypass/pin/collapse hotkeys in both LiteGraph and Vue rendering modes.

Also fixed a bug when starting in litegraph mode => switching to Vue
nodes without reloading => `graph.onTrigger` is set to `undefined` which
interferes with proper setup of node data instrumentation, among other
things.

## Changes

- **What**: Updated keybinding `targetElementId` from `graph-canvas` to
`graph-canvas-container` for node manipulation commands (parent of both
the canvas and transform pane -- vue nodes container).
- **What**: Added conditional `onTrigger` handler restoration in slot
layout sync to prevent Vue node manager conflicts

## Review Focus

Event handler precedence between Vue nodes and LiteGraph systems during
mode switching, ensuring hotkeys work consistently across rendering
modes.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5715-fix-bypass-hotkey-in-vue-nodes-and-fix-node-data-instrumentation-setup-issue-when-switchi-2756d73d3650815c8ec8d5e4d06232e3)
by [Unito](https://www.unito.io)
This commit is contained in:
Christian Byrne
2025-09-21 17:32:12 -07:00
committed by GitHub
parent 023e466dba
commit f951e07cea
5 changed files with 64 additions and 8 deletions

View File

@@ -0,0 +1,49 @@
import {
comfyExpect as expect,
comfyPageFixture as test
} from '../../../fixtures/ComfyPage'
const BYPASS_HOTKEY = 'Control+b'
const BYPASS_CLASS = /before:bg-bypass\/60/
test.describe('Vue Node Bypass', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test('should allow toggling bypass on a selected node with hotkey', async ({
comfyPage
}) => {
const checkpointNode = comfyPage.page.locator('[data-node-id]').filter({
hasText: 'Load Checkpoint'
})
await checkpointNode.getByText('Load Checkpoint').click()
await comfyPage.page.keyboard.press(BYPASS_HOTKEY)
await expect(checkpointNode).toHaveClass(BYPASS_CLASS)
await comfyPage.page.keyboard.press(BYPASS_HOTKEY)
await expect(checkpointNode).not.toHaveClass(BYPASS_CLASS)
})
test('should allow toggling bypass on multiple selected nodes with hotkey', async ({
comfyPage
}) => {
const checkpointNode = comfyPage.page.locator('[data-node-id]').filter({
hasText: 'Load Checkpoint'
})
const ksamplerNode = comfyPage.page.locator('[data-node-id]').filter({
hasText: 'KSampler'
})
await checkpointNode.getByText('Load Checkpoint').click()
await ksamplerNode.getByText('KSampler').click({ modifiers: ['Control'] })
await comfyPage.page.keyboard.press(BYPASS_HOTKEY)
await expect(checkpointNode).toHaveClass(BYPASS_CLASS)
await expect(ksamplerNode).toHaveClass(BYPASS_CLASS)
await comfyPage.page.keyboard.press(BYPASS_HOTKEY)
await expect(checkpointNode).not.toHaveClass(BYPASS_CLASS)
await expect(ksamplerNode).not.toHaveClass(BYPASS_CLASS)
})
})

View File

@@ -122,14 +122,14 @@ export const CORE_KEYBINDINGS: Keybinding[] = [
key: '.'
},
commandId: 'Comfy.Canvas.FitView',
targetElementId: 'graph-canvas'
targetElementId: 'graph-canvas-container'
},
{
combo: {
key: 'p'
},
commandId: 'Comfy.Canvas.ToggleSelected.Pin',
targetElementId: 'graph-canvas'
targetElementId: 'graph-canvas-container'
},
{
combo: {
@@ -137,7 +137,7 @@ export const CORE_KEYBINDINGS: Keybinding[] = [
alt: true
},
commandId: 'Comfy.Canvas.ToggleSelectedNodes.Collapse',
targetElementId: 'graph-canvas'
targetElementId: 'graph-canvas-container'
},
{
combo: {
@@ -145,7 +145,7 @@ export const CORE_KEYBINDINGS: Keybinding[] = [
ctrl: true
},
commandId: 'Comfy.Canvas.ToggleSelectedNodes.Bypass',
targetElementId: 'graph-canvas'
targetElementId: 'graph-canvas-container'
},
{
combo: {
@@ -153,7 +153,7 @@ export const CORE_KEYBINDINGS: Keybinding[] = [
ctrl: true
},
commandId: 'Comfy.Canvas.ToggleSelectedNodes.Mute',
targetElementId: 'graph-canvas'
targetElementId: 'graph-canvas-container'
},
{
combo: {

View File

@@ -595,7 +595,7 @@ export const CORE_SETTINGS: SettingParams[] = [
migrateDeprecatedValue: (value: any[]) => {
return value.map((keybinding) => {
if (keybinding['targetSelector'] === '#graph-canvas') {
keybinding['targetElementId'] = 'graph-canvas'
keybinding['targetElementId'] = 'graph-canvas-container'
}
return keybinding
})

View File

@@ -134,7 +134,11 @@ export function useSlotLayoutSync() {
restoreHandlers = () => {
graph.onNodeAdded = origNodeAdded || undefined
graph.onNodeRemoved = origNodeRemoved || undefined
graph.onTrigger = origTrigger || undefined
// Only restore onTrigger if Vue nodes are not active
// Vue node manager sets its own onTrigger handler
if (!LiteGraph.vueNodesMode) {
graph.onTrigger = origTrigger || undefined
}
graph.onAfterChange = origAfterChange || undefined
}

View File

@@ -596,7 +596,10 @@ export class ComfyApp {
const keybindingStore = useKeybindingStore()
const keybinding = keybindingStore.getKeybinding(keyCombo)
if (keybinding && keybinding.targetElementId === 'graph-canvas') {
if (
keybinding &&
keybinding.targetElementId === 'graph-canvas-container'
) {
useCommandStore().execute(keybinding.commandId)
this.graph.change()