Skip to content

Make the Trac window in the app's theme, and remove the patch window nothing opens - #649

Merged
zaerl merged 3 commits into
trunkfrom
feat/theme-patch-windows
Oct 7, 2026
Merged

zaerl merged 3 commits into
trunkfrom
feat/theme-patch-windows

Conversation

@zaerl

@zaerl zaerl commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

Why

The follow-up of #642: the two windows the app makes besides its own were white under the dark theme. One of them turned out not to exist for anyone.

What changes

The Trac window is made in the app's theme. It is the window Trac's proof-of-work check runs in, shown when the check needs a click, and it is now made in the colour of the theme the app is in, so its frame is not white where Trac's page does not paint. Trac's own page is Trac's and stays as Trac draws it.

The patch window is gone. It had no caller: the review dialog replaced it in the window, and only the preload bridge and the smoke's list of the bridge still named it; the git history shows no renderer ever called it. A window nobody opens cannot be the wrong colour, so it is removed with its channel and its bridge entry, and the review standard's window invariant names the two windows that exist, the main one and Trac's.

Not in this pull request: a dark Trac page; mail rendering is unchanged here and tracked separately.

How to test this

Platforms: any; the Trac window needs the network. From the repository root, after npm ci:

node --test tests/unit/trac-view.test.cjs tests/unit/ipc-wiring.test.cjs
  • trac-view.test.cjs: the Trac window is made in the dark colour under the dark theme and the light colour under the light one; the test is red on trunk, where the window is made with no colour.
  • ipc-wiring.test.cjs: every handler main registers is still one the suite names, with git:create-patch gone from both.
  • The packaged smoke holds the bridge to its list, with createPatchWindow gone from both.

This change has no journey of its own: no journey opens the Trac window, since it needs Trac's check, and the patch window is removed, not changed.

Worth a look by hand (any platform, the current head, with the network): set the theme to Dark in Settings → General, link a Trac ticket and press Show Trac attachments on a ticket whose check Trac escalates to the "I am human" checkbox, so the window appears: its frame is dark around Trac's page. On a ticket whose check clears by itself the window never shows, as before.

What must not have happened: anything in the window offering a patch in a window of its own (nothing did before either); the Trac window failing to show when the check needs a click; the attachment list not arriving.

What I could not test: the escalated check by hand, which Trac decides; I could not make it ask for the click.

Risks and limitations

  • Review: 2 passes, 2 findings fixed here, every style note applied, none left. Details below.
  • The bridge loses a function (createPatchWindow) nothing called; a fork of the renderer that did call it would find it gone.
  • A pre-existing journey, the Gutenberg pull request card in i18n.spec.js from Translate the pull request destination and GitHub sign-in #643, passes in the full suite only on a retry and fails when run alone, on trunk as here. Not touched here.

Related

Follow-up of #642, part of #560 and #542.


Review outcome (required — see AGENTS.md)

Pass 1: 2 [fix here] · 0 [follow-up] · 3 style notes. Pass 2 (on the fix-up): 1 [fix here] · 0 [follow-up] · 2 style notes. All applied here.

  • Review: completed — a separate agent context, read-only; head 1d0673d / base dca4bde; the claim that nothing opens the patch window checked against the renderer, the docs, the menu, the deep-link path and the git history (no renderer ever called it); the module loader of the Trac window's tests; the coverage guard of the wiring suite; ESLint and the two unit files run; 2 [fix here].
    • Fixed: the review standard's window invariant and three comments named the patch window.
    • Style notes, applied: the Trac window's comment overstated when its colour shows; the new test slept through the poll; the save-patch test's name implied a comparison it did not make.
  • Review: completed — a second separate agent context, read-only; head 99efecf / base dca4bde; the zero deadline traced through openAndScrape, the renamed test against what it reads, the standard's sentence against the two windows that exist; ESLint and the two unit files run; 1 [fix here], wording.
    • Fixed: the save-patch test's name said "first read" of a read the handler makes second.
    • Style notes, applied: the stand-in window's variable still called it a patch; a deadline "already passed" that is a deadline of now.
  • Since review: 99efecf → 5131c7c is that wording, in the two unit files only. On 1d0673d: npm run lint, npm test, npm run test:electron, all 124 journeys and the packaged smoke pass; on 99efecf: npm run test:electron (2038); on the head: npm run lint and the two unit files.
