Skip to content

Commit abf591d

Browse files
authored
fix: DOM widget position offset after canvas moves (#4557)
1 parent e7a425e commit abf591d

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

browser_tests/tests/domWidget.spec.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,42 @@ test.describe('DOM Widget', () => {
4747
const finalCount = await comfyPage.getDOMWidgetCount()
4848
expect(finalCount).toBe(initialCount + 1)
4949
})
50+
51+
test('should reposition when layout changes', async ({ comfyPage }) => {
52+
// --- setup ---
53+
54+
const textareaWidget = comfyPage.page
55+
.locator('.comfy-multiline-input')
56+
.first()
57+
await expect(textareaWidget).toBeVisible()
58+
59+
await comfyPage.setSetting('Comfy.Sidebar.Size', 'small')
60+
await comfyPage.setSetting('Comfy.Sidebar.Location', 'left')
61+
await comfyPage.setSetting('Comfy.UseNewMenu', 'Top')
62+
await comfyPage.nextFrame()
63+
64+
let oldPos: [number, number]
65+
const checkBboxChange = async () => {
66+
const boudningBox = (await textareaWidget.boundingBox())!
67+
expect(boudningBox).not.toBeNull()
68+
const position: [number, number] = [boudningBox.x, boudningBox.y]
69+
expect(position).not.toEqual(oldPos)
70+
oldPos = position
71+
}
72+
await checkBboxChange()
73+
74+
// --- test ---
75+
76+
await comfyPage.setSetting('Comfy.Sidebar.Size', 'normal')
77+
await comfyPage.nextFrame()
78+
await checkBboxChange()
79+
80+
await comfyPage.setSetting('Comfy.Sidebar.Location', 'right')
81+
await comfyPage.nextFrame()
82+
await checkBboxChange()
83+
84+
await comfyPage.setSetting('Comfy.UseNewMenu', 'Bottom')
85+
await comfyPage.nextFrame()
86+
await checkBboxChange()
87+
})
5088
})

src/composables/element/useAbsolutePosition.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
import type { Size, Vector2 } from '@comfyorg/litegraph'
2-
import { CSSProperties, ref } from 'vue'
2+
import { CSSProperties, ref, watch } from 'vue'
33

44
import { useCanvasPositionConversion } from '@/composables/element/useCanvasPositionConversion'
55
import { useCanvasStore } from '@/stores/graphStore'
6+
import { useSettingStore } from '@/stores/settingStore'
67

78
export interface PositionConfig {
89
/* The position of the element on litegraph canvas */
@@ -18,9 +19,18 @@ export function useAbsolutePosition(options: { useTransform?: boolean } = {}) {
1819

1920
const canvasStore = useCanvasStore()
2021
const lgCanvas = canvasStore.getCanvas()
21-
const { canvasPosToClientPos } = useCanvasPositionConversion(
22-
lgCanvas.canvas,
23-
lgCanvas
22+
const { canvasPosToClientPos, update: updateCanvasPosition } =
23+
useCanvasPositionConversion(lgCanvas.canvas, lgCanvas)
24+
25+
const settingStore = useSettingStore()
26+
watch(
27+
[
28+
() => settingStore.get('Comfy.Sidebar.Location'),
29+
() => settingStore.get('Comfy.Sidebar.Size'),
30+
() => settingStore.get('Comfy.UseNewMenu')
31+
],
32+
() => updateCanvasPosition(),
33+
{ flush: 'post' }
2434
)
2535

2636
/**

src/composables/element/useCanvasPositionConversion.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export const useCanvasPositionConversion = (
1111
canvasElement: Parameters<typeof useElementBounding>[0],
1212
lgCanvas: LGraphCanvas
1313
) => {
14-
const { left, top } = useElementBounding(canvasElement)
14+
const { left, top, update } = useElementBounding(canvasElement)
1515

1616
const clientPosToCanvasPos = (pos: Vector2): Vector2 => {
1717
const { offset, scale } = lgCanvas.ds
@@ -31,6 +31,7 @@ export const useCanvasPositionConversion = (
3131

3232
return {
3333
clientPosToCanvasPos,
34-
canvasPosToClientPos
34+
canvasPosToClientPos,
35+
update
3536
}
3637
}

0 commit comments

Comments
 (0)