Fly-by clean-up: My understanding from the
[changelog](https://pub.dev/packages/dds/changelog) is that the change
causing the bug in 5.0.4 has been reverted in 5.0.5. Therefore, the pin
should be no longer necessary? Unpinning to find out...
> 5.0.5
[DAP] The change in DDS 5.0.4 to individually add/remove breakpoints has
been reverted and may be restored in a future version.
>
>5.0.4
[DAP] Breakpoints are now added/removed individually instead of all
being cleared and re-added during a setBreakpoints request. This
improves performance and can avoid breakpoints flickering between
unresolved/resolved when adding new breakpoints in the same file.
## Description
This PR adds logic to resolve `DropdownMenuEntry.style` properties with
the correct `WidgetState` when an item is highlighted.
When `MenuItemButton` are highlighted the focused state is not added
automatically because the focus does not move to the items (it stays on
the `TextField` in order to let the user enters text to filter the items
list). This PR sets the `MenuItemButton.statesController` with a forced
focused state to let `MenuItemButton` know that the focused state should
be use to resolve the properties.
## Related Issue
Fixes [DropdownMenuEntry style's text style is not resolving with
states](https://github.com/flutter/flutter/issues/177363)
## Tests
- Adds 1 tests.
Adds logic to pass `--include-unsupported-platform-library-stubs` to the
CFE when launched via `flutter widget-preview start`, as well as logic
to ensure the flag can't be passed as an extra frontend option to bypass
compile time errors due to imports of unsupported libraries.
Fixes https://github.com/flutter/flutter/issues/166431
<!--
Thanks for filing a pull request!
Reviewers are typically assigned within a week of filing a request.
To learn more about code review, see our documentation on Tree Hygiene:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
-->
## Add --web-define option for runtime variable injection in Flutter web
templates
This PR adds support for injecting environment-specific variables into
Flutter web templates during development and build processes through a
new `--web-define` command-line option.
### What this changes
**Before**: Developers had to manually edit HTML templates or use
build-time workarounds to inject environment-specific values (API URLs,
feature flags, etc.) into Flutter web applications.
**After**: Developers can now use `--web-define KEY=VALUE` to inject
variables directly into web templates using `{{VARIABLE_NAME}}`
placeholders.
### Key features
- **Template variable substitution**: Support for `{{VARIABLE_NAME}}`
placeholders in `index.html` and `flutter_bootstrap.js`
- **Runtime validation**: Throws clear errors when required variables
are missing with helpful suggestions
- **Command-line integration**: Works with both `flutter run` and
`flutter build web` commands
- **Multiple variable support**: Can define multiple variables in a
single command
- **Built-in variable protection**: Ignores Flutter's built-in template
variables during validation
### Usage examples
```bash
# Development with API configuration
flutter run -d chrome --web-define=API_URL=https://dev-api.example.com --web-define=DEBUG_MODE=true
# Production build with environment variables
flutter build web --web-define=API_URL=https://api.example.com --web-define=ANALYTICS_ID=GA-123456 --web-define=DEBUG_MODE=false
# Multiple environments
flutter run -d chrome --web-define=ENV=staging --web-define=FEATURE_X=enabled
```
### Template usage
In your `web/index.html`:
```html
<script>
window.config = {
apiUrl: '{{API_URL}}',
environment: '{{ENV}}',
debugMode: {{DEBUG_MODE}}
};
</script>
```
### Error handling
If a variable is missing, the tool provides clear feedback:
```
Missing web-define variable: API_URL
Please provide the missing variable using:
flutter run --web-define=API_URL=VALUE
or
flutter build web --web-define=API_URL=VALUE
```
## Issues fixed
Fixes https://github.com/flutter/flutter/issues/127853
## Additional Usage Examples
### Environment-Specific Configurations (Flavors)
```bash
# Development
flutter run -d chrome --web-define=ENV=dev --web-define=API_URL=http://localhost:3000 --web-define=DEBUG=true
# Production
flutter build web --web-define=ENV=prod --web-define=API_URL=https://api.example.com --web-define=DEBUG=false
```
**Template:**
```html
<script>
window.config = {
environment: '{{ENV}}',
apiUrl: '{{API_URL}}',
debugMode: {{DEBUG}}
};
</script>
```
### Dynamic Asset Loading
```bash
flutter build web --web-define=CDN_URL=https://cdn.example.com --web-define=LOGO_PATH=/assets/logo.png
```
**Template:**
```html
<link rel="icon" href="{{CDN_URL}}{{LOGO_PATH}}">
<link rel="stylesheet" href="{{CDN_URL}}/styles/theme.css">
```
### Analytics Integration
```bash
flutter build web --web-define=GA_ID=G-XXXXXXXXXX --web-define=SENTRY_DSN=https://xxx@sentry.io/123
```
**Template:**
```html
<script async src="https://www.googletagmanager.com/gtag/js?id={{GA_ID}}"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '{{GA_ID}}');
</script>
```
### Feature Flags
```bash
flutter run -d chrome --web-define=FEATURE_X=true --web-define=FEATURE_Y=false
```
**Template:**
```html
<script>
window.features = { featureX: {{FEATURE_X}}, featureY: {{FEATURE_Y}} };
</script>
```
### Multi-Tenant/White-Label Apps
```bash
flutter build web --web-define=TENANT=acme --web-define=PRIMARY_COLOR=#FF5733 --web-define=LOGO_URL=https://cdn.acme.com/logo.png
```
**Template:**
```html
<head>
<title>{{TENANT}} Portal</title>
<link rel="icon" href="{{LOGO_URL}}">
<style>:root { --primary: {{PRIMARY_COLOR}}; }</style>
</head>
```
### Backend Service URLs
```bash
flutter build web \
--web-define=API_URL=https://api.example.com \
--web-define=WS_URL=wss://ws.example.com \
--web-define=AUTH_DOMAIN=auth.example.com
```
**Template:**
```html
<script>
window.services = {
api: '{{API_URL}}',
websocket: '{{WS_URL}}',
auth: '{{AUTH_DOMAIN}}'
};
</script>
```
### SEO & Meta Tags
```bash
flutter build web --web-define=APP_TITLE="My App" --web-define=APP_DESC="Description" --web-define=OG_IMAGE=https://example.com/og.png
```
**Template:**
```html
<head>
<title>{{APP_TITLE}}</title>
<meta name="description" content="{{APP_DESC}}">
<meta property="og:title" content="{{APP_TITLE}}">
<meta property="og:image" content="{{OG_IMAGE}}">
</head>
```
### Build Automation
```json
{
"scripts": {
"dev": "flutter run -d chrome --web-define=ENV=dev --web-define=API_URL=http://localhost:3000",
"prod": "flutter build web --web-define=ENV=prod --web-define=API_URL=https://api.example.com"
}
}
```
### Important Notes
- **Security**: Never expose secrets via `--web-define` (client-side
only)
## Pre-launch Checklist
- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
If you need help, consider asking for advice on the #hackers-new channel
on [Discord].
**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.
<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
---------
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Ben Konyi <bkonyi@google.com>
Co-authored-by: Mouad Debbar <mdebbar@google.com>
This PR restores the correct precedence behavior for web development
server configuration. Since Flutter 3.38, CLI arguments were being
ignored when `web_dev_config.yaml` was present — specifically for HTTPS
and headers.
According to the design and documentation, the precedence should be:
1. Command-line arguments (highest priority)
2. `web_dev_config.yaml`
3. Built-in defaults (lowest priority)
## Root Cause
The regression affected:
* **HTTP headers** — merge order was reversed, causing file config to
override CLI
* **HTTPS config** — CLI TLS arguments were ignored under certain
conditions
Note:
`--web-port` and `--web-hostname` were already working correctly due to
the `host ?? this.host` and `port ?? this.port` pattern.
The observed issue was due to headers + HTTPS only.
## Changes Made
* Fixed header merge order so CLI takes precedence
* Corrected HTTPS config resolution and precedence logic
* Unified logic across `run` and `drive` commands
* Simplified HTTPS handling using `HttpsConfig.parse()`
* Added tests for CLI precedence behavior
## Before (broken)
```
flutter run -d chrome --web-tls-cert-path cert.pem
```
❌ CLI TLS args ignored when config file existed
❌ headers overridden by file config
## After (fixed)
```
flutter run -d chrome --web-tls-cert-path cert.pem
```
✅ CLI TLS args respected
✅ headers override config as expected
## Tests
* Added tests verifying CLI takes precedence
* All existing and new tests pass
* No breaking changes introduced
## Fixes
Fixes: #179014
---------
Co-authored-by: Kevin Moore <kevmoo@google.com>
Co-authored-by: Kevin Moore <kevmoo@users.noreply.github.com>
Co-authored-by: Ben Konyi <bkonyi@google.com>
When targeting Android, don't fail in Flutter tools if the NDK is not
installed. Instead, pass a `null` c compiler config to the hooks. The
hooks can then decide to fail if they need the NDK. If no hook happened
to require the NDK, Flutter for Android apps can be built without the
NDK installed.
Bug: https://github.com/flutter/flutter/issues/180163
## Pre-launch Checklist
- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
This PR fixes https://github.com/flutter/flutter/issues/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
Closes https://github.com/flutter/flutter/issues/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
https://github.com/user-attachments/assets/abafc1ec-dc2f-45ae-a3b5-1e88759dac37
<details closed><summary>Code sample</summary>
```dart
// 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.',
),
),
);
}
}
```
</details>
## Pre-launch Checklist
- [X] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [X] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [X] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [X] I signed the [CLA].
- [X] I listed at least one issue that this PR fixes in the description
above.
- [X] I updated/added relevant documentation (doc comments with `///`).
- [X] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [X] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [X] All existing and new tests are passing.
<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
## Description
This PR adds the `DropdownMenuFormField.errorBuilder` property which
makes it possible to customize the widget used to display the error
message.
This is a follow-up to https://github.com/flutter/flutter/pull/162255
which added the `errorBuilder` property to other form fields.
## Related Issue
Fixes [DropdownMenuFormField is missing an errorBuilder
property](https://github.com/flutter/flutter/issues/172416)
## Tests
Updates 5 tests.
Adds 1 test.
Summary
This PR improves the API documentation for ImageFilter.shader and
isShaderFilterSupported by making the Impeller requirement more explicit
and visible.
What was changed
Added an “Important” notice to clearly state that these APIs are only
supported with Impeller.
Updated the doc comments to front-load this detail instead of placing it
later in the text.
Added cross-reference notes explaining how isShaderFilterSupported
relates to Impeller.
Why this change is helpful
Developers frequently run into confusion when using shader-based filters
without realizing they require Impeller. This change makes the
requirement obvious and easier to discover.
Issue reference
Fixes#178767
There are existing compute unit tests in `compute_unittests.cc` but they
were not added to the build. Add them if `impeller_enable_compute` is
enabled.
Closes#179709
## Pre-launch Checklist
- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.
LLDB's type formatters expect the libcxx ABI namespace to start with two
leading underscores.
See [LLDB Discourse
Thread](https://discourse.llvm.org/t/lldb-type-summaries-not-displayed-for-libcxx-types/88447)
and [LLDB
Sources](5099c07fa0/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp (L761))
Fixes#180132
Note that this change requires a complete rebuild of the engine sources
- see related #180128
## Pre-launch Checklist
- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] All existing and new tests are passing.
DTD only supports a single instance of a registered service with a given
name. For widget preview development, we sometimes want to use a DTD
instance that's attached to an IDE to test IDE integration. However,
IDEs frequently spawn their own widget preview instances which register
services with DTD. In the case where `flutter widget-preview start
--dtd-url=<dtd-url>` is run and `dtd-url` points to a DTD instance with
another widget preview service running, the process simply crashes.
This change adds a unique identifier to the widget preview DTD service
and stream names that allows for each `flutter widget-preview start`
instance to register its own unique widget preview DTD services, even if
other widget preview instances are using the same DTD instance.
Fixes https://github.com/flutter/flutter/issues/179883
## What's new?
- Add `PopupWindowController`, `PopupWindowControllerDelegate`, and
`PopupWindow`
- Implement reference logic for popup windows in the test bindings
- Add tests for the popup windows API
## Pre-launch Checklist
- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [x] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [x] All existing and new tests are passing.