remove event forwarding hack. todo: add link moving in vue

This commit is contained in:
bymyself
2025-09-04 19:19:13 -07:00
parent e8dae57a6a
commit f6051f6634
5 changed files with 2 additions and 256 deletions

View File

@@ -1,186 +0,0 @@
import { useCanvasStore } from '@/stores/graphStore'
import type { LGraphCanvas } from '../../lib/litegraph/src/litegraph'
export function useEventForwarding() {
const canvasStore = useCanvasStore()
// Track active drag operation
let isDragging = false
let dragCleanup: (() => void) | null = null
// Store last known position for escape key handling
const lastPointerPosition = { x: 0, y: 0 }
function createSyntheticPointerEvent(
originalEvent: PointerEvent,
eventType: string
): PointerEvent {
// Only copy properties that LiteGraph actually uses
return new PointerEvent(eventType, {
bubbles: true,
cancelable: true,
view: window,
// Position properties
clientX: originalEvent.clientX,
clientY: originalEvent.clientY,
// Modifier keys
ctrlKey: originalEvent.ctrlKey,
shiftKey: originalEvent.shiftKey,
altKey: originalEvent.altKey,
metaKey: originalEvent.metaKey,
// Button state
button: originalEvent.button,
buttons: originalEvent.buttons,
// Pointer tracking
pointerId: originalEvent.pointerId,
isPrimary: originalEvent.isPrimary,
pointerType: originalEvent.pointerType
})
}
function forwardPointerEvent(
originalEvent: PointerEvent,
eventType: 'down' | 'move' | 'up'
) {
const canvas: LGraphCanvas | null = canvasStore.getCanvas()
if (!canvas) {
console.warn('No canvas available for event forwarding')
return
}
// Prevent original event from bubbling to canvas
originalEvent.stopPropagation()
originalEvent.preventDefault()
// Create synthetic event
const syntheticEvent = createSyntheticPointerEvent(
originalEvent,
`pointer${eventType}`
)
// Create a mutable copy of the event for LiteGraph to modify
const mutableEvent = syntheticEvent as PointerEvent & {
canvasX?: number
canvasY?: number
deltaX?: number
deltaY?: number
safeOffsetX?: number
safeOffsetY?: number
}
// Let LiteGraph adjust coordinates to graph space
// Using 'as any' to bypass TypeScript assertion limitations
;(canvas.adjustMouseEvent as any)(mutableEvent)
// Forward to appropriate handler
switch (eventType) {
case 'down':
canvas.processMouseDown(mutableEvent)
break
case 'move':
canvas.processMouseMove(mutableEvent)
break
case 'up':
canvas.processMouseUp(mutableEvent)
break
}
}
// Pre-create event handlers to avoid recreating on each pointerdown
const handlePointerMove = (e: PointerEvent) => {
if (!isDragging) return
// Update last known position
lastPointerPosition.x = e.clientX
lastPointerPosition.y = e.clientY
forwardPointerEvent(e, 'move')
}
const handlePointerUp = (e: PointerEvent) => {
if (!isDragging) return
isDragging = false
forwardPointerEvent(e, 'up')
// Clean up listeners
if (dragCleanup) {
dragCleanup()
dragCleanup = null
}
}
const handleKeyDown = (e: KeyboardEvent) => {
// Handle escape key to cancel drag
if (e.key === 'Escape' && isDragging) {
isDragging = false
// Create minimal synthetic cancel event
const cancelEvent = new PointerEvent('pointerup', {
bubbles: true,
cancelable: true,
view: window,
// Use last known position from the current drag operation
clientX: lastPointerPosition.x,
clientY: lastPointerPosition.y,
button: 0,
buttons: 0
})
const canvas: LGraphCanvas | null = canvasStore.getCanvas()
if (canvas) {
const mutableCancelEvent = cancelEvent as PointerEvent & {
canvasX?: number
canvasY?: number
deltaX?: number
deltaY?: number
safeOffsetX?: number
safeOffsetY?: number
}
;(canvas.adjustMouseEvent as any)(mutableCancelEvent)
canvas.processMouseUp(mutableCancelEvent)
}
// Clean up
if (dragCleanup) {
dragCleanup()
dragCleanup = null
}
}
}
function handleSlotPointerDown(originalEvent: PointerEvent) {
// Forward the initial pointer down
forwardPointerEvent(originalEvent, 'down')
// Set up drag handling
isDragging = true
// Initialize last known position
lastPointerPosition.x = originalEvent.clientX
lastPointerPosition.y = originalEvent.clientY
// Add global listeners for drag handling
document.addEventListener('pointermove', handlePointerMove, true)
document.addEventListener('pointerup', handlePointerUp, true)
document.addEventListener('keydown', handleKeyDown, true)
// Store cleanup function
dragCleanup = () => {
document.removeEventListener('pointermove', handlePointerMove, true)
document.removeEventListener('pointerup', handlePointerUp, true)
document.removeEventListener('keydown', handleKeyDown, true)
}
}
// Cleanup on unmount
function cleanup() {
isDragging = false
if (dragCleanup) {
dragCleanup()
dragCleanup = null
}
}
return {
handleSlotPointerDown,
cleanup
}
}

