feat: make SystemContextMenuController.isVisible part of the public API#185720
feat: make SystemContextMenuController.isVisible part of the public API#185720shivanshu877 wants to merge 2 commits into
Conversation
The SystemContextMenuController.isVisible getter was annotated with @VisibleForTesting, which meant production code could only access it with a lint warning. There are legitimate use cases for accessing this state outside of tests: - Stretchable text fields (e.g. Liquid Glass) need to skip redundant show() calls when the menu is already visible at the desired target rect, to avoid the menu briefly flashing in and out as the rect changes by sub-pixel amounts during a transformation. This change removes the @VisibleForTesting annotation and expands the docstring to describe the intended use case. Fixes: flutter#179263
|
It looks like this pull request may not have tests. Please make sure to add tests or get an explicit test exemption before merging. If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. If you believe this PR qualifies for a test exemption, contact "@test-exemption-reviewer" in the #hackers channel in Discord (don't just cc them here, they won't see it!). The test exemption team is a small volunteer group, so all reviewers should feel empowered to ask for tests, without delegating that responsibility entirely to the test exemption group. |
There was a problem hiding this comment.
Code Review
This pull request removes the @VisibleForTesting annotation from the isVisible getter in SystemContextMenuController and adds documentation explaining how to use it to avoid redundant show or hide calls. A review comment suggests clarifying that isVisible only tracks visibility and not position, advising that callers remain responsible for tracking the target Rect to ensure the menu updates when its position changes.
|
Per @stuartmorgan-g's broader feedback (#186238 comment): This PR is annotation-only — it removes |
|
Hi @shivanshu877, thank you for the contribution! It would be valuable to see an example of how exposing |
|
Thanks for the review, @Renzo-Olivares! You're right that The specific scenario is: during a stretchy text-field resize (Liquid Glass / iOS auto-grow), tiny layout changes trigger repeated if (!_controller.isVisible || _lastRect != newRect) {
_controller.show(newRect);
_lastRect = newRect;
}This skips the redundant hide/re-show cycle when the rect is unchanged or trivially different. |
Renzo-Olivares
left a comment
There was a problem hiding this comment.
Thank you for the response @shivanshu877. Is the image below the liquid glass stretch effect you are referring to? If so it feels like the tap and drag that you have to do to initiate the stretch animation will end up dismissing the system context menu and there is no way to prevent that.
Screen.Recording.2026-05-15.at.2.52.00.PM.mov
|
Thanks for the video, @Renzo-Olivares — you're right about the Liquid Glass stretch specifically. The tap-and-drag gesture lands outside the menu's bounds, so iOS fires Where it does help is the class of programmatic re-show patterns where the same code path keeps calling Happy to narrow the docstring to reflect that scope. Two options — let me know which you prefer:
|
|
Hi @shivanshu877, it would be helpful if you could provide a minimal example that I can run on a physical device, of the use-case you are referring to. It should the new |
|
Built a minimal demo, source at https://github.com/shivanshu877/isvisible-demo, screen recording from a physical iPhone 16 / iOS 26.4.2 here: https://github.com/shivanshu877/isvisible-demo/releases/tag/v0.1. The reproduction is a The existing dedup in If you'd prefer a different API surface — exposing |
|
/cc @Renzo-Olivares from text input triage |
Description
SystemContextMenuController.isVisiblewas annotated with@visibleForTesting, which meant production code could only access it with a lint warning. There are legitimate use cases for accessing this state outside of tests.This PR removes the
@visibleForTestingannotation and expands the docstring to describe the intended use case.Use case
When building a stretchable text field (e.g. Liquid Glass), small sub-pixel changes to the target
Rectcauseshow()to hide and re-show the system context menu, producing visible flashing. With public access toisVisible, callers can skip redundantshow()calls when the menu is already visible at the desired target.Behavior change
None. The runtime behavior of
isVisibleis unchanged — only the visibility of the API is widened.Tests
Existing tests in
packages/flutter/test/services/system_context_menu_controller_test.dartcover theisVisiblegetter (14 assertions across 14 test cases). All pass with this change.Fixes #179263
Pre-launch Checklist
///).