tabs.rs had grown to 538 lines — past the 500-line ceiling — and was
mixing four unrelated concerns:
- `tab_navigation` (URL changes + history back/forward)
- `tab_metadata` (title, favicon, zoom, favorite/pin, sort, sync flag)
- `tab_archive_restore` (un-archive entry points + query matching)
- core CRUD (open / close / move-to-space + private helpers)
Each split file lives below 250 lines and only pulls the `ely_domain`
types and crate helpers it actually uses. `active_tab_mut` and the
`TabUrlUpdate` enum get `pub(super)` so siblings can reach them; no
behaviour change.
Lift `apply_viewport`'s three-way diff (resize / set_hidpi / set_zoom)
into a `ViewportChange` value so the decision is testable without a
running `SoftwareServoHost`. Four unit cases pin the contract:
- Retina creation (DPR=2.0): only the hidpi push fires (the bug above).
- Standard-DPI creation (DPR=1.0): nothing to push, session already
matches Servo's defaults.
- Mid-session zoom change: only `set_page_zoom` fires.
- Cross-monitor DPR change: only the hidpi push fires.
This is a regression guard for the previous commit — any future change
that re-initializes a session from request values instead of Servo's
post-build defaults will fail `fresh_retina_session_pushes_hidpi_only`.
The newly-created session was stamped with the request's hidpi factor,
but `WebViewBuilder` defaults `hidpi_scale_factor` to 1.0 and we never
override it. `apply_viewport`'s diff check then saw
`session.dpr == request.dpr` and skipped `set_hidpi_scale`, leaving Servo
at hidpi=1.0 forever. On Retina that collapses CSS pixels onto device
pixels — the page lays out for a 2× viewport and renders at half size.
Same shape applies to page zoom.
Initialize the session with Servo's actual post-build defaults so the
viewport diff is the source of truth for whether `set_hidpi_scale` and
`set_page_zoom` need to run.
`move_traffic_light` was framing the close / minimize / zoom NSButtons
at `titlebar_height - traffic_light_position.y - button_h`. Once the
window opts into `NSFullSizeContentViewWindowMask`, the content layout
rectangle covers the whole frame and `titlebar_height()` returns 0 —
collapsing the origin to a large negative Y. macOS still painted the
buttons through its own caching layer at the title bar's natural
position, but the buttons' hit-test rectangle followed the frame off
screen, so clicking close / minimize / zoom did nothing.
Anchor the math against the close button's actual superview frame
height (the themeFrame, which equals the window height in Y-up
coordinates) so the visual position and the hit area stay in lockstep
no matter what mask combination the window opens with. `titlebar_height`
stays available for callers that want the legacy non-full-size
interpretation, with `#[allow(dead_code)]` and a docstring pointing at
this fix.