Implementation notes
  • src/trac-view.js: backgroundColor from windowBackground(nativeTheme.shouldUseDarkColors).
  • src/main.js: buildPatchHtml and git:create-patch removed. src/preload.js: createPatchWindow removed. tests/e2e/packaged/smoke.spec.js, tests/unit/ipc-wiring.test.cjs: their lists.
  • tests/unit/trac-view.test.cjs: the colour under each theme.
  • .github/instructions/code-review.instructions.md: the window invariant names the main and the Trac window.
Screenshots or recording

Not attached: the Trac window shows only when Trac escalates its check, which I could not make it do.

🤖 Generated with Claude Code

zaerl and others added 3 commits October 7, 2026 10:03
…nothing opens

The follow-up of #642: the two windows the app makes besides its own were white under the dark theme. The Trac window, shown when Trac's check needs a click, is now made in the colour of the theme for the moment before Trac has painted; Trac's own page is Trac's. The patch window turned out to have no caller: the review dialog replaced it in the window, and only the preload bridge and the smoke's list of the bridge still named it. A window nobody opens cannot be the wrong colour, so it is gone, with its channel and its bridge entry.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
From the review pass. The review standard's window invariant and three comments named the patch window that is gone; they name the Trac window, which is the second window. The Trac window's comment says when its colour shows, where Trac's page does not paint, and its test skips the poll with a deadline already passed.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
From the second review pass: wording only.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: WordPress/contributor-toolkit/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 3eb94b96-d7e8-4512-b695-b78bbf6380b3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@zaerl zaerl self-assigned this Oct 7, 2026
@zaerl
zaerl merged commit 59afb0c into trunk Oct 7, 2026
8 checks passed
@zaerl
zaerl deleted the feat/theme-patch-windows branch October 7, 2026 08:33
zaerl added a commit that referenced this pull request Oct 7, 2026
…tor's own (#650)

## Why

The prototype's dialog has a fourth theme, and the dark theme of
#642 left it out: a
background and an accent colour of the contributor's own, from which the
design system builds every other colour as it builds the dark theme from
its one seed. This adds it, under the name the design system gives the
second colour: primary. Part of #560.

## What changes

**Custom, on the General tab.** Under **Theme**, a fourth answer;
chosen, two fields appear beneath it: **Background** and **Primary**,
each typed as hex or picked with the system's colour picker, which is
the swatch before the field. A colour is kept as six lowercase hex
digits from three or six as typed; one that is not a colour is refused
in main's words and the field goes back to what is kept. The picker's
choice is kept when the picker is done, not at every step of a drag,
since each keep is a write to the store; the field shows the colour
under the pointer meanwhile. The colours start as the light theme's.

**A custom theme is a scheme too.** Main gives Electron light or dark by
whether the background reads better with white text than with black, the
crossover the design system's own ramp turns at, so the native form
controls and the window's chrome match the page; and the window is made
and painted in the background chosen, as is the Trac window, which main
now hands its colour. The window reads the settings above the design
system's provider, since the theme is one of them, and gives the
provider the two colours; the terminal re-reads its colours whenever the
theme as painted changes, by a name that changes with it.

**When the colours do not read.** The design system says when it could
not reach the contrast it wants between two of the colours it built, and
under Custom the dialog passes that on in one sentence. The colours are
kept all the same: a contributor who chose them can read them, and the
sentence is for the one who did not mean to.

**Not in this pull request:**

- The moment before the settings arrive: a custom theme shows the
standard theme of its scheme for one round trip to main at launch, then
its own. Removing it means handing the renderer the theme before its
first paint, new bridge surface for a separate change.
- Mail rendering is unchanged here and tracked separately.

