Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 19 additions & 15 deletions src/renderer/core/canvas/useCanvasInteractions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,28 @@ export function useCanvasInteractions() {
() => !(canvasStore.canvas?.read_only ?? false)
)

/**
* Returns true if the wheel event target is inside an element that should
* capture wheel events AND that element (or a descendant) currently has focus.
*
* This allows two-finger panning to continue over inputs until the user has
* actively focused the widget, at which point the widget can consume scroll.
*/
const wheelCapturedByFocusedElement = (event: WheelEvent): boolean => {
const target = event.target as HTMLElement | null
const captureElement = target?.closest('[data-capture-wheel="true"]')
const active = document.activeElement as Element | null

return !!(captureElement && active && captureElement.contains(active))
}

/**
* Handles wheel events from UI components that should be forwarded to canvas
* when appropriate (e.g., Ctrl+wheel for zoom in standard mode)
*/
const handleWheel = (event: WheelEvent) => {
// Check if the wheel event is from an element that wants to capture wheel events
const target = event.target as HTMLElement
const captureElement = target?.closest('[data-capture-wheel="true"]')

if (captureElement) {
// Element wants to capture wheel events, don't forward to canvas
return
}
// If a wheel-capturing widget is focused, let it consume the wheel event
if (wheelCapturedByFocusedElement(event)) return

// In standard mode, Ctrl+wheel should go to canvas for zoom
if (isStandardNavMode.value && (event.ctrlKey || event.metaKey)) {
Expand Down Expand Up @@ -87,14 +96,9 @@ export function useCanvasInteractions() {
const forwardEventToCanvas = (
event: WheelEvent | PointerEvent | MouseEvent
) => {
// Check if the wheel event is from an element that wants to capture wheel events
const target = event.target as HTMLElement
const captureElement = target?.closest('[data-capture-wheel="true"]')

if (captureElement) {
// Element wants to capture wheel events, don't forward to canvas
// Honor wheel capture only when the element is focused
if (event instanceof WheelEvent && wheelCapturedByFocusedElement(event))
return
}

const canvasEl = app.canvas?.canvas
if (!canvasEl) return
Expand Down