Skip to content

perf(music): render at 120 Hz on macOS and stop invisible player work - #178

Merged
A-EDev merged 6 commits into
mainfrom
perf/music-frame-discipline
Oct 25, 2026
Merged

A-EDev merged 6 commits into
mainfrom
perf/music-frame-discipline

Conversation

@A-EDev

@A-EDev A-EDev commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

Part 1 of 22 of the music player plan (Android parity). First of the stack; the rest build on it.

  • WebKit's "Prefer Page Rendering Updates near 60fps" feature is on by default, so Flow drew at 60 fps on 120 Hz ProMotion screens. The main and pop-out windows turn it off through WKPreferences' feature list (macos_window::allow_full_frame_rate, every step checks the selector first). Measured in the app: 60 fps before, 120 after.
  • The full player's seek bar follows the audio element every frame while it is open and playing (Android's precise-progress rule), and a drag seeks once on release instead of on every pointer move. The Shorts bar gets seek-on-release too.
  • The music store publishes the playback time once per whole second instead of about 4 times, so every music card's selectors run a quarter as often.
  • While the opaque full player covers the window, the routed page is inert and content-visibility: hidden, so its waves, spinners and shimmers stop painting. Scroll position survives (checked: 600 before and after).

Related issue

Change type

  • Bug fix
  • Feature
  • Refactor or maintenance
  • Documentation
  • Build, packaging, or CI

Validation

  • pnpm test: 369 tests passed, 0 failed
  • pnpm build: passed
  • cargo fmt --manifest-path src-tauri/Cargo.toml --all -- --check: clean
  • cargo clippy --manifest-path src-tauri/Cargo.toml --all-targets --all-features: no new warnings against main (compared at the top of the stack)
  • cargo test --manifest-path src-tauri/Cargo.toml --all-targets --all-features: 781 passed, 0 failed (all sync_* suites included)
  • I smoke-tested the affected desktop behavior. macOS, MacBook Pro 120 Hz: frame rate 60 to 120 fps; seek bar moves smoothly while playing (distinct values every 60 ms) and is still when paused (0 frame callbacks); a drag gives 0 seeks while moving and 1 on release; store writes 4 in 4 s; page covered and uncovered with its scroll kept.
  • OS/device: device testing by the owner. The checks above ran on macOS 27 (Apple Silicon MacBook Pro, 120 Hz) in a dev build of the whole stack; Windows and Linux were not run.

Screenshots or recordings

Risk and compatibility

  • macOS uses the private WKPreferences feature API, guarded by respondsToSelector; on a WebKit without it nothing changes and an info line is logged.
  • Higher frame rate means more frames while something animates; every loop in this stack stops when hidden or paused.
  • New dependencies: objc2 0.6 for macOS (already in the lockfile through wry).
  • No new secrets, private data, telemetry, or broad Tauri permissions were introduced.
  • User-facing documentation was updated where needed (changelog entry in v0.1.0-beta3.txt).
  • Dependency and lockfile changes are intentional and limited to this PR.
  • Breaking changes and upgrade steps are clearly documented. No breaking changes.

Copilot AI balanced review requested due to automatic review settings October 24, 2026 14:18

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@A-EDev
A-EDev merged commit 9c21efe into main Oct 25, 2026
7 checks passed
@A-EDev
A-EDev deleted the perf/music-frame-discipline branch October 29, 2026 21:09
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.

2 participants