fix(workspace): keep the macOS header clear of the lights when zoomed out (#1815)

* fix(workspace): keep the macOS header clear of the lights when zoomed out

App zoom scales CSS pixels but not the native traffic lights. At zoom
-3/-4 the header column starts near 29 window pixels, so Back and the
playlist switcher slid under the lights, and the 27px header band let
the lights overlap the context panel below.

A shell-level TrafficLightsClearanceDirective now publishes the lights'
clearance in CSS pixels (84 x 48 window pixels, from the page zoom
factor) on macOS. The header band grows to the vertical clearance (the
rail starts its first link at the same band, replacing the rail's own
zoom listener), and the header's leading padding grows to the
horizontal clearance less the rail column. Both equal the default
layout at 100 %; Windows/Linux and the phone layout are unchanged. The
native position is shared with the main process as
MACOS_TRAFFIC_LIGHTS_POSITION.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(workspace): pass the header clearance poll labels as options

Equivalent to the string form, which Playwright 1.62 also accepts, but
explicit in every version (Greptile review).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(workspace): check the header switcher before history exists

Since the header's history fallback, a list reached by navigation
leads with Back. The macOS check now takes the switcher on the first
page, which has nothing to go back to, and Back on a detail page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: 4gray <fourgray@proton.me>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
authored and GitHub committed 2026-10-06 19:15:58 +02:00
1 parent 5f21e240e9
commit 5e5b483dca
17 files changed
+519 -131

No files matched your search

+26 -9
View File
@@ -390,15 +390,32 @@ The Electron window hides the native title bar on all desktop platforms
(`titleBarStyle: 'hidden'` in `apps/electron-backend/src/app/app.ts`):
1. macOS keeps the native traffic lights (`titleBarOverlay: true`,
`trafficLightPosition`); the renderer draws no window buttons. The lights
sit in the 56 px header band above the rail, so the macOS rail
(`.app-rail.is-macos`) starts its first link at 56 px: level with the
content area and the dashboard hero, with its hover surface clear of the
lights. App zoom scales CSS pixels but not the lights, so the rail
publishes the page zoom factor (`outerWidth / innerWidth`, refreshed on
`resize`) as `--rail-zoom-factor` and keeps at least 48 window pixels when
zoomed out. `window-controls.e2e.ts` checks the alignment and the gap at
default and minimum zoom on macOS.
`trafficLightPosition` from `MACOS_TRAFFIC_LIGHTS_POSITION` in
`@iptvnator/shared/interfaces`); the renderer draws no window buttons.
The lights sit in the header band (`--workspace-header-band`, 56 px) over
the rail and the header's leading padding. The macOS rail
(`.app-rail.is-macos`) starts its first link below the band: level with
the content area and the dashboard hero, with its hover surface clear of
the lights. The header's content starts 84 window pixels from the
window's left edge (60 px rail plus 24 px padding). macOS 26 ends the
lights at 76 (earlier releases at 68), which is where Back's left edge
sits at 100 % because of its 8 px pull-in.
App zoom (see "Zoom level") scales CSS pixels but not the lights. On
macOS, `TrafficLightsClearanceDirective` on `.workspace-shell` reads the
page zoom factor (`outerWidth / innerWidth`, refreshed on `resize`) and
publishes the clearance in CSS pixels as `--traffic-lights-clear-x` (84
window pixels) and `--traffic-lights-clear-y` (48: the lights' bottom
plus a gap). Zoomed out, the band grows to the vertical clearance, so the
lights never overlap the content area. The header's leading padding grows
to the horizontal clearance, less the rail column
(`--workspace-header-lights-inset`). At 100 % both match the default
layout. Off macOS nothing is published and the defaults apply. The phone
layout, which puts the rail in a row above the header, ignores the
inset. `window-controls.e2e.ts` ("macOS traffic lights") checks the rail
alignment, the first header control (the switcher on the first page,
which has no history fallback yet, then a detail page's Back) and the
content top at default and minimum zoom.
2. Windows and Linux use renderer-drawn window controls
(`app-window-controls`, `libs/ui/components/src/lib/window-controls/`).
`frame` is intentionally left untouched so native resize borders and