mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-19 22:09:37 +00:00
fix: disable pointer events on non-visible DOM widget overlays (#11063)
## Problem When a node with DOM widget overlays (e.g. CLIPTextEncode) is collapsed, the overlay elements can intercept pointer events intended for the canvas collapse toggler, making click-to-expand unreliable. ## Root Cause `updateWidgets()` runs during `onDrawForeground` (canvas render cycle) and sets `widgetState.visible = false` for collapsed nodes. `v-show` then hides the element with `display: none`. However, there is a timing gap between the canvas state change and Vue's DOM update — during this gap the widget overlay still intercepts pointer events. ## Fix Add `!widgetState.visible` to the `pointerEvents` condition in `composeStyle()`. This immediately sets `pointer-events: none` when the widget becomes invisible, preventing event interception before `v-show` applies `display: none`. Also restores click-to-expand in the E2E test, removing the programmatic `node.collapse()` workaround from PR #10967. - Fixes #11006 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-11063-fix-disable-pointer-events-on-non-visible-DOM-widget-overlays-33e6d73d36508179a83cd47121cf933f) by [Unito](https://www.unito.io)
This commit is contained in:
@@ -351,16 +351,9 @@ test.describe('Node Interaction', () => {
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'text-encode-toggled-off.png'
|
||||
)
|
||||
// Re-expand: clicking the canvas toggler on a collapsed node is
|
||||
// unreliable because DOM widget overlays may intercept the pointer
|
||||
// event. Use programmatic collapse() for the expand step.
|
||||
// TODO(#11006): Restore click-to-expand once DOM widget overlay pointer interception is fixed
|
||||
await comfyPage.page.evaluate((nodeId) => {
|
||||
const node = window.app!.graph.getNodeById(nodeId)!
|
||||
node.collapse()
|
||||
window.app!.canvas.setDirty(true, true)
|
||||
}, targetNode.id)
|
||||
await comfyPage.nextFrame()
|
||||
await comfyPage.canvas.click({
|
||||
position: togglerPos
|
||||
})
|
||||
await expect.poll(() => targetNode.isCollapsed()).toBe(false)
|
||||
// Move mouse away to avoid hover highlight differences.
|
||||
await comfyPage.canvasOps.moveMouseToEmptyArea()
|
||||
|
||||
@@ -114,4 +114,21 @@ describe('DomWidget disabled style', () => {
|
||||
expect(root.style.pointerEvents).toBe('none')
|
||||
expect(root.style.opacity).toBe('0.5')
|
||||
})
|
||||
|
||||
it('disables pointer events when widget is not visible', async () => {
|
||||
const widgetState = createWidgetState(false)
|
||||
widgetState.visible = false
|
||||
const { container } = render(DomWidget, {
|
||||
props: {
|
||||
widgetState
|
||||
}
|
||||
})
|
||||
|
||||
widgetState.zIndex = 3
|
||||
await nextTick()
|
||||
|
||||
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
|
||||
const root = container.querySelector('.dom-widget') as HTMLElement
|
||||
expect(root.style.pointerEvents).toBe('none')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -113,7 +113,10 @@ function composeStyle() {
|
||||
...positionStyle.value,
|
||||
...(enableDomClipping.value ? clippingStyle.value : {}),
|
||||
zIndex: widgetState.zIndex,
|
||||
pointerEvents: widgetState.readonly || isDisabled ? 'none' : 'auto',
|
||||
pointerEvents:
|
||||
!widgetState.visible || widgetState.readonly || isDisabled
|
||||
? 'none'
|
||||
: 'auto',
|
||||
opacity: isDisabled ? 0.5 : 1
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user