diff --git a/invokeai/frontend/web/src/features/ui/layouts/TabWithLaunchpadIcon.tsx b/invokeai/frontend/web/src/features/ui/layouts/TabWithLaunchpadIcon.tsx index 9129f44506..0dc960fb30 100644 --- a/invokeai/frontend/web/src/features/ui/layouts/TabWithLaunchpadIcon.tsx +++ b/invokeai/frontend/web/src/features/ui/layouts/TabWithLaunchpadIcon.tsx @@ -16,6 +16,8 @@ import { PiTextAaBold, } from 'react-icons/pi'; +import { useHackOutDvTabDraggable } from './use-hack-out-dv-tab-draggable'; + const TAB_ICONS: Record = { generate: PiTextAaBold, canvas: PiBoundingBoxBold, @@ -41,6 +43,8 @@ export const TabWithLaunchpadIcon = memo((props: IDockviewPanelHeaderProps) => { setFocusedRegion(props.params.focusRegion); }, [props.params.focusRegion]); + useHackOutDvTabDraggable(ref); + return ( diff --git a/invokeai/frontend/web/src/features/ui/layouts/TabWithoutCloseButton.tsx b/invokeai/frontend/web/src/features/ui/layouts/TabWithoutCloseButton.tsx index 3f114784cf..87021a4b91 100644 --- a/invokeai/frontend/web/src/features/ui/layouts/TabWithoutCloseButton.tsx +++ b/invokeai/frontend/web/src/features/ui/layouts/TabWithoutCloseButton.tsx @@ -5,6 +5,7 @@ import type { IDockviewPanelHeaderProps } from 'dockview'; import { memo, useCallback, useRef } from 'react'; import type { PanelParameters } from './auto-layout-context'; +import { useHackOutDvTabDraggable } from './use-hack-out-dv-tab-draggable'; export const TabWithoutCloseButton = memo((props: IDockviewPanelHeaderProps) => { const ref = useRef(null); @@ -20,6 +21,8 @@ export const TabWithoutCloseButton = memo((props: IDockviewPanelHeaderProps diff --git a/invokeai/frontend/web/src/features/ui/layouts/TabWithoutCloseButtonAndWithProgressIndicator.tsx b/invokeai/frontend/web/src/features/ui/layouts/TabWithoutCloseButtonAndWithProgressIndicator.tsx index 38e812c2d3..7433bb317f 100644 --- a/invokeai/frontend/web/src/features/ui/layouts/TabWithoutCloseButtonAndWithProgressIndicator.tsx +++ b/invokeai/frontend/web/src/features/ui/layouts/TabWithoutCloseButtonAndWithProgressIndicator.tsx @@ -7,6 +7,7 @@ import { memo, useCallback, useRef } from 'react'; import { useIsGenerationInProgress } from 'services/api/endpoints/queue'; import type { PanelParameters } from './auto-layout-context'; +import { useHackOutDvTabDraggable } from './use-hack-out-dv-tab-draggable'; export const TabWithoutCloseButtonAndWithProgressIndicator = memo( (props: IDockviewPanelHeaderProps) => { @@ -25,6 +26,8 @@ export const TabWithoutCloseButtonAndWithProgressIndicator = memo( setFocusedRegion(props.params.focusRegion); }, [props.params.focusRegion]); + useHackOutDvTabDraggable(ref); + return ( diff --git a/invokeai/frontend/web/src/features/ui/layouts/use-hack-out-dv-tab-draggable.ts b/invokeai/frontend/web/src/features/ui/layouts/use-hack-out-dv-tab-draggable.ts new file mode 100644 index 0000000000..9ea164f0c6 --- /dev/null +++ b/invokeai/frontend/web/src/features/ui/layouts/use-hack-out-dv-tab-draggable.ts @@ -0,0 +1,22 @@ +import type { RefObject } from 'react'; +import { useEffect } from 'react'; + +/** + * Prevent undesired dnd behavior in Dockview tabs. + * + * Dockview always sets the draggable flag on its tab elements, even when dnd is disabled. This hook traverses + * up from the provided ref to find the closest tab element and sets its `draggable` attribute to `false`. + */ +export const useHackOutDvTabDraggable = (ref: RefObject) => { + useEffect(() => { + const el = ref.current; + if (!el) { + return; + } + const parentTab = el.closest('.dv-tab'); + if (!parentTab) { + return; + } + parentTab.setAttribute('draggable', 'false'); + }, [ref]); +};