feat(audit): Batch 20 — Windows/main-process (UI23, W12, W15, L131)

UI23: cookie sign-in + PO-token windows open with the app's resolved
theme background (passed from the IPC layer), no more white flash.
W12: multi-resolution fallback tray icon (16/24/32/48 via
addRepresentation dataURL, embedded in trayFallbackIcons.ts); decode +
scale factors verified in an Electron probe.
W15: hardwareAcceleration setting (default false = software rendering);
index.ts gates disableHardwareAcceleration on it after the portable
redirect; Appearance card switch with restart note; boot path verified.
L131: resolved by-design — clearing the queue acknowledges failures;
flashFrame (W10) covers attention, Diagnostics persists the record.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-02 12:15:51 -04:00
parent f54d9a1965
commit 3b0d668f6c
11 changed files with 300 additions and 57 deletions
+29 -22
View File
@@ -1118,12 +1118,14 @@ token system + shared primitives (UI/SIMP — high value, larger effort) · i18n
audit's own note ("Fine when interpolated") confirms it; every string that reaches the UI raw (via a toast,
a status line, `cleanError`) is already a complete capitalized sentence. Standard: complete sentences for
anything shown raw; lowercase only for fragments meant to be composed.*
- [ ] **L131 — Taskbar `error` state is ephemeral** — it's driven by live `error` items, so "Clear
- [x] **L131 — Taskbar `error` state is ephemeral** — it's driven by live `error` items, so "Clear
finished" flips the red taskbar bar back to normal even though failures occurred (out of sync with the persisted error log).
*Deferred (arguably by-design, needs the live taskbar): the taskbar reflects the *live queue*, so clearing
finished items legitimately returns it to idle — the persisted record lives in Diagnostics. Whether the red
bar should linger after a clear is a debatable UX call best judged against the real Windows taskbar; left
for the watched Windows pass (with Batch 14/15).*
*Resolved as by-design (Batch 20): the taskbar mirrors the live queue, and "Clear finished" is the user
acknowledging those results — a red bar lingering after the queue is cleared would point at nothing the
window can explain and would need its own dismiss affordance. Attention at failure time is already covered
by the notification + `flashFrame` (W10), and the durable record lives in Diagnostics/errorlog. Judged on
the state semantics rather than pixels; the running production instance on this machine was left
undisturbed.*
- [x] **L132 — `clearProbe` + form-reset logic is duplicated** in DownloadBar (`onUrlChange`, `download`, `addPlaylist`).
*Fixed: a shared `resetForm()` in [useDownloadBar.ts](src/renderer/src/components/downloadBar/useDownloadBar.ts)
now owns the post-enqueue reset (URL + probe + the one-shot trim/schedule/advanced/incognito/options),
@@ -1507,16 +1509,17 @@ are an undefined spacing/radius/type scale and a drift between Fluent components
### Dialogs, menus, status, navigation
- [ ] **UI23 — Fragmented overlay/dialog system.** Native OS dialogs (pickers, backup save/open,
- [x] **UI23 — Fragmented overlay/dialog system.** Native OS dialogs (pickers, backup save/open,
backup warning `messageBox`), one custom React overlay (CommandPalette), a full-screen view
(Onboarding), and an **unstyled separate `BrowserWindow`** (cookie sign-in) that shows none of the
app's theme/chrome. **Standard:** keep native for file/confirm; unify in-app overlays under one
themed primitive; theme the sign-in window's title/background to match.
*Deferred (larger, needs the live windows): the in-app overlays are already fairly unified — CommandPalette
and the new Toaster share the non-portal `Z`/`SCRIM`/`ELEVATION` tokens (Batch 6/11). The actionable
remainder is theming the separate cookie **sign-in `BrowserWindow`** (its own HTML/background) to match the
app's Light/Dark chrome — a main-process window change best verified with a real login flow open, so it's
left for a watched session. Native file/confirm dialogs stay native by design.*
*Fixed (Batch 20, the actionable remainder): the cookie sign-in window — and the PO-token window, its
sibling on the same login partition — now open with `backgroundColor` set to the app's resolved theme
(`PAGE_BACKGROUND[resolveBackgroundMode(...)]`, supplied by the IPC layer to avoid an import cycle), so
neither flashes default-white chrome before the remote page paints; their title bars already follow the
app theme via the W3 `nativeTheme.themeSource` bridge. In-app overlays were already unified on the
non-portal `Z`/`SCRIM`/`ELEVATION` tokens; native file/confirm dialogs stay native by design.*
- [x] **UI24 — No context menus anywhere.** Every row exposes actions only as inline buttons;
right-click does nothing on any screen, despite many per-row actions that conventionally also live on
right-click. **Standard:** add consistent right-click menus mirroring row actions, or note "none by design."
@@ -1858,13 +1861,15 @@ DPI handled by Chromium). The deviations:
[ipc.ts](src/main/ipc.ts) calls `win.setOverlayIcon(badge, label)` with an accessible count label
("N downloads active" / "Download error"), cleared to `null` when the queue goes idle. (Numeric count
lives in the tooltip label — a 16px overlay can't legibly render digits.)*
- [ ] **W12 — Fallback tray icon is single-resolution.** The embedded fallback is a 32×32 PNG, so on
- [x] **W12 — Fallback tray icon is single-resolution.** The embedded fallback is a 32×32 PNG, so on
150%/200% DPI the tray glyph is blurry when the real multi-size `.ico` is absent. **Standard:** a
multi-size fallback (or rely only on the `.ico`).
*Deferred (low value, needs the real tray to judge): the fallback only renders in the unlikely case the
bundled multi-size `build/icon.ico` is missing (W14 regenerated it), so it's a fallback-of-a-fallback. A
multi-res embedded base64 is fiddly to author and best verified on a real high-DPI tray — not worth an
unattended change for a path that shouldn't be hit.*
*Fixed (Batch 20): the fallback is now a multi-representation `NativeImage` — 16/24/32/48 px renders of
build/icon.svg (ImageMagick, like W14) embedded in
[trayFallbackIcons.ts](src/main/trayFallbackIcons.ts) and added via `addRepresentation` at scale factors
1/1.5/2/3, so Windows picks the crisp size for the DPI. Verified in an Electron probe: the image decodes
(non-empty) and reports all four scale factors. As before, it only renders if the bundled icon.ico is
missing.*
- [x] **W13 — Notifications set no icon.** `new Notification({title, body})` omitted `icon`; on the **portable**
build (no installed AUMID shortcut) Windows toasts showed a generic icon. *Fixed: both notification sites
([download.ts](src/main/download.ts) completion/failure toast + [index.ts](src/main/index.ts) background-running
@@ -1878,14 +1883,16 @@ DPI handled by Chromium). The deviations:
### High DPI, multiple monitors, touch
- [ ] **W15 — Software rendering is global.** Hardware acceleration is disabled for a documented GPU
- [x] **W15 — Software rendering is global.** Hardware acceleration is disabled for a documented GPU
workaround; on high-DPI/large windows this trades GPU compositing for CPU, which can be sluggish.
**Standard:** re-enable HW accel where the target GPU allows (the memo already flags revisiting this).
*Deferred (deliberate workaround, external dependency): `disableHardwareAcceleration()` is the fix for the
dev machine's GPU/driver blank-overlay bug (documented in index.ts and the project memo) — the very reason
the app hand-rolls non-portal overlays. Re-enabling HW accel can't be validated until the NVIDIA driver
issue is confirmed resolved on the target GPU, so it's intentionally left until that watched hardware pass.
PERF8 (this batch) trims the first-paint cost that software rendering compounds.*
*Fixed (Batch 20) as a user setting rather than a blind re-enable (the dev-machine GPU bug still can't be
validated here): new `Settings.hardwareAcceleration` (default **false** = today's safe software rendering),
surfaced as Settings → Appearance → "Hardware acceleration" with a restart note. index.ts reads it before
ready (after the portable userData redirect) and only then calls `disableHardwareAcceleration()`; the
window-occlusion feature stays disabled in both modes (a separate documented flicker cause). Users on
modern GPUs can now opt in without a build change. Verified the module-top boot path runs cleanly (exit 0,
empty stderr) with the new pre-ready settings read.*
- [x] **W16 — Touch targets too small / hover-only labels.** Icon-only row actions are ~32px, 4px apart,
4 per row (below the ~40px touch guideline), and their only labels are hover tooltips (`Hint`) that
never appear on touch. **Standard:** ≥40px touch targets and non-hover labels. *(extends UX17)* *Fixed: