From abf591d122ff4027b6502fed4126ad4b15e147b4 Mon Sep 17 00:00:00 2001 From: Rizumu Ayaka Date: Tue, 29 Jul 2025 16:40:47 +0800 Subject: [PATCH] fix: DOM widget position offset after canvas moves (#4557) --- browser_tests/tests/domWidget.spec.ts | 38 +++++++++++++++++++ .../element/useAbsolutePosition.ts | 18 +++++++-- .../element/useCanvasPositionConversion.ts | 5 ++- 3 files changed, 55 insertions(+), 6 deletions(-) diff --git a/browser_tests/tests/domWidget.spec.ts b/browser_tests/tests/domWidget.spec.ts index 4ff305e1a..8119a71ad 100644 --- a/browser_tests/tests/domWidget.spec.ts +++ b/browser_tests/tests/domWidget.spec.ts @@ -47,4 +47,42 @@ test.describe('DOM Widget', () => { const finalCount = await comfyPage.getDOMWidgetCount() expect(finalCount).toBe(initialCount + 1) }) + + test('should reposition when layout changes', async ({ comfyPage }) => { + // --- setup --- + + const textareaWidget = comfyPage.page + .locator('.comfy-multiline-input') + .first() + await expect(textareaWidget).toBeVisible() + + await comfyPage.setSetting('Comfy.Sidebar.Size', 'small') + await comfyPage.setSetting('Comfy.Sidebar.Location', 'left') + await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.nextFrame() + + let oldPos: [number, number] + const checkBboxChange = async () => { + const boudningBox = (await textareaWidget.boundingBox())! + expect(boudningBox).not.toBeNull() + const position: [number, number] = [boudningBox.x, boudningBox.y] + expect(position).not.toEqual(oldPos) + oldPos = position + } + await checkBboxChange() + + // --- test --- + + await comfyPage.setSetting('Comfy.Sidebar.Size', 'normal') + await comfyPage.nextFrame() + await checkBboxChange() + + await comfyPage.setSetting('Comfy.Sidebar.Location', 'right') + await comfyPage.nextFrame() + await checkBboxChange() + + await comfyPage.setSetting('Comfy.UseNewMenu', 'Bottom') + await comfyPage.nextFrame() + await checkBboxChange() + }) }) diff --git a/src/composables/element/useAbsolutePosition.ts b/src/composables/element/useAbsolutePosition.ts index d334af7c7..bca981669 100644 --- a/src/composables/element/useAbsolutePosition.ts +++ b/src/composables/element/useAbsolutePosition.ts @@ -1,8 +1,9 @@ import type { Size, Vector2 } from '@comfyorg/litegraph' -import { CSSProperties, ref } from 'vue' +import { CSSProperties, ref, watch } from 'vue' import { useCanvasPositionConversion } from '@/composables/element/useCanvasPositionConversion' import { useCanvasStore } from '@/stores/graphStore' +import { useSettingStore } from '@/stores/settingStore' export interface PositionConfig { /* The position of the element on litegraph canvas */ @@ -18,9 +19,18 @@ export function useAbsolutePosition(options: { useTransform?: boolean } = {}) { const canvasStore = useCanvasStore() const lgCanvas = canvasStore.getCanvas() - const { canvasPosToClientPos } = useCanvasPositionConversion( - lgCanvas.canvas, - lgCanvas + const { canvasPosToClientPos, update: updateCanvasPosition } = + useCanvasPositionConversion(lgCanvas.canvas, lgCanvas) + + const settingStore = useSettingStore() + watch( + [ + () => settingStore.get('Comfy.Sidebar.Location'), + () => settingStore.get('Comfy.Sidebar.Size'), + () => settingStore.get('Comfy.UseNewMenu') + ], + () => updateCanvasPosition(), + { flush: 'post' } ) /** diff --git a/src/composables/element/useCanvasPositionConversion.ts b/src/composables/element/useCanvasPositionConversion.ts index 77e86ddec..2c0f7198e 100644 --- a/src/composables/element/useCanvasPositionConversion.ts +++ b/src/composables/element/useCanvasPositionConversion.ts @@ -11,7 +11,7 @@ export const useCanvasPositionConversion = ( canvasElement: Parameters[0], lgCanvas: LGraphCanvas ) => { - const { left, top } = useElementBounding(canvasElement) + const { left, top, update } = useElementBounding(canvasElement) const clientPosToCanvasPos = (pos: Vector2): Vector2 => { const { offset, scale } = lgCanvas.ds @@ -31,6 +31,7 @@ export const useCanvasPositionConversion = ( return { clientPosToCanvasPos, - canvasPosToClientPos + canvasPosToClientPos, + update } }