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
-4
View File
@@ -2,7 +2,6 @@ import Electrobun, { ApplicationMenu, BrowserWindow, Updater, Utils } from "elec
import { BRANDING } from "../shared/branding";
import type { EditorOpenContext } from "../shared/rpc";
import { effectiveConcurrency, type AppSettings } from "../shared/types";
import { PanelContextMenu } from "./context-menu";
import { EditManager } from "./edits";
import { EditorWindows } from "./editor-windows";
import { SessionRegistry } from "./fs/registry";
@@ -46,7 +45,6 @@ const engine = new TransferEngine(registry);
const store = new ConnectionStore();
const settings = new SettingsStore();
const edits = new EditManager(registry, engine, settings);
const contextMenu = new PanelContextMenu();
const watcher = new LocalDirWatcher();
const events = {
sessionClosed: (_info: { sessionId: string; reason: string }) => {},
@@ -65,7 +63,6 @@ const rpc = createAppRPC({
store,
settings,
edits,
contextMenu,
watcher,
mainWindow: () => mainWin,
events,
@@ -158,7 +155,6 @@ win.on("close", () => {
});
new AppTray(win);
contextMenu.onAction = (action) => rpc.send.menuAction({ action });
// notify on finished transfers while the window is in the background
let windowFocused = true;