Merge main into feat/7css-skin + give the HTML context menu an Aero skin

main retired electrobun's native context menu (a documented no-op on Linux) in
favour of an HTML one on every platform. Merging that here needs the menu to
look right under the Win7 skin as well.

Conflicts, all resolved by keeping both sides:
- src/bun/index.ts — createAppRPC keeps the branch's mainWindow getter, drops
  main's removed contextMenu dep.
- ui/src/app/app.ts — imports both TitleBar and ContextMenu.
- ui/src/app/platform.ts — kept the branch's version (its IS_MAC_CHROME accounts
  for the frameless win7 chrome, and MOD_LABEL correctly keys on the real
  platform rather than the chrome), plus exporting IS_MAC and adding IS_LINUX
  for the menu's per-OS shell wording.

Aero menu (branch-only): 7.css has no menu component, so it is hand-authored
across both layers — the row <button>s shed their push-button slab in `skin`
(revert-layer only reaches `utilities` from there), and the square-cornered
slab, hairline border and gradient selection band are stated in `skinfix`.
Built strictly from existing --w7-* vars, never literal hex, so the
hand-written dark Win7 palette recolours it for free. Hover and the keyboard
cursor share one band (the component marks the cursor with `bg-accent`, which
is overridden alongside :hover) as a real Win7 menu does.

Also answers a question the merge raised: frameless windows DO work on Linux.
The GTK wrapper honours titleBarStyle "hidden" — it calls
gtk_window_set_decorated(false) and logs "GTK: Created window without
decorations (custom titlebar)". Verified on GNOME/Wayland and documented in
architecture.md.

Verified: backend `tsc --noEmit` clean, `bun run build:ui` clean (492.52 kB
initial, still under the 500 kB budget), app launches with the skin active,
frameless, no console errors and no GBM failures.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-08-15 14:59:02 +02:00
co-authored by Claude
23 changed files with 737 additions and 214 deletions
+53
View File
@@ -579,6 +579,19 @@ body {
.win7 .w7-flat::after {
content: none;
}
/* Context-menu rows are <button>s, so 7.css would paint each one as an Aero
push-button slab. Strip the slab here (revert-layer needs `skin`); the
Win7 menu paint itself is stated in `skinfix` below. */
.win7 .w7-menu button {
background: revert-layer;
border: 0;
box-shadow: none;
}
.win7 .w7-menu button::before,
.win7 .w7-menu button::after {
content: none;
}
}
/* Above `skin`, for rules that must state a value rather than defer to a
@@ -591,4 +604,44 @@ body {
min-height: 23px;
padding: 0 12px;
}
/* Aero context menu. 7.css has no menu component, so this is hand-authored —
but ONLY out of the existing --w7-* vars, never literal hex, so the
hand-written dark Win7 palette above recolours it for free. Values are
stated (not reverted), hence `skinfix` rather than `skin`.
A real Win7 menu is a square-cornered white slab with a hairline border
and a gradient selection band that spans the full row. */
.win7 .w7-menu {
border-radius: 0;
border: 1px solid var(--w7-el-bd);
background: var(--w7-surface);
color: var(--w7-el-c);
font: var(--w7-font);
padding: 2px;
box-shadow: 0 2px 6px #0000004d;
}
.win7 .w7-menu button {
border-radius: 0;
padding: 3px 8px;
color: var(--w7-el-c);
}
/* Hover AND keyboard highlight share the band — the utility `bg-accent` that
drives the keyboard cursor is overridden here, so both look identical. */
.win7 .w7-menu button:hover,
.win7 .w7-menu button.bg-accent {
background: var(--w7-li-bg-hl);
border: 1px solid var(--w7-li-bd-hl);
/* keep the 1px border from shifting the label */
padding: 2px 7px;
}
.win7 .w7-menu .w7-menu-sep {
border-color: var(--w7-el-bd);
margin: 2px 0;
}
/* Accelerator hints ride the muted colour, like Win7's grey shortcut column.
Keyed on the utility class the accelerator span carries — `:last-child`
would also catch the LABEL on every item that has no accelerator. */
.win7 .w7-menu button > span.text-muted-foreground {
color: var(--w7-el-c-d);
}
}