Skip to content

Fix/ios share context menu#176199

Merged
auto-submit[bot] merged 9 commits intoflutter:masterfrom
muradhossin:fix/ios-share-context-menu
Jan 6, 2026
Merged

Fix/ios share context menu#176199
auto-submit[bot] merged 9 commits intoflutter:masterfrom
muradhossin:fix/ios-share-context-menu

Conversation

@muradhossin
Copy link
Contributor

This PR fixes #173491 by adding the missing 'Share' option to the default iOS SystemContextMenu when shareEnabled is true.

Changes:

Added IOSSystemContextMenuItemShare to getDefaultItems in system_context_menu.dart.
Added a widget test to ensure Share is present in the default items for non-empty selections on iOS.
Rationale:
This aligns Flutter's default iOS text selection context menu with native iOS behavior, ensuring users see the expected 'Share' option when selecting text.

Demo:
Video showing Share option in iOS context menu: https://github.com/user-attachments/assets/e04cd1f9-7d92-4147-a09b-719f03d9c625

@github-actions github-actions bot added the framework flutter/packages/flutter repository. See also f: labels. label Sep 29, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request correctly adds the missing 'Share' option to the default iOS SystemContextMenu when shareEnabled is true, aligning Flutter's behavior with native iOS. The change is simple and effective, and it's accompanied by a thorough widget test to ensure the new functionality works as expected. I've included a few minor suggestions to improve code consistency and readability.

Comment on lines +166 to +167
if (editableTextState.liveTextInputEnabled) const IOSSystemContextMenuItemLiveText(),
if (editableTextState.shareEnabled) const IOSSystemContextMenuItemShare(),
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For consistency with the order of getters in EditableTextState, it would be better to place the shareEnabled check before liveTextInputEnabled. This improves logical grouping and maintainability, adhering to the style guide's principle of logical ordering.1

      if (editableTextState.shareEnabled) const IOSSystemContextMenuItemShare(),
      if (editableTextState.liveTextInputEnabled) const IOSSystemContextMenuItemLiveText(),

Style Guide References

Footnotes

  1. Other class members should be ordered logically (e.g., by lifecycle, or grouping related fields and methods). (link)

Copy link
Contributor

Choose a reason for hiding this comment

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

I would agree with that but no big deal if you have a reason for this ordering, @muradhossin .


