From 8cf5942a5f78aa5e0a81aa111d806c259b7f2f61 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Sun, 30 Aug 2026 10:50:20 +0200 Subject: [PATCH] fix(app): keep web composer focused after submit (#4067) The keyboard-sync change needed submission blur to dismiss the native keyboard, but applying it to every platform interrupted consecutive keyboard-driven messages on web and desktop. Keep submission blur native-only. --- .../app/e2e/browser/composer-focus.spec.ts | 29 +++++++++++++++++++ packages/app/e2e/support/helpers/composer.ts | 8 +++++ packages/app/src/panels/agent-panel.tsx | 4 +-- 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 packages/app/e2e/browser/composer-focus.spec.ts diff --git a/packages/app/e2e/browser/composer-focus.spec.ts b/packages/app/e2e/browser/composer-focus.spec.ts new file mode 100644 index 0000000000..897e536340 --- /dev/null +++ b/packages/app/e2e/browser/composer-focus.spec.ts @@ -0,0 +1,29 @@ +import { test } from "../support/fixtures"; +import { + expectComposerDraft, + expectComposerFocused, + expectComposerVisible, + submitMessage, + typeIntoFocusedComposer, +} from "../support/helpers/composer"; +import { openAgentRoute, seedMockAgentWorkspace } from "../support/helpers/mock-agent"; + +test("submitting a message leaves the composer ready for the next message", async ({ page }) => { + const agent = await seedMockAgentWorkspace({ + repoPrefix: "composer-focus-", + title: "Composer focus", + }); + + try { + await openAgentRoute(page, agent); + await expectComposerVisible(page); + + await submitMessage(page, "First message"); + await expectComposerFocused(page); + + await typeIntoFocusedComposer(page, "Second message"); + await expectComposerDraft(page, "Second message"); + } finally { + await agent.cleanup(); + } +}); diff --git a/packages/app/e2e/support/helpers/composer.ts b/packages/app/e2e/support/helpers/composer.ts index eb8760b91c..c7d2683284 100644 --- a/packages/app/e2e/support/helpers/composer.ts +++ b/packages/app/e2e/support/helpers/composer.ts @@ -38,6 +38,10 @@ export async function expectComposerEditable(page: Page): Promise { await expect(composerInput(page)).toBeEditable({ timeout: 15_000 }); } +export async function expectComposerFocused(page: Page): Promise { + await expect(composerInput(page)).toBeFocused(); +} + export async function submitMessage(page: Page, text: string): Promise { const input = composerInput(page); await expect(input).toBeEditable({ timeout: 30_000 }); @@ -49,6 +53,10 @@ export async function fillComposerDraft(page: Page, text: string): Promise await composerInput(page).fill(text); } +export async function typeIntoFocusedComposer(page: Page, text: string): Promise { + await page.keyboard.type(text); +} + export async function sendDraftToQueue(page: Page): Promise { await composerInput(page).press("Control+Enter"); } diff --git a/packages/app/src/panels/agent-panel.tsx b/packages/app/src/panels/agent-panel.tsx index 2cc6e97b5a..f412b10738 100644 --- a/packages/app/src/panels/agent-panel.tsx +++ b/packages/app/src/panels/agent-panel.tsx @@ -47,7 +47,7 @@ import { MAX_CONTENT_WIDTH, useIsCompactFormFactor, } from "@/constants/layout"; -import { isWeb } from "@/constants/platform"; +import { isNative, isWeb } from "@/constants/platform"; import { useAgentAttentionClear } from "@/hooks/use-agent-attention-clear"; import { useAgentInputDraft, type AgentInputDraft } from "@/composer/draft/input-draft"; import { @@ -1713,7 +1713,7 @@ function ActiveAgentComposer({ serverId={serverId} workspaceId={workspaceId} externalKeyboardShift - blurOnSubmit + blurOnSubmit={isNative} isPaneFocused={isPaneFocused} value={agentInputDraft.text} onChangeText={agentInputDraft.editText}