From 92de66ccc0d1284d80ae2dbec50a392470165461 Mon Sep 17 00:00:00 2001 From: Comfy Org PR Bot Date: Tue, 16 Dec 2025 04:32:01 +0900 Subject: [PATCH] [backport core/1.34] fix: move selected groups when dragging nodes in vueNodes mode (#7505) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport of #7306 to `core/1.34` Automatically created by backport workflow. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7505-backport-core-1-34-fix-move-selected-groups-when-dragging-nodes-in-vueNodes-mode-2ca6d73d365081e2af2fd6a5e9599941) by [Unito](https://www.unito.io) Co-authored-by: Terry Jia --- .../extensions/vueNodes/layout/useNodeDrag.ts | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/renderer/extensions/vueNodes/layout/useNodeDrag.ts b/src/renderer/extensions/vueNodes/layout/useNodeDrag.ts index 235e8b9bb..fb6e86635 100644 --- a/src/renderer/extensions/vueNodes/layout/useNodeDrag.ts +++ b/src/renderer/extensions/vueNodes/layout/useNodeDrag.ts @@ -1,6 +1,7 @@ import { storeToRefs } from 'pinia' import { toValue } from 'vue' +import type { LGraphGroup } from '@/lib/litegraph/src/LGraphGroup' import { useCanvasStore } from '@/renderer/core/canvas/canvasStore' import { useLayoutMutations } from '@/renderer/core/layout/operations/layoutMutations' import { layoutStore } from '@/renderer/core/layout/store/layoutStore' @@ -13,13 +14,14 @@ import type { import { useNodeSnap } from '@/renderer/extensions/vueNodes/composables/useNodeSnap' import { useShiftKeySync } from '@/renderer/extensions/vueNodes/composables/useShiftKeySync' import { useTransformState } from '@/renderer/core/layout/transform/useTransformState' +import { isLGraphGroup } from '@/utils/litegraphUtil' import { createSharedComposable } from '@vueuse/core' export const useNodeDrag = createSharedComposable(useNodeDragIndividual) function useNodeDragIndividual() { const mutations = useLayoutMutations() - const { selectedNodeIds } = storeToRefs(useCanvasStore()) + const { selectedNodeIds, selectedItems } = storeToRefs(useCanvasStore()) // Get transform utilities from TransformPane if available const transformState = useTransformState() @@ -37,6 +39,10 @@ function useNodeDragIndividual() { let rafId: number | null = null let stopShiftSync: (() => void) | null = null + // For groups: track the last applied canvas delta to compute frame delta + let lastCanvasDelta: Point | null = null + let selectedGroups: LGraphGroup[] | null = null + function startDrag(event: PointerEvent, nodeId: NodeId) { const layout = toValue(layoutStore.getNodeLayoutRef(nodeId)) if (!layout) return @@ -67,6 +73,10 @@ function useNodeDragIndividual() { otherSelectedNodesStartPositions = null } + // Capture selected groups (filter from selectedItems which only contains selected items) + selectedGroups = toValue(selectedItems).filter(isLGraphGroup) + lastCanvasDelta = { x: 0, y: 0 } + mutations.setSource(LayoutSource.Vue) } @@ -127,6 +137,21 @@ function useNodeDragIndividual() { mutations.moveNode(otherNodeId, newOtherPosition) } } + + // Move selected groups using frame delta (difference from last frame) + // This matches LiteGraph's behavior which uses delta-based movement + if (selectedGroups && selectedGroups.length > 0 && lastCanvasDelta) { + const frameDelta = { + x: canvasDelta.x - lastCanvasDelta.x, + y: canvasDelta.y - lastCanvasDelta.y + } + + for (const group of selectedGroups) { + group.move(frameDelta.x, frameDelta.y, true) + } + } + + lastCanvasDelta = canvasDelta }) } @@ -195,6 +220,8 @@ function useNodeDragIndividual() { dragStartPos = null dragStartMouse = null otherSelectedNodesStartPositions = null + selectedGroups = null + lastCanvasDelta = null // Stop tracking shift key state stopShiftSync?.()