testWidgets(
'Default iOS SystemContextMenu includes Share for non-empty selection',
(WidgetTester tester) async {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The indentation for the test callback seems off. Running dart format should fix this and ensure consistency with the rest of the file. This adheres to the Flutter style guide which mandates dart format usage.1

Suggested change
(WidgetTester tester) async {
(WidgetTester tester) async {

Style Guide References

Footnotes

  1. All Dart code is formatted using dart format. This is enforced by CI. (link)

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if this is right or not, I'll defer to the CI checks. If they're green it's ok.

Comment on lines +1351 to +1354
final List<IOSSystemContextMenuItemData> lastItems = untypedItems.map((dynamic value) {
final Map<String, dynamic> itemJson = value as Map<String, dynamic>;
return systemContextMenuItemDataFromJson(itemJson);
}).toList();
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This mapping can be simplified for better readability by using a collection for.

Suggested change
final List<IOSSystemContextMenuItemData> lastItems = untypedItems.map((dynamic value) {
final Map<String, dynamic> itemJson = value as Map<String, dynamic>;
return systemContextMenuItemDataFromJson(itemJson);
}).toList();
final List<IOSSystemContextMenuItemData> lastItems = <IOSSystemContextMenuItemData>[
for (final dynamic value in untypedItems)
systemContextMenuItemDataFromJson(value as Map<String, dynamic>),
];

Copy link
Contributor

Choose a reason for hiding this comment

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

This seems legit.

@justinmc justinmc self-requested a review October 14, 2025 22:19
Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

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

Thanks for fixing this. Did we just forget to add the share button here? It makes me really wish we could use a switch or something to ensure that we don't miss any other new subclasses.

Take a look at the analyzer failure, you're missing a type in your test.

Comment on lines +166 to +167
if (editableTextState.liveTextInputEnabled) const IOSSystemContextMenuItemLiveText(),
if (editableTextState.shareEnabled) const IOSSystemContextMenuItemShare(),
Copy link
Contributor

Choose a reason for hiding this comment

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

I would agree with that but no big deal if you have a reason for this ordering, @muradhossin .


testWidgets(
'Default iOS SystemContextMenu includes Share for non-empty selection',
(WidgetTester tester) async {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure if this is right or not, I'll defer to the CI checks. If they're green it's ok.

Comment on lines +1351 to +1354
final List<IOSSystemContextMenuItemData> lastItems = untypedItems.map((dynamic value) {
final Map<String, dynamic> itemJson = value as Map<String, dynamic>;
return systemContextMenuItemDataFromJson(itemJson);
}).toList();
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems legit.

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

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

Looks good besides the accidental changes in pubspec.lock.

Comment on lines +163 to +164
for (final ContextMenuButtonItem button in editableTextState.contextMenuButtonItems) {
switch (button.type) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This is great, now we know all button types are handled and always will be!

Comment on lines +1406 to +1411
expect(
itemsReceived.last.any(
(IOSSystemContextMenuItemData e) => e is IOSSystemContextMenuItemDataShare,
),
isTrue,
);
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: I wonder if there is a matcher that you could use here like contains? See https://main-api.flutter.dev/flutter/package-matcher_matcher/.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you revert the changes in this file?

Copy link
Contributor

@justinmc justinmc left a comment

Choose a reason for hiding this comment

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

LGTM 👍, thanks for following through on this PR!

for (final ContextMenuButtonItem button in editableTextState.contextMenuButtonItems) {
switch (button.type) {
case ContextMenuButtonType.copy:
items.add(const IOSSystemContextMenuItemCopy());
Copy link
Member

Choose a reason for hiding this comment

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

Does editableTextState.copyEnabled etc not need to be checked any more?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

contextMenuButtonItems already applies those enable-checks for us.

So by iterating editableTextState.contextMenuButtonItems, we’re consuming the filtered set — only enabled actions are present.

That’s why we no longer need separate editableTextState.copyEnabled etc checks here — the switch is now operating on the already-screened model, which is the single source of truth for both Flutter-rendered and native menus.

@muradhossin
Copy link
Contributor Author

@justinmc May I know if there’s any update on the merge?

@justinmc justinmc requested a review from dkwingsmt November 25, 2025 23:09
Copy link
Contributor

@dkwingsmt dkwingsmt left a comment

Choose a reason for hiding this comment

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

LGTM. Thank you!

@justinmc
Copy link
Contributor

@muradhossin Can you fix the analyzer failure here?

Fixes flutter#173491.

This adds IOSSystemContextMenuItemShare to the default iOS system
context menu items when shareEnabled is true, ensuring native 'Share'
option appears for text selections.
@muradhossin muradhossin requested review from a team and jtmcdole as code owners December 31, 2025 09:06
@github-actions github-actions bot added a: tests "flutter test", flutter_test, or one of our tests a: text input Entering text in a text field or keyboard related problems platform-android Android applications specifically platform-ios iOS applications specifically tool Affects the "flutter" command-line tool. See also t: labels. engine flutter/engine related. See also e: labels. f: material design flutter/packages/flutter/material repository. a: accessibility Accessibility, e.g. VoiceOver or TalkBack. (aka a11y) platform-fuchsia Fuchsia code specifically f: scrolling Viewports, list views, slivers, etc. f: cupertino flutter/packages/flutter/cupertino repository platform-windows Building on or for Windows specifically labels Dec 31, 2025
@github-actions github-actions bot removed platform-web Web applications specifically platform-linux Building on or for Linux specifically a: desktop Running on desktop f: integration_test The flutter/packages/integration_test plugin e: impeller Impeller rendering backend issues and features requests team-android Owned by Android platform team team-ios Owned by iOS platform team labels Dec 31, 2025
@muradhossin
Copy link
Contributor Author

muradhossin commented Dec 31, 2025

@muradhossin Can you fix the analyzer failure here?

@justinmc Could you please guide me on why many of the checks are failing?

@LouiseHsu
Copy link
Contributor

@muradhossin Can you fix the analyzer failure here?

@justinmc Could you please guide me on why many of the checks are failing?

can you try removing your changes to pubspec.lock and then merge master?

@LouiseHsu LouiseHsu added the autosubmit Merge PR when tree becomes green via auto submit App label Jan 6, 2026
@auto-submit auto-submit bot added this pull request to the merge queue Jan 6, 2026
Merged via the queue into flutter:master with commit eb7fb9a Jan 6, 2026
71 checks passed
@flutter-dashboard flutter-dashboard bot removed the autosubmit Merge PR when tree becomes green via auto submit App label Jan 6, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jan 7, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jan 7, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jan 7, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jan 7, 2026
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Jan 7, 2026
auto-submit bot pushed a commit to flutter/packages that referenced this pull request Jan 7, 2026
Roll Flutter from 13b2b91 to 01d37bc (74 revisions)

flutter/flutter@13b2b91...01d37bc

2026-01-07 [email protected] Replace Hybrid Composition wiki page with dev-facing content (flutter/flutter#180642)
2026-01-07 [email protected] Improve code quality in `FlutterActivityTest.java` (flutter/flutter#180585)
2026-01-07 [email protected] Roll Dart SDK to 3.11.0-296.1.beta (flutter/flutter#180633)
2026-01-07 [email protected] Bump target Windows version to 10 (flutter/flutter#180624)
2026-01-07 [email protected] Run hook_user_defines and link_hook integration tests on CI (flutter/flutter#180622)
2026-01-07 [email protected] Fix division by zero in RenderTable intrinsic size methods (flutter/flutter#178217)
2026-01-07 [email protected] Remove more  `requires 24` anotations (flutter/flutter#180116)
2026-01-07 [email protected] Roll Skia from 3971dbb85d45 to c5359a4d720e (1 revision) (flutter/flutter#180631)
2026-01-07 [email protected] Fix TabBar.image does not render at initialIndex for the first time (flutter/flutter#179616)
2026-01-07 [email protected] Roll Skia from 1e7ad625f6f7 to 3971dbb85d45 (3 revisions) (flutter/flutter#180627)
2026-01-07 [email protected] Unpin DDS (flutter/flutter#180571)
2026-01-07 [email protected] Fix DropdownMenuEntry.style not resolved when entry is highlighted (flutter/flutter#178873)
2026-01-07 [email protected] Remove unnecessary `@RequiresApi24` annotations from FlutterFragment methods (flutter/flutter#180117)
2026-01-07 [email protected] Roll Skia from 7fc63228056b to 1e7ad625f6f7 (1 revision) (flutter/flutter#180616)
2026-01-07 [email protected] Roll Fuchsia Linux SDK from QfR2ZFZ5kGTD3raO3... to dTvN_JVSCfGFRasvH... (flutter/flutter#180612)
2026-01-07 [email protected] [ Widget Preview ] Add support for `dart:ffi` imports (flutter/flutter#180586)
2026-01-07 [email protected] Roll Skia from eec90000a899 to 7fc63228056b (2 revisions) (flutter/flutter#180608)
2026-01-07 [email protected] Add --web-define flag for template variable injection in Flutter web builds (flutter/flutter#175805)
2026-01-07 [email protected] docs(engine): update rbe notes (flutter/flutter#180599)
2026-01-06 [email protected] Roll Skia from b6249496c230 to eec90000a899 (3 revisions) (flutter/flutter#180602)
2026-01-06 [email protected] Forward proxy 404 responses to client (flutter/flutter#179858)
2026-01-06 [email protected] Roll Dart SDK from 40a8c6188f7f to d2e3ce177270 (1 revision) (flutter/flutter#180598)
2026-01-06 [email protected] Restore CLI precedence for web headers and HTTPS over web_dev_config.yaml (flutter/flutter#179639)
2026-01-06 [email protected] Roll Skia from f5d9da13d56d to b6249496c230 (1 revision) (flutter/flutter#180596)
2026-01-06 [email protected] Enable misc leak tracking (flutter/flutter#176992)
2026-01-06 [email protected] [hooks] Don't require NDK for Android targets (flutter/flutter#180594)
2026-01-06 [email protected] [skia] Disable legacy non-const SkData APIs (flutter/flutter#179684)
2026-01-06 [email protected] Fix/ios share context menu (flutter/flutter#176199)
2026-01-06 [email protected] Roll Skia from b970aeffa66f to f5d9da13d56d (5 revisions) (flutter/flutter#180588)
2026-01-06 [email protected] Manually bump dependencies (flutter/flutter#180509)
2026-01-06 [email protected] Roll Dart SDK from 8150be8a0e48 to 40a8c6188f7f (2 revisions) (flutter/flutter#180582)
2026-01-06 [email protected] Roll Packages from 12eb764 to d3f860d (2 revisions) (flutter/flutter#180581)
2026-01-06 [email protected] Roll Fuchsia Test Scripts from MHF-UAfO6sVKqSEYk... to nR2ESa1Gd8yPcWo06... (flutter/flutter#180578)
2026-01-06 [email protected] Add tooltip support to PlatformMenuItem and PlatformMenu. (flutter/flutter#180069)
2026-01-06 [email protected] Add DropdownMenuFormField.errorBuilder (flutter/flutter#179345)
2026-01-06 [email protected] Roll Skia from 1845397e11ba to b970aeffa66f (2 revisions) (flutter/flutter#180566)
2026-01-06 [email protected] Don't embed unreferenced assets (flutter/flutter#179251)
2026-01-06 [email protected] Improve documentation about ValueNotifier's behavior (flutter/flutter#179870)
2026-01-06 [email protected] Roll Skia from 904ba00331ca to 1845397e11ba (5 revisions) (flutter/flutter#180558)
2026-01-06 [email protected] Roll Dart SDK from 2fb9ad834c4d to 8150be8a0e48 (1 revision) (flutter/flutter#180557)
2026-01-06 [email protected] Roll Skia from 98c042dde68c to 904ba00331ca (3 revisions) (flutter/flutter#180550)
2026-01-06 [email protected] Roll Dart SDK from ba9f7f790966 to 2fb9ad834c4d (2 revisions) (flutter/flutter#180548)
2026-01-06 [email protected] Roll Fuchsia Linux SDK from ubBGcRaAKWKihQ4ac... to QfR2ZFZ5kGTD3raO3... (flutter/flutter#180547)
2026-01-06 [email protected] Make sure that a DraggableScrollableSheet doesn't crash in 0x0 enviro… (flutter/flutter#180433)
2026-01-06 [email protected] Make sure that a ColorFiltered doesn't crash 0x0 environment (flutter/flutter#180307)
2026-01-06 [email protected] Make sure that a FadeInImage doesn't crash in 0x0 environment (flutter/flutter#180495)
...
ivan-vanyusho pushed a commit to ivan-vanyusho/packages that referenced this pull request Jan 26, 2026
Roll Flutter from 13b2b91 to 01d37bc (74 revisions)

flutter/flutter@13b2b91...01d37bc

2026-01-07 [email protected] Replace Hybrid Composition wiki page with dev-facing content (flutter/flutter#180642)
2026-01-07 [email protected] Improve code quality in `FlutterActivityTest.java` (flutter/flutter#180585)
2026-01-07 [email protected] Roll Dart SDK to 3.11.0-296.1.beta (flutter/flutter#180633)
2026-01-07 [email protected] Bump target Windows version to 10 (flutter/flutter#180624)
2026-01-07 [email protected] Run hook_user_defines and link_hook integration tests on CI (flutter/flutter#180622)
2026-01-07 [email protected] Fix division by zero in RenderTable intrinsic size methods (flutter/flutter#178217)
2026-01-07 [email protected] Remove more  `requires 24` anotations (flutter/flutter#180116)
2026-01-07 [email protected] Roll Skia from 3971dbb85d45 to c5359a4d720e (1 revision) (flutter/flutter#180631)
2026-01-07 [email protected] Fix TabBar.image does not render at initialIndex for the first time (flutter/flutter#179616)
2026-01-07 [email protected] Roll Skia from 1e7ad625f6f7 to 3971dbb85d45 (3 revisions) (flutter/flutter#180627)
2026-01-07 [email protected] Unpin DDS (flutter/flutter#180571)
2026-01-07 [email protected] Fix DropdownMenuEntry.style not resolved when entry is highlighted (flutter/flutter#178873)
2026-01-07 [email protected] Remove unnecessary `@RequiresApi24` annotations from FlutterFragment methods (flutter/flutter#180117)
2026-01-07 [email protected] Roll Skia from 7fc63228056b to 1e7ad625f6f7 (1 revision) (flutter/flutter#180616)
2026-01-07 [email protected] Roll Fuchsia Linux SDK from QfR2ZFZ5kGTD3raO3... to dTvN_JVSCfGFRasvH... (flutter/flutter#180612)
2026-01-07 [email protected] [ Widget Preview ] Add support for `dart:ffi` imports (flutter/flutter#180586)
2026-01-07 [email protected] Roll Skia from eec90000a899 to 7fc63228056b (2 revisions) (flutter/flutter#180608)
2026-01-07 [email protected] Add --web-define flag for template variable injection in Flutter web builds (flutter/flutter#175805)
2026-01-07 [email protected] docs(engine): update rbe notes (flutter/flutter#180599)
2026-01-06 [email protected] Roll Skia from b6249496c230 to eec90000a899 (3 revisions) (flutter/flutter#180602)
2026-01-06 [email protected] Forward proxy 404 responses to client (flutter/flutter#179858)
2026-01-06 [email protected] Roll Dart SDK from 40a8c6188f7f to d2e3ce177270 (1 revision) (flutter/flutter#180598)
2026-01-06 [email protected] Restore CLI precedence for web headers and HTTPS over web_dev_config.yaml (flutter/flutter#179639)
2026-01-06 [email protected] Roll Skia from f5d9da13d56d to b6249496c230 (1 revision) (flutter/flutter#180596)
2026-01-06 [email protected] Enable misc leak tracking (flutter/flutter#176992)
2026-01-06 [email protected] [hooks] Don't require NDK for Android targets (flutter/flutter#180594)
2026-01-06 [email protected] [skia] Disable legacy non-const SkData APIs (flutter/flutter#179684)
2026-01-06 [email protected] Fix/ios share context menu (flutter/flutter#176199)
2026-01-06 [email protected] Roll Skia from b970aeffa66f to f5d9da13d56d (5 revisions) (flutter/flutter#180588)
2026-01-06 [email protected] Manually bump dependencies (flutter/flutter#180509)
2026-01-06 [email protected] Roll Dart SDK from 8150be8a0e48 to 40a8c6188f7f (2 revisions) (flutter/flutter#180582)
2026-01-06 [email protected] Roll Packages from 12eb764 to d3f860d (2 revisions) (flutter/flutter#180581)
2026-01-06 [email protected] Roll Fuchsia Test Scripts from MHF-UAfO6sVKqSEYk... to nR2ESa1Gd8yPcWo06... (flutter/flutter#180578)
2026-01-06 [email protected] Add tooltip support to PlatformMenuItem and PlatformMenu. (flutter/flutter#180069)
2026-01-06 [email protected] Add DropdownMenuFormField.errorBuilder (flutter/flutter#179345)
2026-01-06 [email protected] Roll Skia from 1845397e11ba to b970aeffa66f (2 revisions) (flutter/flutter#180566)
2026-01-06 [email protected] Don't embed unreferenced assets (flutter/flutter#179251)
2026-01-06 [email protected] Improve documentation about ValueNotifier's behavior (flutter/flutter#179870)
2026-01-06 [email protected] Roll Skia from 904ba00331ca to 1845397e11ba (5 revisions) (flutter/flutter#180558)
2026-01-06 [email protected] Roll Dart SDK from 2fb9ad834c4d to 8150be8a0e48 (1 revision) (flutter/flutter#180557)
2026-01-06 [email protected] Roll Skia from 98c042dde68c to 904ba00331ca (3 revisions) (flutter/flutter#180550)
2026-01-06 [email protected] Roll Dart SDK from ba9f7f790966 to 2fb9ad834c4d (2 revisions) (flutter/flutter#180548)
2026-01-06 [email protected] Roll Fuchsia Linux SDK from ubBGcRaAKWKihQ4ac... to QfR2ZFZ5kGTD3raO3... (flutter/flutter#180547)
2026-01-06 [email protected] Make sure that a DraggableScrollableSheet doesn't crash in 0x0 enviro… (flutter/flutter#180433)
2026-01-06 [email protected] Make sure that a ColorFiltered doesn't crash 0x0 environment (flutter/flutter#180307)
2026-01-06 [email protected] Make sure that a FadeInImage doesn't crash in 0x0 environment (flutter/flutter#180495)
...
engine-flutter-autoroll added a commit to engine-flutter-autoroll/packages that referenced this pull request Feb 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

framework flutter/packages/flutter repository. See also f: labels.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[iOS] iOS system context menu is missing the "Share" button

5 participants