Compare commits
16 Commits
fix/codera
...
fix/spaceb
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16ad2c5975 | ||
|
|
813f54bff4 | ||
|
|
0f6fb90d04 | ||
|
|
0972a46a15 | ||
|
|
f5cdee82e9 | ||
|
|
571bb51ab5 | ||
|
|
a47081c169 | ||
|
|
0e47f9fb10 | ||
|
|
9427d7ed60 | ||
|
|
d114b01a75 | ||
|
|
53bdf7f6c3 | ||
|
|
fc082d84b9 | ||
|
|
3cf19af173 | ||
|
|
1d1e16b62d | ||
|
|
2f8f5253b5 | ||
|
|
f5ac48c5be |
|
Before Width: | Height: | Size: 103 KiB After Width: | Height: | Size: 97 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 99 KiB After Width: | Height: | Size: 98 KiB |
@@ -1953,6 +1953,10 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
this._key_callback = this.processKey.bind(this)
|
||||
|
||||
canvas.addEventListener('keydown', this._key_callback, true)
|
||||
// In Vue nodes mode, also listen on document for keydown since Vue elements may have focus
|
||||
if (LiteGraph.vueNodesMode) {
|
||||
document.addEventListener('keydown', this._key_callback, true)
|
||||
}
|
||||
// keyup event must be bound on the document
|
||||
document.addEventListener('keyup', this._key_callback, true)
|
||||
|
||||
@@ -1977,14 +1981,24 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
const { canvas } = this
|
||||
|
||||
// Assertions: removing nullish is fine.
|
||||
canvas.removeEventListener('pointercancel', this._mousecancel_callback!)
|
||||
// Note: capture flag must match addEventListener for removal to work
|
||||
canvas.removeEventListener(
|
||||
'pointercancel',
|
||||
this._mousecancel_callback!,
|
||||
true
|
||||
)
|
||||
canvas.removeEventListener('pointerout', this._mouseout_callback!)
|
||||
canvas.removeEventListener('pointermove', this._mousemove_callback!)
|
||||
canvas.removeEventListener('pointerup', this._mouseup_callback!)
|
||||
canvas.removeEventListener('pointerdown', this._mousedown_callback!)
|
||||
canvas.removeEventListener('pointerup', this._mouseup_callback!, true)
|
||||
canvas.removeEventListener('pointerdown', this._mousedown_callback!, true)
|
||||
canvas.removeEventListener('wheel', this._mousewheel_callback!)
|
||||
canvas.removeEventListener('keydown', this._key_callback!)
|
||||
document.removeEventListener('keyup', this._key_callback!)
|
||||
canvas.removeEventListener('keydown', this._key_callback!, true)
|
||||
// Always remove document keydown listener - it may have been added if vueNodesMode
|
||||
// was true during bindEvents, even if vueNodesMode has since changed
|
||||
if (this._key_callback) {
|
||||
document.removeEventListener('keydown', this._key_callback, true)
|
||||
}
|
||||
document.removeEventListener('keyup', this._key_callback!, true)
|
||||
canvas.removeEventListener('contextmenu', this._doNothing)
|
||||
canvas.removeEventListener('dragenter', this._doReturnTrue)
|
||||
|
||||
@@ -3668,8 +3682,14 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
if (!graph) return
|
||||
|
||||
let block_default = false
|
||||
// @ts-expect-error EventTarget.localName is not in standard types
|
||||
if (e.target.localName == 'input') return
|
||||
// Skip all text-editable surfaces to avoid blocking typing/selection/copy
|
||||
const target = e.target as HTMLElement | null
|
||||
if (
|
||||
target?.localName === 'input' ||
|
||||
target?.localName === 'textarea' ||
|
||||
target?.isContentEditable
|
||||
)
|
||||
return
|
||||
|
||||
if (e.type == 'keydown') {
|
||||
// TODO: Switch
|
||||
@@ -3705,9 +3725,12 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
// paste
|
||||
this.pasteFromClipboard({ connectInputs: e.shiftKey })
|
||||
} else if (e.key === 'Delete' || e.key === 'Backspace') {
|
||||
// delete or backspace
|
||||
// @ts-expect-error EventTarget.localName is not in standard types
|
||||
if (e.target.localName != 'input' && e.target.localName != 'textarea') {
|
||||
// delete or backspace (but don't intercept when editing text)
|
||||
if (
|
||||
target?.localName !== 'input' &&
|
||||
target?.localName !== 'textarea' &&
|
||||
!target?.isContentEditable
|
||||
) {
|
||||
if (this.selectedItems.size === 0) {
|
||||
this.#noItemsSelected()
|
||||
return
|
||||
|
||||
@@ -2,11 +2,12 @@ import { setActivePinia } from 'pinia'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { nextTick, ref } from 'vue'
|
||||
|
||||
import { useNodePointerInteractions } from '@/renderer/extensions/vueNodes/composables/useNodePointerInteractions'
|
||||
import { useNodeEventHandlers } from '@/renderer/extensions/vueNodes/composables/useNodeEventHandlers'
|
||||
import { createTestingPinia } from '@pinia/testing'
|
||||
|
||||
import { layoutStore } from '@/renderer/core/layout/store/layoutStore'
|
||||
import type { NodeLayout } from '@/renderer/core/layout/types'
|
||||
import { useNodeEventHandlers } from '@/renderer/extensions/vueNodes/composables/useNodeEventHandlers'
|
||||
import { useNodePointerInteractions } from '@/renderer/extensions/vueNodes/composables/useNodePointerInteractions'
|
||||
import { useNodeDrag } from '@/renderer/extensions/vueNodes/layout/useNodeDrag'
|
||||
|
||||
const forwardEventToCanvasMock = vi.fn()
|
||||
|
||||
@@ -6,8 +6,8 @@ import { useVueNodeLifecycle } from '@/composables/graph/useVueNodeLifecycle'
|
||||
import { useCanvasInteractions } from '@/renderer/core/canvas/useCanvasInteractions'
|
||||
import { layoutStore } from '@/renderer/core/layout/store/layoutStore'
|
||||
import { useNodeEventHandlers } from '@/renderer/extensions/vueNodes/composables/useNodeEventHandlers'
|
||||
import { isMultiSelectKey } from '@/renderer/extensions/vueNodes/utils/selectionUtils'
|
||||
import { useNodeDrag } from '@/renderer/extensions/vueNodes/layout/useNodeDrag'
|
||||
import { isMultiSelectKey } from '@/renderer/extensions/vueNodes/utils/selectionUtils'
|
||||
|
||||
export function useNodePointerInteractions(
|
||||
nodeIdRef: MaybeRefOrGetter<string>
|
||||
@@ -65,6 +65,12 @@ export function useNodePointerInteractions(
|
||||
function onPointermove(event: PointerEvent) {
|
||||
if (forwardMiddlePointerIfNeeded(event)) return
|
||||
|
||||
// Don't handle pointer events when canvas is in panning mode - forward to canvas instead
|
||||
if (!shouldHandleNodePointerEvents.value) {
|
||||
forwardEventToCanvas(event)
|
||||
return
|
||||
}
|
||||
|
||||
// Don't activate drag while resizing
|
||||
if (layoutStore.isResizingVueNodes.value) return
|
||||
|
||||
|
||||
@@ -293,6 +293,10 @@ export function useSlotLinkInteraction({
|
||||
raf.cancel()
|
||||
dragContext.dispose()
|
||||
clearCompatible()
|
||||
// Reset litegraph pointer state
|
||||
if (app.canvas) {
|
||||
app.canvas.pointer.isDown = false
|
||||
}
|
||||
}
|
||||
|
||||
const updatePointerState = (event: PointerEvent) => {
|
||||
@@ -409,6 +413,11 @@ export function useSlotLinkInteraction({
|
||||
|
||||
const handlePointerMove = (event: PointerEvent) => {
|
||||
if (!pointerSession.matches(event)) return
|
||||
|
||||
// When in panning mode (read_only), let litegraph handle panning - don't stop propagation
|
||||
if (app.canvas?.read_only) return
|
||||
|
||||
// Not in panning mode - Vue handles link drag, stop propagation to prevent litegraph interference
|
||||
event.stopPropagation()
|
||||
|
||||
dragContext.pendingPointerMove = {
|
||||
@@ -539,7 +548,10 @@ export function useSlotLinkInteraction({
|
||||
}
|
||||
|
||||
const handlePointerUp = (event: PointerEvent) => {
|
||||
event.stopPropagation()
|
||||
// When in panning mode, let litegraph handle - but still cleanup our link drag state
|
||||
if (!app.canvas?.read_only) {
|
||||
event.stopPropagation()
|
||||
}
|
||||
finishInteraction(event)
|
||||
}
|
||||
|
||||
@@ -584,6 +596,10 @@ export function useSlotLinkInteraction({
|
||||
if (event.button !== 0) return
|
||||
if (!nodeId) return
|
||||
if (pointerSession.isActive()) return
|
||||
|
||||
// Don't start link drag if in panning mode - let litegraph handle panning
|
||||
if (app.canvas?.read_only) return
|
||||
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
|
||||
@@ -703,6 +719,9 @@ export function useSlotLinkInteraction({
|
||||
)
|
||||
|
||||
pointerSession.begin(event.pointerId)
|
||||
// Sync pointer state with litegraph so spacebar panning works
|
||||
canvas.last_mouse = [event.clientX, event.clientY]
|
||||
canvas.pointer.isDown = true
|
||||
|
||||
toCanvasPointerEvent(event)
|
||||
updatePointerState(event)
|
||||
|
||||