From ab8e1e61ff7c0bbad08c95e15a09f3ec42333410 Mon Sep 17 00:00:00 2001 From: "paseo-bot[bot]" <266920839+paseo-bot[bot]@users.noreply.github.com> Date: Sat, 7 Nov 2026 16:18:07 +0000 Subject: [PATCH] fix(app): keep the composer ready after clicking Send (#9015) Pointer submission blurs the editor before sending and clears retained focus intent. Restore focus through the existing default send action for mouse-driven layouts, while keeping touch keyboard dismissal intact. Co-authored-by: paseo-bot[bot] <266920839+paseo-bot[bot]@users.noreply.github.com> --- packages/app/e2e/browser/composer-focus.spec.ts | 14 +++++++++++++- packages/app/src/composer/input/input.tsx | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/app/e2e/browser/composer-focus.spec.ts b/packages/app/e2e/browser/composer-focus.spec.ts index 4f2610b8db..61d2a5a35e 100644 --- a/packages/app/e2e/browser/composer-focus.spec.ts +++ b/packages/app/e2e/browser/composer-focus.spec.ts @@ -19,6 +19,7 @@ import { expectWorkspaceHeaderVisible, resizeComposerViewport, submitMessage, + submitMessageWithButton, typeIntoFocusedComposer, } from "../support/helpers/composer"; import { openAgentRoute, seedMockAgentWorkspace } from "../support/helpers/mock-agent"; @@ -146,6 +147,14 @@ test("submitting a message leaves the composer ready for the next message", asyn await openAgentRoute(page, agent); await expectComposerVisible(page); + await submitMessageWithButton(page, "Pointer submission"); + await expectComposerDraft(page, ""); + await expectComposerFocused(page); + await typeIntoFocusedComposer(page, "Ready after Send"); + await expectComposerDraft(page, "Ready after Send"); + await agent.client.waitForFinish(agent.agentId, 15_000); + await expectComposerFocused(page); + await submitMessage(page, "First message"); await expectComposerFocused(page); @@ -173,7 +182,7 @@ test("submitting a message leaves the composer ready for the next message", asyn "Investigate: [this FR](https://example.com/issues/39150) next. Thanks", ); await agent.client.waitForFinish(agent.agentId, 15_000); - await expect(page.getByRole("button", { name: "Copy turn", exact: true })).toBeVisible(); + await expect(page.getByRole("button", { name: "Copy turn", exact: true }).last()).toBeVisible(); await connection.drop(); await connection.waitForBlockedConnection(); await pasteRichTextIntoComposer({ @@ -313,6 +322,9 @@ test.describe("touch screen wide enough for the desktop layout", () => { // Autofocus makes its first attempt on the next animation frame. await waitForAnimationFrames(page, 4); await expectComposerNotFocused(page); + await submitMessageWithButton(page, "Touch submission"); + await expectComposerDraft(page, ""); + await expectComposerNotFocused(page); } finally { await agent.cleanup(); } diff --git a/packages/app/src/composer/input/input.tsx b/packages/app/src/composer/input/input.tsx index fc82a73e6d..5cb380c34b 100644 --- a/packages/app/src/composer/input/input.tsx +++ b/packages/app/src/composer/input/input.tsx @@ -1791,6 +1791,9 @@ export const MessageInput = forwardRef( handleSendMessage, handleQueueMessage, }); + if (hasFinePointer()) { + textInputRef.current?.focus(); + } }, [defaultSendBehavior, isAgentRunning, onQueue, handleQueueMessage, handleSendMessage]); const handleAlternateSendAction = useCallback(() => {