## How to test this

Platforms: any. The journeys drive this on macOS and Windows. From the
repository root, after `npm ci` and `npm run build:once`:

```
npx playwright test --project=journeys settings.spec i18n.spec
```

- `settings.spec.js`, the custom theme journey: the colours are asked
for under Custom alone and start as the light theme's; a dark background
typed and entered is kept, Electron is told the scheme, and the page,
the body and the window are painted in it at once; a primary colour in
three digits is kept in six and the brand surface is built from it; a
colour spelled another way shows as kept; a colour picked with the
picker is kept; a colour that is not one is refused in main's words and
what is kept stays; a light background makes a light theme again;
started again, the window is made in the background and the fields show
the colours kept.
- `i18n.spec.js`: the control in the pseudo-locale.

Six claims were broken one at a time and each turned the journey red:
the page not seeded from the colours, Electron not told the scheme, a
refusal leaving the typed text, three digits not expanded, the window
not painted in the background, and the picker driven from what is kept
rather than the draft, which was the bug the first review pass found.
`tests/unit/theme.test.cjs` holds the resolution, the crossover and the
hex forms; `settings.test.cjs` what is accepted; `ipc-wiring.test.cjs`
what Electron, the window and the Trac window are given.

**Worth a look by hand** (any platform, the current head): Settings →
General → Theme → **Custom**. Type `102030` into Background and press
Enter: the whole window is navy, the dialog included, and the native
controls (the folder field's button, a select's list) are dark. Press
the Primary swatch, drag in the picker: the field follows the pointer;
close the picker: the buttons take the colour. Type `navy`: refused
under the fields, the field back to the colour kept. Type `fff8e1`: a
cream theme with dark text and light controls. Quit and open the app: it
opens in the cream, after a moment of the standard light theme.

