diff --git a/electron/about.test.ts b/electron/about.test.ts index 79fdea4d..514e34bd 100644 --- a/electron/about.test.ts +++ b/electron/about.test.ts @@ -68,7 +68,24 @@ describe("PRODUCT_NAME", () => { it("matches the display name macOS reads out of Info.plist", () => { expect(key("CFBundleDisplayName")).toBe(PRODUCT_NAME); - expect(key("CFBundleName")).toBe(PRODUCT_NAME); + }); + + /* + * CFBundleName must NOT be set, and this is the assertion that says why. + * + * Electron resolves its helper apps from CFBundleName, and electron-builder names + * them after `productName` — so they ship as "Openscreen Helper.app". Setting + * CFBundleName to "RoleModel Studio" sent Electron looking for "RoleModel Studio + * Helper.app", which does not exist, and the app aborted before drawing a window: + * + * FATAL:electron_main_delegate_mac.mm:65] Unable to find helper app + * + * That is what made v0.0.1 unopenable. Nothing is lost by leaving it unset: the + * menu bar reads PRODUCT_NAME because main.ts calls app.setName at module scope, + * and everything a person actually reads comes from CFBundleDisplayName above. + */ + it("leaves CFBundleName unset, so Electron can still find its helper apps", () => { + expect(key("CFBundleName")).toBeUndefined(); }); it("leaves the bundle on disk named upstream's, which the cask and the shim resolve", () => { diff --git a/electron/studio/embedded-editor.ts b/electron/studio/embedded-editor.ts index 9d9c6233..51aa6f29 100644 --- a/electron/studio/embedded-editor.ts +++ b/electron/studio/embedded-editor.ts @@ -107,7 +107,7 @@ function create(): WebContentsView { created.webContents.on("dom-ready", () => { created.webContents .insertCSS( - "html, body, #root { background: #09090b !important; } :root { --titlebar-inset-left: 0px; }", + ":root { --titlebar-inset-left: 0px; }", ) .catch(() => { /* cosmetic, and the page may be mid-teardown */ diff --git a/electron/windows.ts b/electron/windows.ts index 1fbd686b..a50edfc9 100644 --- a/electron/windows.ts +++ b/electron/windows.ts @@ -67,17 +67,17 @@ function applyContentProtection(win: BrowserWindow, label: string) { if (CONTENT_PROTECTION_DISABLED) { console.warn( `[content-protection] OFF for the ${label} window ` + - "(OPENSCREEN_DISABLE_CONTENT_PROTECTION=1) — it will appear in screen captures, " + - "including recordings. Unset it for anything but automated testing.", + "(OPENSCREEN_DISABLE_CONTENT_PROTECTION=1) — it will appear in screen captures, " + + "including recordings. Unset it for anything but automated testing.", ); return; } if (CONTENT_PROTECTION_BREAKS_DISPLAY && !CONTENT_PROTECTION_FORCED) { console.warn( `[content-protection] OFF for the ${label} window — macOS ` + - `${process.getSystemVersion()} never displays a content-protected window, so ` + - "enabling it would make this window permanently invisible. It may therefore appear " + - "in screen captures. Set OPENSCREEN_FORCE_CONTENT_PROTECTION=1 to re-test.", + `${process.getSystemVersion()} never displays a content-protected window, so ` + + "enabling it would make this window permanently invisible. It may therefore appear " + + "in screen captures. Set OPENSCREEN_FORCE_CONTENT_PROTECTION=1 to re-test.", ); return; } @@ -447,8 +447,7 @@ export function createEditorWindow(query: Record = {}): BrowserW // Windows/Linux the topbar uses the `titlebar-area-*` env vars instead. win.webContents .insertCSS( - `html, body, #root { background: #09090b !important; } - :root { --titlebar-inset-left: ${isMac ? "68px" : "0px"}; }`, + `:root { --titlebar-inset-left: ${isMac ? "68px" : "0px"}; }`, ) .catch(() => { // Best-effort cosmetic; ignore if the page is mid-teardown. @@ -545,8 +544,25 @@ export function createStudioWindow(url: string): BrowserWindow { const inset = process.platform === "darwin" ? "72px" : "0px"; win.webContents .insertCSS( - `html, body { background: #141415 !important; } - .op-page__main-header { -webkit-app-region: drag; } + /* + * No `html, body { background: … !important }` here. + * + * It was belt-and-braces against a white flash, and the window's own + * `backgroundColor: "#141415"` above already does that — it is painted + * before the page exists, which is earlier than any injected rule can + * manage anyway. + * + * What it also did was reset the page's background-image. `background` + * is a shorthand, so with !important it wiped the Studio's grid and any + * future page texture, and nothing in a stylesheet can outrank it. + * Injected on dom-ready, it landed after first paint: the grid appeared + * and then vanished, which reads as the page fighting itself. Two days + * were spent looking for the override inside the page, where it was not. + * + * The drag region below is the only thing that genuinely belongs to the + * host: it is about the window frame, and it is inert in a browser. + */ + `.op-page__main-header { -webkit-app-region: drag; } .op-page__main-header button, .op-page__main-header a, .op-page__main-header input { -webkit-app-region: no-drag; } diff --git a/public/wallpapers/brand/academy-ruby.jpg b/public/wallpapers/brand/academy-ruby.jpg index 0dd85d73..1529a04b 100644 Binary files a/public/wallpapers/brand/academy-ruby.jpg and b/public/wallpapers/brand/academy-ruby.jpg differ diff --git a/public/wallpapers/brand/lcad-board.jpg b/public/wallpapers/brand/lcad-board.jpg index 5da48642..c2da3726 100644 Binary files a/public/wallpapers/brand/lcad-board.jpg and b/public/wallpapers/brand/lcad-board.jpg differ diff --git a/public/wallpapers/brand/rolemodel.jpg b/public/wallpapers/brand/rolemodel.jpg new file mode 100644 index 00000000..75f73f51 Binary files /dev/null and b/public/wallpapers/brand/rolemodel.jpg differ diff --git a/public/wallpapers/brand/thumbs/academy-ruby.jpg b/public/wallpapers/brand/thumbs/academy-ruby.jpg index 2479c3cc..6d00cf88 100644 Binary files a/public/wallpapers/brand/thumbs/academy-ruby.jpg and b/public/wallpapers/brand/thumbs/academy-ruby.jpg differ diff --git a/public/wallpapers/brand/thumbs/lcad-board.jpg b/public/wallpapers/brand/thumbs/lcad-board.jpg index fb1ad8f9..faeb866b 100644 Binary files a/public/wallpapers/brand/thumbs/lcad-board.jpg and b/public/wallpapers/brand/thumbs/lcad-board.jpg differ diff --git a/public/wallpapers/brand/thumbs/rolemodel.jpg b/public/wallpapers/brand/thumbs/rolemodel.jpg new file mode 100644 index 00000000..cbf3f106 Binary files /dev/null and b/public/wallpapers/brand/thumbs/rolemodel.jpg differ diff --git a/src/lib/brandWallpapers.ts b/src/lib/brandWallpapers.ts index 2884fe46..421f8d94 100644 --- a/src/lib/brandWallpapers.ts +++ b/src/lib/brandWallpapers.ts @@ -25,4 +25,5 @@ export const BRAND_WALLPAPERS: readonly BrandWallpaper[] = [ { path: "/wallpapers/brand/docks-board.jpg", thumb: "/wallpapers/brand/thumbs/docks-board.jpg", label: "Dock Designer · tinted board" }, { path: "/wallpapers/brand/railing-board.jpg", thumb: "/wallpapers/brand/thumbs/railing-board.jpg", label: "Railing Designer · tinted board" }, { path: "/wallpapers/brand/rolemodel-blue.jpg", thumb: "/wallpapers/brand/thumbs/rolemodel-blue.jpg", label: "Blue" }, + { path: "/wallpapers/brand/rolemodel.jpg", thumb: "/wallpapers/brand/thumbs/rolemodel.jpg", label: "Bright Blue" }, ]; diff --git a/website/docs/rolemodel/development.md b/website/docs/rolemodel/development.md index 43e33e2b..658e45b1 100644 --- a/website/docs/rolemodel/development.md +++ b/website/docs/rolemodel/development.md @@ -74,7 +74,7 @@ npm run verify # just the assertions ``` It is deliberately not a unit-test suite. Most of what breaks here is a contract -between two things — a formula that promises eight commands, a client that builds +between two things — a formula that promises nine commands, a client that builds a path the server resolves differently, a cask whose checksums no longer match its release — and those are the assertions worth having. Several exist because something shipped broken: diff --git a/website/docs/rolemodel/pipeline.md b/website/docs/rolemodel/pipeline.md index 555b5ae8..030eba0e 100644 --- a/website/docs/rolemodel/pipeline.md +++ b/website/docs/rolemodel/pipeline.md @@ -68,7 +68,7 @@ call site, which is what keeps rebasing on upstream cheap. What they add: brew install rolemodel/tap/rm-video ``` -That installs Node and eight commands: +That installs Node and nine commands: | command | does | |---|---| @@ -78,6 +78,7 @@ That installs Node and eight commands: | `rm-voice` | narration → audio + an exact SRT | | `rm-mux` | reconciles narration timing against a recast render | | `rm-library` | builds the library index | +| `rm-compose` | cuts scenes and footage into one document the editor opens | | `rm-share` | sends a finished video for review | | `rm-setup` | checks every piece of the install and repairs what it can |