diff --git a/apps/desktop/src/renderer/__tests__/composerMorphScope.test.ts b/apps/desktop/src/renderer/__tests__/composerMorphScope.test.ts index a39d52b5f3..294c3333d0 100644 --- a/apps/desktop/src/renderer/__tests__/composerMorphScope.test.ts +++ b/apps/desktop/src/renderer/__tests__/composerMorphScope.test.ts @@ -32,6 +32,15 @@ describe('composer morph scope', () => { expect(modelSelector).toContain('{trigger}'); }); + it('composer 选完模型后把焦点送回输入框;设置页不传 restoreFocusTarget', () => { + expect(chatInput).toContain('restoreFocusTarget={composerSuggestionFocusTarget}'); + expect(modelSelector).toContain('restoreFocusTarget?: () => HTMLElement | null'); + expect(modelSelector).toContain('onMouseDown={morphEnabled ? (event) => event.preventDefault() : undefined}'); + expect(settingsModel).not.toContain('restoreFocusTarget'); + expect(subagentModel).not.toContain('restoreFocusTarget'); + expect(createWorker).not.toContain('restoreFocusTarget'); + }); + it('PermissionSelector / ExtraDirsButton 仅 composer 使用,恒走脱身上浮 morph(无 opt-in、无 Radix 回退)', () => { expect(permissionSelector).not.toContain('useMorphPopover'); expect(extraDirsButton).not.toContain('useMorphPopover'); diff --git a/apps/desktop/src/renderer/__tests__/morphPopover.test.tsx b/apps/desktop/src/renderer/__tests__/morphPopover.test.tsx index 483e3f76e3..dcfa26b373 100644 --- a/apps/desktop/src/renderer/__tests__/morphPopover.test.tsx +++ b/apps/desktop/src/renderer/__tests__/morphPopover.test.tsx @@ -7,6 +7,8 @@ * 故本文件按新语义重写(取代旧 ghost/left-定位/focus-first-action/scroll-close 契约): * - 打开聚焦 [data-morph-autofocus] → 首个 input → 面板容器(不抢焦到首个按钮,§14.2) * - 关闭仅键盘(Esc)归还 trigger 焦点;鼠标关闭(选项/outside)不回焦(防误弹 trigger tooltip) + * - 传了 restoreFocusTarget 时,指针关闭立刻回该目标(选完模型能接着打字); + * Esc 仍回 trigger(§14.2);其它控件已接走则不抢 * - outside pointerdown 关闭,但嵌套 Radix portal(data-radix-popper-content-wrapper)内不算 outside * - trigger chip 全程可见(不隐藏),再点即关(toggle) * - 无 ghost 幽灵层 @@ -227,6 +229,159 @@ describe('MorphPopover interaction contract', () => { expect(document.activeElement).not.toBe(trigger); }); + it('restoreFocusTarget:鼠标选完后把焦点送回指定输入,而不是 trigger 或 body', async () => { + function RestoreHomeHarness() { + const [open, setOpen] = useState(false); + const composerRef = useRef(null); + return ( + <> +