**What must not have happened:** the standard themes looking any
different (the guide's pictures are the reference); a picker drag
writing the store at every step; a colour kept that the field does not
show; a server or build touched by a change.

**What I could not test:** Windows and Linux pickers, which the OS
draws; the journeys drive the picker through its value, as a picker does
when it is done.

## Risks and limitations

- Review: 2 passes, 6 findings fixed here, 1 follow-up left (the flash
at launch), every style note applied. Details below.
- **A custom theme flashes the standard theme of its scheme at launch**,
for one round trip to main. See above.
- **The pre-paint of a dark window** is the dark seed, not the custom
background, for the moment before the page's script runs; then the
standard dark theme, then the custom one.
- **Two colours can be chosen that read badly together.** The dialog
says so and keeps them; the standard themes are one press away.

## Related

Part of #560, which is part of #542. Follows
#642 and
#649.

---

<details>
<summary>Design decisions and alternatives considered</summary>

- **"Primary", not the prototype's "accent".** It is what the design
system calls the seed, and what the provider's prop is named.
- **The scheme from the background's luminance**, by the rule the design
system's ramp uses to pick its text direction: white where it contrasts
better than black. One rule, so the native controls and the ramp agree
except within a hair of the crossover.
- **The picker commits when done, not as it is dragged.** A drag is tens
of events a second; each keep is a store write and an IPC round trip.
- **The picker driven from the draft.** A controlled input is put back
to its prop after every step of a drag, and the picker's closing then
reads the old colour: the first review pass found the picker never
saving.
- **The settings read above the provider.** The theme is a setting, so
the component that reads the settings has to sit above the one that
paints with them; the app is handed what was read.
- **The warning passed on, the colours kept.** The design system's
answer is the authority on contrast; the contributor is the authority on
what they want to look at.

</details>

<details>
<summary>Review outcome (required — see AGENTS.md)</summary>

**Pass 1: 4 [fix here] · 1 [follow-up] · 4 style notes. Pass 2 (on the
fix-up): 2 [fix here] · 0 [follow-up] · 3 style notes. All 6 fixed here,
every style note applied, 1 follow-up left.**

- **Review:** completed — a separate agent context, read-only; head
`8b3658a` / base `59afb0c`; the store rule against the changed handlers,
the theme's ordering in main against Electron's `themeSource`, the
luminance maths against the design system's own ramp direction, React's
controlled-input restore against the colour picker's `change`, the
design system's input and the provider's warnings; ESLint and the unit
files run; 4 [fix here], 1 [follow-up].
- Fixed: a colour picked with the picker was never kept, since a
controlled input is put back to its prop after every step of a drag and
the picker's closing read the old colour; the wiring test's Trac
assertion never opened a Trac window; the fallback before the settings
arrive was a branch in the component; the hex fields' monospace rule
reached nothing.
- Follow-up left: the standard theme of the scheme shows for one round
trip at launch.
- Style notes, applied: the crossover pinned; a colour spelled another
way shown as kept; a dead prop; the translator comment checked.
- **Review:** completed — a second separate agent context, read-only;
head `7fdf4e0` / base `59afb0c`; the picker's event order on a real
picker and under Playwright's fill, the listener's double-commit, the
accent ramp's first step for the journey's exact colours, the crossover
recomputed; ESLint and the unit files run; 2 [fix here].
- Fixed: a keep that finished late overwrote newer typing in the field;
what the field shows after a keep, and what the picker holds while the
field holds no colour, were decided in the component.
- Style notes, applied: the Trac assertion built a repository it never
opened; the journey's two exact colours say where they come from; a
comment on the swatch.
- **Since review:** `7fdf4e0 → 0a9965d` is those two and the notes, not
reviewed again; `31c125c` stands the swatch in the design system's
prefix slot as a centred square, from the maintainer's look at the
dialog, not reviewed again. On `0a9965d`: `npm run lint`, `npm test`,
`npm run test:electron`, all 133 journeys, the packaged smoke and the
docs build pass; on the head: `npm run lint`, `npm run test:electron`
(2045) and all 133 journeys, the packaged smoke not run since the
maintainer's own app held the single-instance lock. The commit after it
fixes a Windows-only cleanup race in `tests/unit/log-tail.test.cjs`, a
test this branch does not otherwise touch, which failed the Windows unit
job on `31c125c`: the read helper now settles on the stream's `close`,
so the folder is removed after the file is.

</details>

<details>
<summary>Implementation notes</summary>

- `src/theme.cjs`: `THEMES` with 'custom', `THEME_KEYS`, `resolveTheme`,
`nativeThemeSource`, `normalizeHexColor`, `isHexColor`, `isDarkColor`,
`PRIMARY`. `src/settings.cjs`: `customBackground`, `customPrimary`,
`acceptColor`.
- `src/main.js`: `themeSettings`, `applyTheme`, `currentTheme`,
`paintWindowForTheme`; `settings:set` applies for any theme key; the
Trac window is handed `backgroundColor`. `src/trac-view.js`:
`deps.backgroundColor`.
- `src/renderer/components/app-theme.jsx`: `AppTheme({ settings })`,
`useThemeKey`, `useThemeWarnings`. `src/renderer/index.jsx`: `Root`
reads the settings above the provider.
`src/renderer/hooks/use-site-terminal.jsx`: re-reads on the theme's
name.
- `src/renderer/components/settings-dialog.jsx`: `ColorField`, the
fourth option, the warning. `src/renderer/settings-view.cjs`:
`themeItems`. `src/renderer/shell.css`: `.theme-colors`, `.color-field`,
`.color-swatch`.
- Tests: `tests/unit/theme.test.cjs`, `settings.test.cjs`,
`settings-view.test.cjs`, `ipc-wiring.test.cjs`, `trac-view.test.cjs`;
`tests/e2e/journeys/settings.spec.js`.

</details>

<details>
<summary>Screenshots or recording</summary>

Not attached: I have no way to upload images from the command line. The
custom theme journey drives everything that changed; `SHOTS_THEME` takes
light or dark only, so a picture of a custom theme is a hand's work.

</details>

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
@zaerl zaerl added this to the v2.0.0 milestone Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant