Skip to content

fix: keep the Cupertino top bar clear of the side safe-area insets - #972

Merged
diegotori merged 2 commits into
fluttercommunity:masterfrom
xsahil03x:fix/cupertino-top-bar-side-safe-area
Oct 20, 2026
Merged

diegotori merged 2 commits into
fluttercommunity:masterfrom
xsahil03x:fix/cupertino-top-bar-side-safe-area

Conversation

@xsahil03x

@xsahil03x xsahil03x commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #971.

CupertinoControls wrapped its bottom bar in a SafeArea but not its top bar, so outside fullscreen the top bar's end-side buttons (mute, cast, additional controls) sat under the notch or status rail on devices with a side inset: an iPhone in landscape, or the iPhone Duo in every pose.

The top bar is now wrapped in a SafeArea(top: false, bottom: false). It's sides only, because the player usually sits below the embedder's own header, where the top inset is already accounted for; padding the top would push the bar down by the status bar's height. In fullscreen, PlayerWithControls already applies its own SafeArea, so nothing changes there.

Verified with a test in test/uninitialized_controls_state_test.dart: the mute button stays clear of a right inset, and it fails without the fix. flutter test and flutter analyze pass.

🤖 Generated with Claude Code

@xsahil03x
xsahil03x force-pushed the fix/cupertino-top-bar-side-safe-area branch from cb98203 to 8f75652 Compare September 28, 2026 16:17
The bottom bar is wrapped in a SafeArea, but the top bar was not, so outside
fullscreen its buttons (mute, cast, additional controls) sat under a notch or
status rail on devices with a side inset. Pad the top bar by the side insets
only, since the player often sits below the embedder's own header where the
top inset has already been accounted for.

Fixes fluttercommunity#971

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 82.61%. Comparing base (d568acf) to head (be88d00).
⚠️ Report is 4 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #972   +/-   ##
=======================================
  Coverage   82.60%   82.61%           
=======================================
  Files          48       48           
  Lines        2967     2968    +1     
=======================================
+ Hits         2451     2452    +1     
  Misses        516      516           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@ibrahim-iqbal ibrahim-iqbal left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Fix is spot on — SafeArea(top: false, bottom: false) with the implicit left: true, right: true is exactly the right shape for a bar that sits inside an embedder that already owns the top inset. The test is particularly nice because the asserted invariant (mute button's right edge stays inside screenWidth - rightInset) is the actual user-facing symptom, so it's resistant to layout refactors.

Two tiny style nits, take or leave:

  • videoPlayerController and chewieController in the new test are never reassigned — final would read a touch cleaner.
  • expect(muteButton, findsOneWidget) before tester.getRect(muteButton.first) would make the test fail with a clearer message if the ancestor finder ever matches zero or multiple.

Neither blocks the merge.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@xsahil03x

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @ibrahim-iqbal!

  • Kept var: every test in this file uses it, so final would make this one the odd one out.
  • Added findsOneWidget in be88d00. While doing it I found the ancestor finder matched two GestureDetectors, so the test now measures the icon directly with find.byIcon(Icons.volume_up), which matches exactly one.

@diegotori this is ready for a look when you have a moment.

@diegotori diegotori left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM.

@diegotori
diegotori merged commit 8d85807 into fluttercommunity:master Oct 20, 2026
5 checks passed
diegotori added a commit that referenced this pull request Oct 20, 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.

CupertinoControls top bar ignores the side safe-area insets outside fullscreen

3 participants