diff --git a/src/components/launch/HudControls.tsx b/src/components/launch/HudControls.tsx
index 78ef09a76..c417b754c 100644
--- a/src/components/launch/HudControls.tsx
+++ b/src/components/launch/HudControls.tsx
@@ -746,6 +746,7 @@ export const HudNotice = memo(function HudNotice({
confirmLabel,
onDismiss,
onConfirm,
+ confirmOnEnter = false,
}: {
title: string;
description: string;
@@ -753,7 +754,20 @@ export const HudNotice = memo(function HudNotice({
confirmLabel: string;
onDismiss: () => void;
onConfirm: () => void;
+ /** Enter confirms while no control has focus; a focused control keeps its own Enter. */
+ confirmOnEnter?: boolean;
}) {
+ useEffect(() => {
+ if (!confirmOnEnter) return;
+ const handleKeyDown = (event: KeyboardEvent) => {
+ if (event.key !== "Enter" || event.repeat || event.target !== document.body) return;
+ if (event.ctrlKey || event.altKey || event.shiftKey || event.metaKey) return;
+ onConfirm();
+ };
+ window.addEventListener("keydown", handleKeyDown);
+ return () => window.removeEventListener("keydown", handleKeyDown);
+ }, [confirmOnEnter, onConfirm]);
+
return (
{
expect(recorderState.value.dismissSoftwareEncoderFallbackNotice).toHaveBeenCalledTimes(1);
expect(recorderState.value.dismissSoftwareEncoderFallbackNotice).toHaveBeenCalledWith(true);
});
+
+ it("leaves Enter alone", async () => {
+ recorderState.value.softwareEncoderFallbackNoticeVisible = true;
+
+ renderLaunchWindow();
+ await screen.findByRole("button", { name: "Got it" });
+ fireEvent.keyDown(document.body, { key: "Enter" });
+
+ expect(recorderState.value.dismissSoftwareEncoderFallbackNotice).not.toHaveBeenCalled();
+ });
+});
+
+// #1428: the prompt's buttons need the mouse, and a window with nothing focused took Enter nowhere.
+describe("LaunchWindow system language prompt", () => {
+ beforeEach(() => {
+ platformState.value = "win32";
+ resetLaunchMocks();
+ i18nState.value.systemLocaleSuggestion = "zh-CN";
+ });
+
+ afterEach(() => {
+ cleanup();
+ vi.unstubAllGlobals();
+ });
+
+ it("accepts the suggestion on Enter while no control has focus", async () => {
+ renderLaunchWindow();
+ await screen.findByRole("button", { name: "Switch to English" });
+
+ fireEvent.keyDown(document.body, { key: "Enter" });
+
+ expect(i18nState.value.acceptSystemLocaleSuggestion).toHaveBeenCalledTimes(1);
+ expect(i18nState.value.dismissSystemLocaleSuggestion).not.toHaveBeenCalled();
+ });
+
+ it("leaves Enter to a control that has focus", async () => {
+ renderLaunchWindow();
+ const keep = await screen.findByRole("button", { name: "Keep current language" });
+ const user = userEvent.setup();
+
+ keep.focus();
+ await user.keyboard("{Enter}");
+
+ expect(i18nState.value.dismissSystemLocaleSuggestion).toHaveBeenCalledTimes(1);
+ expect(i18nState.value.acceptSystemLocaleSuggestion).not.toHaveBeenCalled();
+ });
+
+ it("ignores a held Enter, and other keys", async () => {
+ renderLaunchWindow();
+ await screen.findByRole("button", { name: "Switch to English" });
+
+ fireEvent.keyDown(document.body, { key: "Enter", repeat: true });
+ fireEvent.keyDown(document.body, { key: " " });
+ fireEvent.keyDown(document.body, { key: "Enter", ctrlKey: true });
+ fireEvent.keyDown(document.body, { key: "Enter", altKey: true });
+ fireEvent.keyDown(document.body, { key: "Enter", shiftKey: true });
+ fireEvent.keyDown(document.body, { key: "Enter", metaKey: true });
+
+ expect(i18nState.value.acceptSystemLocaleSuggestion).not.toHaveBeenCalled();
+ });
+
+ it("leaves Enter alone while a popover is open", async () => {
+ renderLaunchWindow();
+ fireEvent.click(await screen.findByRole("button", { name: "Language: English" }));
+
+ fireEvent.keyDown(document.body, { key: "Enter" });
+
+ expect(i18nState.value.acceptSystemLocaleSuggestion).not.toHaveBeenCalled();
+ });
});
// #1149: sonner's default corner of the HUD window is where the bar is, so a toast covered
diff --git a/src/components/launch/LaunchWindow.tsx b/src/components/launch/LaunchWindow.tsx
index 0bad565d7..50df3e645 100644
--- a/src/components/launch/LaunchWindow.tsx
+++ b/src/components/launch/LaunchWindow.tsx
@@ -1450,6 +1450,7 @@ export function LaunchWindow() {
})}
onDismiss={dismissSystemLocaleSuggestion}
onConfirm={acceptSystemLocaleSuggestion}
+ confirmOnEnter={!isPopoverOpen}
/>
)}