From 023e466dba3cd0f64fcaad75bcb54542411d2576 Mon Sep 17 00:00:00 2001 From: Christian Byrne Date: Sun, 21 Sep 2025 14:39:40 -0700 Subject: [PATCH] fix using shift modifier to (de-)select Vue nodes (#5714) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fixes https://github.com/Comfy-Org/ComfyUI_frontend/issues/5688 by adding shift modifier support for multi-selecting Vue nodes, enabling standard shift+click selection behavior alongside existing ctrl/cmd+click. ## Changes - **What**: Updated Vue node event handlers to include `event.shiftKey` in multi-select logic - **Testing**: Added browser tests for both ctrl and shift modifier selection behaviors ## Review Focus Multi-select behavior consistency across different input modifiers and platform compatibility (Windows/Mac/Linux shift key handling). ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-5714-fix-using-shift-modifier-to-de-select-Vue-nodes-2756d73d365081bcb5e0fe80eacdb2f0) by [Unito](https://www.unito.io) --- .../nodeInteractions/selectionState.spec.ts | 47 +++++++++++++++++++ .../composables/useNodeEventHandlers.ts | 2 +- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 browser_tests/tests/vueNodes/nodeInteractions/selectionState.spec.ts diff --git a/browser_tests/tests/vueNodes/nodeInteractions/selectionState.spec.ts b/browser_tests/tests/vueNodes/nodeInteractions/selectionState.spec.ts new file mode 100644 index 000000000..ff8b6f951 --- /dev/null +++ b/browser_tests/tests/vueNodes/nodeInteractions/selectionState.spec.ts @@ -0,0 +1,47 @@ +import { + comfyExpect as expect, + comfyPageFixture as test +} from '../../../fixtures/ComfyPage' + +test.describe('Vue Node Selection', () => { + test.beforeEach(async ({ comfyPage }) => { + await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.vueNodes.waitForNodes() + }) + + const modifiers = [ + { key: 'Control', name: 'ctrl' }, + { key: 'Shift', name: 'shift' } + ] as const + + for (const { key: modifier, name } of modifiers) { + test(`should allow selecting multiple nodes with ${name}+click`, async ({ + comfyPage + }) => { + await comfyPage.page.getByText('Load Checkpoint').click() + expect(await comfyPage.vueNodes.getSelectedNodeCount()).toBe(1) + + await comfyPage.page.getByText('Empty Latent Image').click({ + modifiers: [modifier] + }) + expect(await comfyPage.vueNodes.getSelectedNodeCount()).toBe(2) + + await comfyPage.page.getByText('KSampler').click({ + modifiers: [modifier] + }) + expect(await comfyPage.vueNodes.getSelectedNodeCount()).toBe(3) + }) + + test(`should allow de-selecting nodes with ${name}+click`, async ({ + comfyPage + }) => { + await comfyPage.page.getByText('Load Checkpoint').click() + expect(await comfyPage.vueNodes.getSelectedNodeCount()).toBe(1) + + await comfyPage.page.getByText('Load Checkpoint').click({ + modifiers: [modifier] + }) + expect(await comfyPage.vueNodes.getSelectedNodeCount()).toBe(0) + }) + } +}) diff --git a/src/renderer/extensions/vueNodes/composables/useNodeEventHandlers.ts b/src/renderer/extensions/vueNodes/composables/useNodeEventHandlers.ts index 8ed854a0c..e3ab1c66c 100644 --- a/src/renderer/extensions/vueNodes/composables/useNodeEventHandlers.ts +++ b/src/renderer/extensions/vueNodes/composables/useNodeEventHandlers.ts @@ -38,7 +38,7 @@ function useNodeEventHandlersIndividual() { const node = nodeManager.value.getNode(nodeData.id) if (!node) return - const isMultiSelect = event.ctrlKey || event.metaKey + const isMultiSelect = event.ctrlKey || event.metaKey || event.shiftKey if (isMultiSelect) { // Ctrl/Cmd+click -> toggle selection