Files
openidea/src/workbench/MainMenu.test.ts
T
l0ng-ai 642b80cef0 fix(workbench): Keep a way out of Distraction Free Mode on Windows (#47)
Root cause: on Windows the window is frameless and the main menu lives in the custom title bar; Distraction Free Mode rendered a bare title bar without it, the toggle has no default shortcut (as in IDEA) and the mode persists across restarts, leaving no way out.
Fix (IDEA): the bare title bar keeps the main menu when there is no native menu bar; a lone Alt opens the main menu; entering the mode (or restoring it) shows "To exit Distraction Free Mode, use View | Appearance … or Find Action" with an Exit action, in its own notification group.
Siblings covered: Distraction Free + Full Screen on Windows; other chrome-hiding settings checked (unaffected).
Verified in-app on macOS (hint, Exit action, single Don't Show Again). Windows-only parts (☰ in bare title bar, lone Alt) not verified on Windows.

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 10:38:26 +08:00

89 lines
2.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { menuItems, onLoneAlt } from "./MainMenu";
describe("lone Alt opens the main menu", () => {
const key = (type: string, k: string, init: KeyboardEventInit = {}) =>
window.dispatchEvent(new KeyboardEvent(type, { key: k, bubbles: true, cancelable: true, ...init }));
it.each<[string, () => void, number]>([
["Alt alone", () => (key("keydown", "Alt", { altKey: true }), key("keyup", "Alt")), 1],
[
"Alt+1",
() => (
key("keydown", "Alt", { altKey: true }),
key("keydown", "1", { altKey: true }),
key("keyup", "1"),
key("keyup", "Alt")
),
0,
],
[
"Ctrl+Alt",
() => (
key("keydown", "Control", { ctrlKey: true }),
key("keydown", "Alt", { ctrlKey: true, altKey: true }),
key("keyup", "Alt")
),
0,
],
[
"Alt+click",
() => (
key("keydown", "Alt", { altKey: true }),
window.dispatchEvent(new Event("pointerdown")),
key("keyup", "Alt")
),
0,
],
[
"held Alt (repeat)",
() => (
key("keydown", "Alt", { altKey: true }),
key("keydown", "Alt", { altKey: true, repeat: true }),
key("keyup", "Alt")
),
0,
],
])("%s", (_, press, expected) => {
let opened = 0;
const off = onLoneAlt(window, () => void opened++);
press();
off();
expect(opened).toBe(expected);
});
});
describe("main menu model", () => {
it("maps menu nodes to menu items, localising spec labels only", () => {
const items = menuItems([
{ kind: "action", id: "file.save", label: "Save All", hint: null, arg: null },
{ kind: "separator" },
{
kind: "submenu",
id: "openRecent",
label: "Open Recent",
children: [
{
kind: "action",
id: "file.openRecentProject",
label: "openidea — ~/openidea",
hint: null,
arg: "/p/openidea",
},
{ kind: "placeholder", id: "recent.none", label: "No Recent Projects" },
],
},
]);
expect(items[0]).toEqual({ kind: "action", action: "file.save", arg: undefined, label: "Save All" });
expect(items[1]).toEqual({ kind: "separator" });
expect(items[2]).toMatchObject({ id: "openRecent", label: "Open Recent" });
const sub = (items[2] as { submenu: unknown[] }).submenu;
expect(sub[0]).toEqual({
kind: "action",
action: "file.openRecentProject",
arg: "/p/openidea",
label: "openidea — ~/openidea",
});
expect(sub[1]).toMatchObject({ label: "No Recent Projects", disabled: true });
});
});