From 0652986c4b0b996a2d3cff131475a77ad9163601 Mon Sep 17 00:00:00 2001 From: Hank Zhang Date: Wed, 17 Jun 2026 11:30:15 +0800 Subject: [PATCH] feat: add Ctrl+Enter / Cmd+Enter as send shortcut Support Ctrl+Enter (Windows/Linux) and Cmd+Enter (macOS) as additional send shortcuts alongside plain Enter. Shift+Enter continues to insert a newline. Changes: - ChatInput: expand Enter check to accept Ctrl/Cmd+Enter - ChatInput.test: add 4 tests covering plain Enter, Shift+Enter, Ctrl+Enter, and Cmd+Enter --- .../src/screens/Chat/ChatInput.test.tsx | 30 +++++++++++++++++++ src/renderer/src/screens/Chat/ChatInput.tsx | 3 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/renderer/src/screens/Chat/ChatInput.test.tsx b/src/renderer/src/screens/Chat/ChatInput.test.tsx index 6b6c8a094..391d4fff3 100644 --- a/src/renderer/src/screens/Chat/ChatInput.test.tsx +++ b/src/renderer/src/screens/Chat/ChatInput.test.tsx @@ -69,3 +69,33 @@ describe("ChatInput — CJK IME Enter handling", () => { expect(onSubmit).toHaveBeenCalledWith("안녕하세요", []); }); }); + +describe("ChatInput — Enter shortcut variants", () => { + it("submits on plain Enter", () => { + const { onSubmit, textarea } = renderInput(); + fireEvent.change(textarea, { target: { value: "hello" } }); + fireEvent.keyDown(textarea, { key: "Enter" }); + expect(onSubmit).toHaveBeenCalledWith("hello", []); + }); + + it("does not submit on Shift+Enter (newline)", () => { + const { onSubmit, textarea } = renderInput(); + fireEvent.change(textarea, { target: { value: "hello" } }); + fireEvent.keyDown(textarea, { key: "Enter", shiftKey: true }); + expect(onSubmit).not.toHaveBeenCalled(); + }); + + it("submits on Ctrl+Enter", () => { + const { onSubmit, textarea } = renderInput(); + fireEvent.change(textarea, { target: { value: "hello" } }); + fireEvent.keyDown(textarea, { key: "Enter", ctrlKey: true }); + expect(onSubmit).toHaveBeenCalledWith("hello", []); + }); + + it("submits on Cmd+Enter (macOS)", () => { + const { onSubmit, textarea } = renderInput(); + fireEvent.change(textarea, { target: { value: "hello" } }); + fireEvent.keyDown(textarea, { key: "Enter", metaKey: true }); + expect(onSubmit).toHaveBeenCalledWith("hello", []); + }); +}); diff --git a/src/renderer/src/screens/Chat/ChatInput.tsx b/src/renderer/src/screens/Chat/ChatInput.tsx index 9efa20a2b..41eedb212 100644 --- a/src/renderer/src/screens/Chat/ChatInput.tsx +++ b/src/renderer/src/screens/Chat/ChatInput.tsx @@ -352,7 +352,8 @@ export const ChatInput = forwardRef( } } - if (e.key === "Enter" && !e.shiftKey) { + // Send: plain Enter (without Shift) or Ctrl/Cmd+Enter + if (e.key === "Enter" && (!e.shiftKey || e.ctrlKey || e.metaKey)) { e.preventDefault(); handleSend(); }