Add a toggleable Windows 7 (7.css) skin behind a new skin setting
Evaluation branch: a full Aero skin, including frameless windows with our own title bar, switchable against the existing modern look. The app already had a four-axis runtime skinning mechanism and zero component stylesheets, so the skin is one new setting plus one stylesheet section rather than a parallel UI. The key move is cascade order: 7.css is imported into a `skin` layer ABOVE Tailwind's `utilities`, so its bare element rules outrank the ~1900 inline utility classes already in the templates. Template changes are limited to additive, skin-inert hooks (ARIA roles, `has-scrollbar`, `w7-toolbar`, `w7-btn`). - styles.css: explicit layer order, `7.css/dist/7.scoped.css` via `layer(skin)`, a token bridge re-pointing the existing semantic tokens at Win7 values (no new tokens, so `@theme inline` is untouched), a hand-authored dark Win7 palette, and neutralizers that `revert-layer` 7.css's dialog-button metrics back to the utility layer. Neutralizers must live inside `skin`, not `skinfix` — `revert-layer` only reaches `utilities` from one layer up. - Frameless chrome: `chromeOptions(skin)` is now the single place either skin's frame is decided. `titleBarStyle: "hidden"` on every platform, which is also the only way to drop the macOS traffic lights. New `title-bar` component mounted by all three window roots. - Window controls over RPC (minimize/toggle-maximize/close/is-maximized), served per window kind so the X reuses each one's existing close path — editors still get their dirty prompt. electrobun has no maximize event, so the state is derived from `resize`; double-click-to-maximize is implemented here too. - Font: Noto Sans vendored (OFL-1.1) under ui/src/fonts, since Segoe UI is absent off Windows and not redistributable. Verified: backend `tsc --noEmit` clean, `bun run build:ui` clean (486 kB initial, under the 500 kB budget), app launches with the skin active and no console errors. The rendered result has not been eyeballed — screen capture and accessibility are both denied to the shell on this machine. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+19
-10
@@ -16,7 +16,7 @@ import { migrateLegacyDataDir } from "./store/paths";
|
||||
import { SettingsStore } from "./store/settings";
|
||||
import { AppTray } from "./tray";
|
||||
import { TransferEngine } from "./transfers/engine";
|
||||
import { buildPreload, showWhenReady } from "./windows";
|
||||
import { buildPreload, chromeOptions, showWhenReady, trackMaximizeState } from "./windows";
|
||||
|
||||
const PROD_URL = "views://app/index.html";
|
||||
|
||||
@@ -56,7 +56,20 @@ const events = {
|
||||
openConnectionManager: () => {},
|
||||
showAbout: () => {},
|
||||
};
|
||||
const rpc = createAppRPC({ registry, engine, store, settings, edits, contextMenu, watcher, events });
|
||||
// Late-bound for the same reason events is: `win` below takes this rpc in its
|
||||
// constructor, so it cannot exist yet. Only the win7 title bar reads it.
|
||||
let mainWin: BrowserWindow | undefined;
|
||||
const rpc = createAppRPC({
|
||||
registry,
|
||||
engine,
|
||||
store,
|
||||
settings,
|
||||
edits,
|
||||
contextMenu,
|
||||
watcher,
|
||||
mainWindow: () => mainWin,
|
||||
events,
|
||||
});
|
||||
// late-bound like events: a watched local dir changed -> tell the main webview
|
||||
watcher.onChange = (dir) => rpc.send.pathRefresh({ sessionId: "local", dir });
|
||||
const url = await getMainViewUrl();
|
||||
@@ -67,8 +80,6 @@ const url = await getMainViewUrl();
|
||||
let currentSettings = await settings.load();
|
||||
setBackendLocale(currentSettings.locale); // native menus/errors follow the UI language
|
||||
|
||||
const isMac = process.platform === "darwin";
|
||||
|
||||
const win = new BrowserWindow({
|
||||
title: BRANDING.appName,
|
||||
url,
|
||||
@@ -78,12 +89,8 @@ const win = new BrowserWindow({
|
||||
x: 120,
|
||||
y: 120,
|
||||
},
|
||||
// macOS: fuse the tab bar with the titlebar — traffic lights overlay the
|
||||
// UI's h-10 tab row (offset centers them vertically). Other platforms keep
|
||||
// the native titlebar and the tab bar stays a separate row.
|
||||
...(isMac
|
||||
? { titleBarStyle: "hiddenInset" as const, trafficLightOffset: { x: 12, y: 13 } }
|
||||
: {}),
|
||||
// Frame decision (per skin) lives in chromeOptions — see windows.ts.
|
||||
...chromeOptions(currentSettings.skin),
|
||||
// lets the UI pick the fused layout + theme before first paint
|
||||
preload: buildPreload("main", currentSettings),
|
||||
rpc,
|
||||
@@ -91,6 +98,8 @@ const win = new BrowserWindow({
|
||||
hidden: true,
|
||||
});
|
||||
showWhenReady(win);
|
||||
mainWin = win;
|
||||
trackMaximizeState(win, (maximized) => rpc.send.windowState({ maximized }));
|
||||
|
||||
const editors = new EditorWindows({
|
||||
registry,
|
||||
|
||||
Reference in New Issue
Block a user