Skip to content

Commit dfe0988

Browse files
[fix] Prevent drag activation during Vue node resize (#7064)
## Summary - Add isResizingVueNodes flag to layoutStore - Set flag in useNodeResize during resize operation - Check flag in useNodePointerInteractions to skip drag activation Fixes a bug where resizing a Vue node after selecting it would incorrectly trigger drag logic, causing the node to teleport. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7064-fix-Prevent-drag-activation-during-Vue-node-resize-2bb6d73d365081a2ad0ad4c7be76afee) by [Unito](https://www.unito.io) --------- Co-authored-by: DrJKL <[email protected]>
1 parent d76c59c commit dfe0988

File tree

5 files changed

+65
-0
lines changed

5 files changed

+65
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import {
2+
comfyExpect as expect,
3+
comfyPageFixture as test
4+
} from '../../../../fixtures/ComfyPage'
5+
6+
test.describe('Vue Node Resizing', () => {
7+
test.beforeEach(async ({ comfyPage }) => {
8+
await comfyPage.setSetting('Comfy.VueNodes.Enabled', true)
9+
await comfyPage.vueNodes.waitForNodes()
10+
})
11+
12+
test('should resize node without position drift after selecting', async ({
13+
comfyPage
14+
}) => {
15+
// Get a Vue node fixture
16+
const node = await comfyPage.vueNodes.getFixtureByTitle('Load Checkpoint')
17+
const initialBox = await node.boundingBox()
18+
if (!initialBox) throw new Error('Node bounding box not found')
19+
20+
// Select the node first (this was causing the bug)
21+
await node.header.click()
22+
await comfyPage.page.waitForTimeout(100) // Brief pause after selection
23+
24+
// Get position after selection
25+
const selectedBox = await node.boundingBox()
26+
if (!selectedBox)
27+
throw new Error('Node bounding box not found after select')
28+
29+
// Verify position unchanged after selection
30+
expect(selectedBox.x).toBeCloseTo(initialBox.x, 1)
31+
expect(selectedBox.y).toBeCloseTo(initialBox.y, 1)
32+
33+
// Now resize from bottom-right corner
34+
const resizeStartX = selectedBox.x + selectedBox.width - 5
35+
const resizeStartY = selectedBox.y + selectedBox.height - 5
36+
37+
await comfyPage.page.mouse.move(resizeStartX, resizeStartY)
38+
await comfyPage.page.mouse.down()
39+
await comfyPage.page.mouse.move(resizeStartX + 50, resizeStartY + 30)
40+
await comfyPage.page.mouse.up()
41+
42+
// Get final position and size
43+
const finalBox = await node.boundingBox()
44+
if (!finalBox) throw new Error('Node bounding box not found after resize')
45+
46+
// Position should NOT have changed (the bug was position drift)
47+
expect(finalBox.x).toBeCloseTo(initialBox.x, 1)
48+
expect(finalBox.y).toBeCloseTo(initialBox.y, 1)
49+
50+
// Size should have increased
51+
expect(finalBox.width).toBeGreaterThan(initialBox.width)
52+
expect(finalBox.height).toBeGreaterThan(initialBox.height)
53+
})
54+
})

src/renderer/core/layout/store/layoutStore.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ class LayoutStoreImpl implements LayoutStore {
138138

139139
// Vue dragging state for selection toolbox (public ref for direct mutation)
140140
public isDraggingVueNodes = ref(false)
141+
// Vue resizing state to prevent drag from activating during resize
142+
public isResizingVueNodes = ref(false)
141143

142144
constructor() {
143145
// Initialize Yjs data structures

src/renderer/extensions/vueNodes/composables/useNodePointerInteractions.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,12 +92,14 @@ const mockData = vi.hoisted(() => {
9292

9393
vi.mock('@/renderer/core/layout/store/layoutStore', () => {
9494
const isDraggingVueNodes = ref(false)
95+
const isResizingVueNodes = ref(false)
9596
const fakeNodeLayoutRef = ref(mockData.fakeNodeLayout)
9697
const getNodeLayoutRef = vi.fn(() => fakeNodeLayoutRef)
9798
const setSource = vi.fn()
9899
return {
99100
layoutStore: {
100101
isDraggingVueNodes,
102+
isResizingVueNodes,
101103
getNodeLayoutRef,
102104
setSource
103105
}

src/renderer/extensions/vueNodes/composables/useNodePointerInteractions.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ export function useNodePointerInteractions(
6363
function onPointermove(event: PointerEvent) {
6464
if (forwardMiddlePointerIfNeeded(event)) return
6565

66+
// Don't activate drag while resizing
67+
if (layoutStore.isResizingVueNodes.value) return
68+
6669
const nodeId = toValue(nodeIdRef)
6770

6871
if (nodeManager.value?.getNode(nodeId)?.flags?.pinned) {

src/renderer/extensions/vueNodes/interactions/resize/useNodeResize.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { useEventListener } from '@vueuse/core'
22
import { ref } from 'vue'
33

44
import type { Point, Size } from '@/renderer/core/layout/types'
5+
import { layoutStore } from '@/renderer/core/layout/store/layoutStore'
56
import { useNodeSnap } from '@/renderer/extensions/vueNodes/composables/useNodeSnap'
67
import { useShiftKeySync } from '@/renderer/extensions/vueNodes/composables/useShiftKeySync'
78
import { useTransformState } from '@/renderer/core/layout/transform/useTransformState'
@@ -55,6 +56,8 @@ export function useNodeResize(
5556
// Capture pointer to ensure we get all move/up events
5657
target.setPointerCapture(event.pointerId)
5758

59+
// Mark as resizing to prevent drag from activating
60+
layoutStore.isResizingVueNodes.value = true
5861
isResizing.value = true
5962
resizeStartPointer.value = { x: event.clientX, y: event.clientY }
6063
resizeStartSize.value = startSize
@@ -93,6 +96,7 @@ export function useNodeResize(
9396
const handlePointerUp = (upEvent: PointerEvent) => {
9497
if (isResizing.value) {
9598
isResizing.value = false
99+
layoutStore.isResizingVueNodes.value = false
96100
resizeStartPointer.value = null
97101
resizeStartSize.value = null
98102

0 commit comments

Comments
 (0)