From 1fd2a7f684a27ed11eb2bf5b6e853598531b5f2f Mon Sep 17 00:00:00 2001 From: yu859 <15715093608@163.com> Date: Fri, 24 Jul 2026 22:27:13 +0800 Subject: [PATCH] fix(core): hide stale panes when switching docks in popup mode --- .../components/dock/DockPanel.vue | 4 ++-- .../components/dock/DockStandalone.vue | 4 ++-- .../webcomponents/utils/useIframePanes.ts | 21 +++++++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/packages/core/src/client/webcomponents/components/dock/DockPanel.vue b/packages/core/src/client/webcomponents/components/dock/DockPanel.vue index becf65505..1808aa346 100644 --- a/packages/core/src/client/webcomponents/components/dock/DockPanel.vue +++ b/packages/core/src/client/webcomponents/components/dock/DockPanel.vue @@ -6,7 +6,7 @@ import type { DockLayout } from './dock-layout' import { useElementBounding, useWindowSize } from '@vueuse/core' import { computed, onMounted, reactive, ref, toRefs, useTemplateRef } from 'vue' import { getEntryGroup } from '../../state/dock-settings' -import { useIframePanes } from '../../utils/useIframePanes' +import { getEntryPaneKey, useIframePanes } from '../../utils/useIframePanes' import ViewEntry from '../views/ViewEntry.vue' import { DEFAULT_DOCK_LAYOUT, resolveDockAnchor } from './dock-layout' import { openDockContextMenu } from './DockContextMenu' @@ -36,7 +36,7 @@ const mousePosition = reactive({ x: 0, y: 0 }) const dockPanel = useTemplateRef('dockPanel') const viewsContainer = useTemplateRef('viewsContainer') -const panes = useIframePanes(viewsContainer, context.panel) +const panes = useIframePanes(viewsContainer, context.panel, () => getEntryPaneKey(selected.value)) function openContextMenu(e: MouseEvent) { if (!dockPanel.value) diff --git a/packages/core/src/client/webcomponents/components/dock/DockStandalone.vue b/packages/core/src/client/webcomponents/components/dock/DockStandalone.vue index a8ba581bb..cfe9c8d54 100644 --- a/packages/core/src/client/webcomponents/components/dock/DockStandalone.vue +++ b/packages/core/src/client/webcomponents/components/dock/DockStandalone.vue @@ -2,7 +2,7 @@ import type { DocksContext } from '@vitejs/devtools-kit/client' import { computed, useTemplateRef, watch } from 'vue' import { getEntryGroup } from '../../state/dock-settings' -import { useIframePanes } from '../../utils/useIframePanes' +import { getEntryPaneKey, useIframePanes } from '../../utils/useIframePanes' import { useIsRpcTrusted } from '../../utils/useIsRpcTrusted' import CommandPalette from '../command-palette/CommandPalette.vue' import Confirm from '../display/Confirm.vue' @@ -20,7 +20,7 @@ const props = defineProps<{ const context = props.context const viewsContainer = useTemplateRef('viewsContainer') -const panes = useIframePanes(viewsContainer, context.panel) +const panes = useIframePanes(viewsContainer, context.panel, () => getEntryPaneKey(context.docks.selected)) const isRpcTrusted = useIsRpcTrusted(context, (isTrusted) => { if (!isTrusted) { diff --git a/packages/core/src/client/webcomponents/utils/useIframePanes.ts b/packages/core/src/client/webcomponents/utils/useIframePanes.ts index 8895f9faa..9a948c301 100644 --- a/packages/core/src/client/webcomponents/utils/useIframePanes.ts +++ b/packages/core/src/client/webcomponents/utils/useIframePanes.ts @@ -1,9 +1,16 @@ +import type { DevToolsDockEntry } from '@vitejs/devtools-kit' import type { DocksPanelContext } from '@vitejs/devtools-kit/client' import type { IframePanes } from 'iframe-pane' import type { ShallowRef } from 'vue' import { createIframePanes } from 'iframe-pane' import { markRaw, onScopeDispose, shallowRef, watch } from 'vue' +export function getEntryPaneKey(entry: DevToolsDockEntry | null | undefined): string | null { + if (!entry) + return null + return entry.type === 'iframe' ? (entry.frameId ?? entry.id) : entry.id +} + /** * Own an {@link IframePanes} manager for a dock shell, parking its persistent * iframe/element panes in the given overlay container. @@ -18,6 +25,7 @@ import { markRaw, onScopeDispose, shallowRef, watch } from 'vue' export function useIframePanes( container: Readonly>, panel?: DocksPanelContext, + getActiveKey?: () => string | null, ): Readonly> { const panes = shallowRef() @@ -32,6 +40,19 @@ export function useIframePanes( { immediate: true, flush: 'post' }, ) + if (getActiveKey) { + watch( + getActiveKey, + (activeKey) => { + panes.value?.list().forEach((pane) => { + if (pane.id !== activeKey) + pane.hide() + }) + }, + { flush: 'post' }, + ) + } + if (panel) { // A panel move changes its box position without resizing the target, so the // shared ResizeObserver/scroll listeners never fire — re-sync explicitly.