Skip to content

Conversation

@ksokolovskyi
Copy link
Contributor

@ksokolovskyi ksokolovskyi commented Dec 18, 2025

Closes #180031

Description

  • Adds tooltip support to PlatformMenuItem and PlatformMenu
  • Updates platform_menu_bar_test.dart to cover tooltip related changes and makes test-specific code private
  • Updates FlutterMenuPlugin.mm to support tooltip
  • Updates FlutterMenuPluginTest.mm to cover tooltip related changes
tooltips.mov
Code sample
// THIS SAMPLE ONLY WORKS ON MACOS.

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

/// Flutter code sample for [PlatformMenuBar].

void main() => runApp(const ExampleApp());

enum MenuSelection { about, showMessage }

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: Scaffold(body: PlatformMenuBarExample()));
  }
}

class PlatformMenuBarExample extends StatefulWidget {
  const PlatformMenuBarExample({super.key});

  @override
  State<PlatformMenuBarExample> createState() => _PlatformMenuBarExampleState();
}

class _PlatformMenuBarExampleState extends State<PlatformMenuBarExample> {
  String _message = 'Hello';
  bool _showMessage = false;

  void _handleMenuSelection(MenuSelection value) {
    switch (value) {
      case MenuSelection.about:
        showAboutDialog(
          context: context,
          applicationName: 'MenuBar Sample',
          applicationVersion: '1.0.0',
        );
      case MenuSelection.showMessage:
        setState(() {
          _showMessage = !_showMessage;
        });
    }
  }

  @override
  Widget build(BuildContext context) {
    ////////////////////////////////////
    // THIS SAMPLE ONLY WORKS ON MACOS.
    ////////////////////////////////////

    // This builds a menu hierarchy that looks like this:
    // Flutter API Sample
    //  ├ About
    //  ├ ────────  (group divider)
    //  ├ Hide/Show Message
    //  ├ Messages
    //  │  ├ I am not throwing away my shot.
    //  │  └ There's a million things I haven't done, but just you wait.
    //  └ Quit
    return PlatformMenuBar(
      menus: <PlatformMenuItem>[
        PlatformMenu(
          label: 'Flutter API Sample',
          menus: <PlatformMenuItem>[
            PlatformMenuItemGroup(
              members: <PlatformMenuItem>[
                PlatformMenuItem(
                  label: 'About',
                  tooltip: 'Show information about APP_NAME',
                  onSelected: () {
                    _handleMenuSelection(MenuSelection.about);
                  },
                ),
              ],
            ),
            PlatformMenuItemGroup(
              members: <PlatformMenuItem>[
                PlatformMenuItem(
                  onSelected: () {
                    _handleMenuSelection(MenuSelection.showMessage);
                  },
                  shortcut: const CharacterActivator('m'),
                  label: _showMessage ? 'Hide Message' : 'Show Message',
                  tooltip: _showMessage
                      ? 'The message will be hidden.'
                      : 'The message will be shown.',
                ),
                PlatformMenu(
                  label: 'Messages',
                  menus: <PlatformMenuItem>[
                    PlatformMenuItem(
                      label: 'I am not throwing away my shot.',
                      shortcut: const SingleActivator(
                        LogicalKeyboardKey.digit1,
                        meta: true,
                      ),
                      onSelected: () {
                        setState(() {
                          _message = 'I am not throwing away my shot.';
                        });
                      },
                    ),
                    PlatformMenuItem(
                      label:
                          "There's a million things I haven't done, but just you wait.",
                      shortcut: const SingleActivator(
                        LogicalKeyboardKey.digit2,
                        meta: true,
                      ),
                      onSelected: () {
                        setState(() {
                          _message =
                              "There's a million things I haven't done, but just you wait.";
                        });
                      },
                    ),
                  ],
                ),
              ],
            ),
            if (PlatformProvidedMenuItem.hasMenu(
              PlatformProvidedMenuItemType.quit,
            ))
              const PlatformProvidedMenuItem(
                type: PlatformProvidedMenuItemType.quit,
              ),
          ],
        ),
      ],
      child: Center(
        child: Text(
          _showMessage
              ? _message
              : 'This space intentionally left blank.\n'
                    'Show a message here using the menu.',
        ),
      ),
    );
  }
}

Pre-launch Checklist

@github-actions github-actions bot added framework flutter/packages/flutter repository. See also f: labels. engine flutter/engine related. See also e: labels. a: desktop Running on desktop platform-macos labels Dec 18, 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 introduces tooltip support for platform menu items in Flutter. The changes involve adding a tooltip property to PlatformMenu and PlatformMenuItem in the Dart API, serializing this property through the platform channel, and implementing its display on the native macOS side. The native implementation also includes logic to replace kAppName within tooltips. Unit tests were updated to reflect these changes, including adding tooltip values to test menu structures and verifying their presence. The reviewer suggested updating the documentation for the PlatformMenu and PlatformMenuItem constructors to explicitly mention the new tooltip parameter, in line with the Flutter Style Guide.

class PlatformMenu extends PlatformMenuItem with DiagnosticableTreeMixin {
/// Creates a const [PlatformMenu].
///
/// The [label] and [menus] fields are required.
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 documentation for the PlatformMenu constructor should be updated to mention the new tooltip parameter. According to the Flutter Style Guide, all public members should have documentation.

Suggested change
/// The [label] and [menus] fields are required.
/// The [label] and [menus] fields are required. The [tooltip] is optional.
References
  1. All public members should have documentation. The constructor is a public member and the new tooltip parameter should be documented. (link)

class PlatformMenuItem with Diagnosticable {
/// Creates a const [PlatformMenuItem].
///
/// The [label] attribute is required.
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 documentation for the PlatformMenuItem constructor should be updated to include the new tooltip parameter. According to the Flutter Style Guide, all public members should have documentation.

Suggested change
/// The [label] attribute is required.
/// The [label] attribute is required. The [tooltip] is optional.
References
  1. All public members should have documentation. The constructor is a public member and the new tooltip parameter should be documented. (link)

@hellohuanlin hellohuanlin requested review from a team and hellohuanlin December 18, 2025 22:41
[item setTitle:[[item title] stringByReplacingOccurrencesOfString:kAppName
withString:appName]];
}
if ([item toolTip] && [[item toolTip] containsString:kAppName]) {
Copy link
Contributor

Choose a reason for hiding this comment

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

no need to check [item toolTip]

@ksokolovskyi ksokolovskyi added the autosubmit Merge PR when tree becomes green via auto submit App label Jan 6, 2026
@ksokolovskyi
Copy link
Contributor Author

@hellohuanlin thanks a lot for your review!

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

Labels

a: desktop Running on desktop engine flutter/engine related. See also e: labels. framework flutter/packages/flutter repository. See also f: labels. platform-macos

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add .toolTip property to PlatformMenuBar's PlatformMenuItem class

2 participants