View File

@@ -13,7 +13,6 @@
:style="{
height: slotHeight + 'px'
}"
@pointerdown="handleClick"
>
<!-- Connection Dot -->
<SlotConnectionDot
@@ -63,10 +62,6 @@ interface InputSlotProps {
const props = defineProps<InputSlotProps>()
const emit = defineEmits<{
'slot-click': [event: PointerEvent]
}>()
// Error boundary implementation
const renderError = ref<string | null>(null)
const { toastErrorHandler } = useErrorHandling()
@@ -83,13 +78,6 @@ const slotColor = computed(() => getSlotColor(props.slotData.type))
// Get slot height from litegraph constants
const slotHeight = COMFY_VUE_NODE_DIMENSIONS.components.SLOT_HEIGHT
// Handle click events
const handleClick = (event: PointerEvent) => {
if (!props.readonly) {
emit('slot-click', event)
}
}
const transformState = inject<TransformState | undefined>(
'transformState',
undefined

View File

@@ -12,9 +12,6 @@
:node-id="nodeInfo?.id != null ? String(nodeInfo.id) : ''"
:index="getActualInputIndex(input, index)"
:readonly="readonly"
@slot-click="
handleInputSlotClick(getActualInputIndex(input, index), $event)
"
/>
</div>
@@ -26,16 +23,14 @@
:node-id="nodeInfo?.id != null ? String(nodeInfo.id) : ''"
:index="index"
:readonly="readonly"
@slot-click="handleOutputSlotClick(index, $event)"
/>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, onErrorCaptured, onUnmounted, ref } from 'vue'
import { computed, onErrorCaptured, ref } from 'vue'
import { useEventForwarding } from '@/composables/graph/useEventForwarding'
import type { VueNodeData } from '@/composables/graph/useGraphNodeManager'
import { useErrorHandling } from '@/composables/useErrorHandling'
import type { INodeSlot, LGraphNode } from '@/lib/litegraph/src/litegraph'
@@ -107,26 +102,6 @@ const getActualInputIndex = (
return actualIndex !== -1 ? actualIndex : filteredIndex
}
// Set up event forwarding for slot interactions
const { handleSlotPointerDown, cleanup } = useEventForwarding()
// Handle input slot click
const handleInputSlotClick = (_index: number, event: PointerEvent) => {
// Forward the event to LiteGraph for native slot handling
handleSlotPointerDown(event)
}
// Handle output slot click
const handleOutputSlotClick = (_index: number, event: PointerEvent) => {
// Forward the event to LiteGraph for native slot handling
handleSlotPointerDown(event)
}
// Clean up event listeners on unmount
onUnmounted(() => {
cleanup()
})
// Error boundary implementation
const renderError = ref<string | null>(null)
const { toastErrorHandler } = useErrorHandling()

View File

@@ -23,7 +23,6 @@
:index="getWidgetInputIndex(widget)"
:readonly="readonly"
:dot-only="true"
@slot-click="handleWidgetSlotClick($event, widget)"
/>
</div>
<!-- Widget Component -->
@@ -40,9 +39,8 @@
</template>
<script setup lang="ts">
import { computed, onErrorCaptured, onUnmounted, ref } from 'vue'
import { computed, onErrorCaptured, ref } from 'vue'
import { useEventForwarding } from '@/composables/graph/useEventForwarding'
import type {
SafeWidgetData,
VueNodeData
@@ -70,9 +68,6 @@ interface NodeWidgetsProps {
const props = defineProps<NodeWidgetsProps>()
// Set up event forwarding for slot interactions
const { handleSlotPointerDown, cleanup } = useEventForwarding()
// Use widget renderer composable
const { getWidgetComponent, shouldRenderAsVue } = useWidgetRenderer()
@@ -166,18 +161,4 @@ const getWidgetInputIndex = (widget: ProcessedWidget): number => {
})
return idx >= 0 ? idx : 0
}
// Handle widget slot click
const handleWidgetSlotClick = (
event: PointerEvent,
_widget: ProcessedWidget
) => {
// Forward the event to LiteGraph for native slot handling
handleSlotPointerDown(event)
}
// Clean up event listeners on unmount
onUnmounted(() => {
cleanup()
})
</script>

View File

@@ -14,7 +14,6 @@
:style="{
height: slotHeight + 'px'
}"
@pointerdown="handleClick"
>
<!-- Slot Name -->
<span
@@ -61,10 +60,6 @@ interface OutputSlotProps {
const props = defineProps<OutputSlotProps>()
const emit = defineEmits<{
'slot-click': [event: PointerEvent]
}>()
// Error boundary implementation
const renderError = ref<string | null>(null)
@@ -82,13 +77,6 @@ const slotColor = computed(() => getSlotColor(props.slotData.type))
// Get slot height from litegraph constants
const slotHeight = COMFY_VUE_NODE_DIMENSIONS.components.SLOT_HEIGHT
// Handle click events
const handleClick = (event: PointerEvent) => {
if (!props.readonly) {
emit('slot-click', event)
}
}
const transformState = inject<TransformState | undefined>(
'transformState',
undefined