Previously, we were comparing the signed int `target_length` (returned by WideCharToMultiByte) to a size_t string length, resulting in a signed/unsigned comparison warning as follows:
```
windows\runner\utils.cpp(54,43): warning C4018: '>': signed/unsigned mismatch
```
WideCharToMultiByte returns:
* 0 on error
* the number of bytes written to the buffer pointed to by its fifth parameter, lpMultiByteStr, on success.
As a result it's safe to store the return value in an unsigned int, which eliminates the warning.
No changes to tests since this is dependent on end-user project settings/modifications and does not trigger a warning with default project settings.
Fixes: https://github.com/flutter/flutter/issues/134227
Reverts flutter/flutter#142709
Initiated by: vashworth
Reason for reverting: `Mac tool_tests_general` started failing on this commit: https://ci.chromium.org/ui/p/flutter/builders/prod/Mac%20tool_tests_general/15552/overview
Original PR Author: dcharkes
Reviewed By: {christopherfujino, chingjun, reidbaker}
This change reverts the following previous change:
Original Description:
Native assets in other build systems are not built with `package:native_assets_builder` invoking `build.dart` scripts. Instead all packages have their own blaze rules. Therefore we'd like to not depend on `package:native_assets_builder` from flutter tools in g3 at all.
This PR aims to move the imports of `native_assets_builder` and `native_assets_cli` into the `isolated/` directory and into the files with a `main` function that are not used in with other build systems.
In order to be able to remove all imports in files used by other build systems, two new interfaces are added `HotRunnerNativeAssetsBuilder` and `TestCompilerNativeAssetsBuilder`. New parameters are then piped all the way through from the entry points:
* bin/fuchsia_tester.dart
* lib/executable.dart
The build_system/targets dir is already excluded in other build systems.
So, after this PR only the two above files and build_system/targets import from `isolated/native_assets/` and only `isolated/native_assets/` import `package:native_assets_cli` and `package:native_assets_builder`.
Context:
* https://github.com/flutter/flutter/issues/142041
`destructiveRed` is an alias for `systemRed`, but, in the definition, the precise type information is lost.
This PR gives `destructiveRed` the type `CupertinoDynamicColor` (and not the superclass `Color`) like all the other colors defined in this file.
Native assets in other build systems are not built with `package:native_assets_builder` invoking `build.dart` scripts. Instead all packages have their own blaze rules. Therefore we'd like to not depend on `package:native_assets_builder` from flutter tools in g3 at all.
This PR aims to move the imports of `native_assets_builder` and `native_assets_cli` into the `isolated/` directory and into the files with a `main` function that are not used in with other build systems.
In order to be able to remove all imports in files used by other build systems, two new interfaces are added `HotRunnerNativeAssetsBuilder` and `TestCompilerNativeAssetsBuilder`. New parameters are then piped all the way through from the entry points:
* bin/fuchsia_tester.dart
* lib/executable.dart
The build_system/targets dir is already excluded in other build systems.
So, after this PR only the two above files and build_system/targets import from `isolated/native_assets/` and only `isolated/native_assets/` import `package:native_assets_cli` and `package:native_assets_builder`.
Context:
* https://github.com/flutter/flutter/issues/142041
Fixes#128696 (Motion checkbox)
This PR updates the Material 3 tab indicator animation, so that it stretches, as it can be seen in the showcase videos in the specification https://m3.material.io/components/tabs/accessibility#13ed756b-fb35-4bb3-ac8c-1157e49031d8
One thing to note is that the Material 3 videos have a tab transition duration of 700 ms, whereas currently in Flutter the duration is 300 ms. I recorded 4 comparison videos to see the difference better (current animation vs stretch animation and 300 ms vs 700 ms)
@Piinks You mentioned the other day that the default tab size could be updated in the future to better reflect the new size in M3. Maybe the `kTabScrollDuration` constant is another one that could end up being updated, as 300 ms for this animation feels too fast.
Here are the comparison videos (Material 3 spec showcase on the left and Flutter on the right)
## Original animation - 300 ms
https://github.com/flutter/flutter/assets/22084723/d5b594fd-52ea-4328-b8e2-ddb597c81f69
## New animation - 300 ms
https://github.com/flutter/flutter/assets/22084723/c822f7ab-3fc4-4403-a53b-872d047f6227
---
## Original animation - 700 ms
https://github.com/flutter/flutter/assets/22084723/fe39a32d-3d10-4c0d-98df-bd5e1c9336d0
## New animation - 700 ms
https://github.com/flutter/flutter/assets/22084723/8d4b0628-6312-40c2-bd99-b4bcb8e23ba9
---
## Code sample
```dart
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: TabExample(),
);
}
}
class TabExample extends StatelessWidget {
const TabExample({super.key});
@override
Widget build(BuildContext context) {
return DefaultTabController(
initialIndex: 1,
length: 3,
child: Scaffold(
appBar: AppBar(
title: const Text('My saved media'),
bottom: const TabBar(
tabs: <Widget>[
Tab(
icon: Icon(Icons.videocam_outlined),
text: "Video",
),
Tab(
icon: Icon(Icons.photo_outlined),
text: "Photos",
),
Tab(
icon: Icon(Icons.audiotrack),
text: "Audio",
),
],
),
),
body: const TabBarView(
children: <Widget>[
Center(
child: Text("Tab 1"),
),
Center(
child: Text("Tab 2"),
),
Center(
child: Text("Tab 3"),
),
],
),
),
);
}
}
```
*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
This change affects Android and iOS devices using the TextField's context menu. After this change the context menu will fade out when scrolling the text and fade in when the scroll ends.
If the scroll ends and the selection is outside of the view, then the toolbar will be scheduled to show in a future scroll end. This toolbar scheduling can be invalidated if the `TextEditingValue` changed anytime between the scheduling and when the toolbar is ready to be shown.
This change also fixes a regression where the TextField context menu would not fade when the selection handles where not visible.
When using the native browser context menu this behavior is not controlled by Flutter.
https://github.com/flutter/flutter/assets/948037/3f46bcbb-ba6f-456c-8473-e42919b9d572Fixes#52425Fixes#105804Fixes#52426
â¦and removed the no-shuffle tag.
This PR fixes#142376 by fixing the flaky test in language_version_test.dart and removes the no-shuffle tag.
Â
## The Problem
The test expected the language version that is set at the top of the test file ('2.13' set in language_version_test.dart â line 14) but defaulted to the language version set in the file it is testing ('2.12' is set in language_version.dart).
This problem was hidden when some other test ran before this test and set up the language version correctly.
Â
## The Fix
Make the test itself load the default language version we are testing against.
This PR updates almost* all Gradle buildscripts in the Flutter repo the `example` and `dev` (in particular, in `dev/integration_tests` and in `dev/benchmarks`) directories to apply Flutter's Gradle plugins using the declarative `plugins {}` block.
*almost, because:
- add-to-app (aka hybrid) apps are not migrated (related https://github.com/flutter/flutter/issues/138756)
- apps that purposefully use build files to ensure backward compatibility (e.g. [`gradle_deprecated_settings`](https://github.com/flutter/flutter/tree/3.16.0/dev/integration_tests/gradle_deprecated_settings))
Add a new `BuildTargets` class that provides commonly used build targets. And avoid importing files from `build_system/targets` except from the top level entrypoints or from top level commands.
Also move `scene_importer.dart` and `shader_compiler.dart` into `build_system/tools` because they are not `Target` classes, but wrapper for certain tools.
With this change, we can ignore all files in `build_system/targets` internally and make PR #142709 easier to land internally. See cl/603434066 for the corresponding internal change.
Related to:
https://github.com/flutter/flutter/pull/142709https://github.com/flutter/flutter/issues/142041
Also note that I have opted to add a new variable in `globals.dart` for `BuildTargets` in this PR, but I know that we are trying to get rid of globals. Several alternatives that I was considering:
1. Add a new field in `BuildSystem` that returns a `BuildTargets` instance. Since `BuildSystem` is already in `globals`, we can access build targets using `globals.buildSystem.buildTargets` without adding a new global variable.
2. Properly inject the `BuildTargetsImpl` instance from the top level `executable.dart` and top level commands.
Let me know if you want me to do one of the above instead. Thanks!
This implements dual compile via the newly available flutter.js bootstrapping APIs for intelligent build fallback.
* Users can now use the `FlutterLoader.load` API from flutter.js
* Flutter tool injects build info into the `index.html` of the user so that the bootstrapper knows which build variants are available to bootstrap
* The semantics of the `--wasm` flag for `flutter build web` have changed:
- Instead of producing a separate `build/web_wasm` directory, the output goes to the `build/web` directory like a normal web build
- Produces a dual build that contains two build variants: dart2wasm+skwasm and dart2js+CanvasKit. The dart2wasm+skwasm will only work on Chrome in a cross-origin isolated context, all other environments will fall back to dart2js+CanvasKit.
- `--wasm` and `--web-renderer` are now mutually exclusive. Since there are multiple build variants with `--wasm`, the web renderer cannot be expressed via a single command-line flag. For now, we are hard coding what build variants are produced with the `--wasm` flag, but I plan on making this more customizable in the future.
* Build targets now can optionally provide a "build key" which can uniquely identify any specific parameterization of that build target. This way, the build target can invalidate itself by changing its build key. This works a bit better than just stuffing everything into the environment defines because (a) it doesn't invalidate the entire build, just the targets which are affected and (b) settings for multiple build variants don't translate well to the flat map of environment defines.
Reland https://github.com/flutter/flutter/pull/141818 with a fix for a special case: If only `background` is specified for `TextButton.styleFrom` or `OutlinedButton.styleFrom` it applies the button's disabled state, i.e. as if the same value had been specified for disabledBackgroundColor.
The change relative to #141818 is the indicated line below:
```dart
final MaterialStateProperty<Color?>? backgroundColorProp = switch ((backgroundColor, disabledBackgroundColor)) {
(null, null) => null,
(_, null) => MaterialStatePropertyAll<Color?>(backgroundColor), // ADDED THIS LINE
(_, _) => _TextButtonDefaultColor(backgroundColor, disabledBackgroundColor),
};
```
This backwards incompatibility cropped up in an internal test, see internal Google issue b/323399158.
This PR is step 5 in the journey to solve issue #136139 and make the entire Flutter repo more readable.
(previous pull requests: #139048, #139882, #141591, #142279)
The current focus is on `packages/flutter/lib/src/material/`.
The previous PR covered files in this directory starting with `a`, `b`, and `c`; this pull request is for `d` through `m`.
When the Dart VM is not found within 10 minutes in CI on CoreDevices (iOS 17+), stop the app and upload the logs from DerivedData. The app has to be stopped first since the logs are not put in DerivedData until it's stopped.
Also, rearranged some logic to have CoreDevice have its own function for Dart VM url discovery.
Debugging for https://github.com/flutter/flutter/issues/142448.
Reverts flutter/flutter#141818
Initiated by: XilaiZhang
This change reverts the following previous change:
Original Description:
Fixes https://github.com/flutter/flutter/issues/139456, https://github.com/flutter/flutter/issues/130335, https://github.com/flutter/flutter/issues/89563.
Two new properties have been added to ButtonStyle to make it possible to insert arbitrary state-dependent widgets in a button's background or foreground. These properties can be specified for an individual button, using the style parameter, or for all buttons using a button theme's style parameter.
The new ButtonStyle properties are `backgroundBuilder` and `foregroundBuilder` and their (function) types are:
```dart
typedef ButtonLayerBuilder = Widget Function(
BuildContext context,
Set<MaterialState> states,
Widget? child
);
```
The new builder functions are called whenever the button is built and the `states` parameter communicates the pressed/hovered/etc state fo the button.
## `backgroundBuilder`
Creates a widget that becomes the child of the button's Material and whose child is the rest of the button, including the button's `child` parameter. By default the returned widget is clipped to the Material's ButtonStyle.shape.
The `backgroundBuilder` can be used to add a gradient to the button's background. Here's an example that creates a yellow/orange gradient background:
![opaque-gradient-bg](https://github.com/flutter/flutter/assets/1377460/80df8368-e7cf-49ef-aee7-2776a573644c)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
return DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(colors: [Colors.orange, Colors.yellow]),
),
child: child,
);
},
),
child: Text('Text Button'),
)
```
Because the background widget becomes the child of the button's Material, if it's opaque (as it is in this case) then it obscures the overlay highlights which are painted on the button's Material. To ensure that the highlights show through one can decorate the background with an `Ink` widget. This version also overrides the overlay color to be (shades of) red, because that makes the highlights look a little nicer with the yellow/orange background.
![ink-gradient-bg](https://github.com/flutter/flutter/assets/1377460/68a49733-f30e-44a1-a948-dc8cc95e1716)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
overlayColor: Colors.red,
backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
return Ink(
decoration: BoxDecoration(
gradient: LinearGradient(colors: [Colors.orange, Colors.yellow]),
),
child: child,
);
},
),
child: Text('Text Button'),
)
```
Now the button's overlay highlights are painted on the Ink widget. An Ink widget isn't needed if the background is sufficiently translucent. This version of the example creates a translucent backround widget.
![translucent-graident-bg](https://github.com/flutter/flutter/assets/1377460/3b016e1f-200a-4d07-8111-e20d29f18014)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
overlayColor: Colors.red,
backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
return DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Colors.orange.withOpacity(0.5),
Colors.yellow.withOpacity(0.5),
]),
),
child: child,
);
},
),
child: Text('Text Button'),
)
```
One can also decorate the background with an image. In this example, the button's background is an burlap texture image. The foreground color has been changed to black to make the button's text a little clearer relative to the mottled brown backround.
![burlap-bg](https://github.com/flutter/flutter/assets/1377460/f2f61ab1-10d9-43a4-bd63-beecdce33b45)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
foregroundColor: Colors.black,
backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
return Ink(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(burlapUrl),
fit: BoxFit.cover,
),
),
child: child,
);
},
),
child: Text('Text Button'),
)
```
The background widget can depend on the `states` parameter. In this example the blue/orange gradient flips horizontally when the button is hovered/pressed.
![gradient-flip](https://github.com/flutter/flutter/assets/1377460/c6c6fe26-ae47-445b-b82d-4605d9583bd8)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
final Color color1 = Colors.blue.withOpacity(0.5);
final Color color2 = Colors.orange.withOpacity(0.5);
return DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: switch (states.contains(MaterialState.hovered)) {
true => <Color>[color1, color2],
false => <Color>[color2, color1],
},
),
),
child: child,
);
},
),
child: Text('Text Button'),
)
```
The preceeding examples have not included a BoxDecoration border because ButtonStyle already supports `ButtonStyle.shape` and `ButtonStyle.side` parameters that can be uesd to define state-dependent borders. Borders defined with the ButtonStyle side parameter match the button's shape. To add a border that changes color when the button is hovered or pressed, one must specify the side property using `copyWith`, since there's no `styleFrom` shorthand for this case.
![border-gradient-bg](https://github.com/flutter/flutter/assets/1377460/63cffcd3-0dcf-4eb1-aed5-d14adf1e57f6)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
foregroundColor: Colors.indigo,
backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
final Color color1 = Colors.blue.withOpacity(0.5);
final Color color2 = Colors.orange.withOpacity(0.5);
return DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: switch (states.contains(MaterialState.hovered)) {
true => <Color>[color1, color2],
false => <Color>[color2, color1],
},
),
),
child: child,
);
},
).copyWith(
side: MaterialStateProperty.resolveWith<BorderSide?>((Set<MaterialState> states) {
if (states.contains(MaterialState.hovered)) {
return BorderSide(width: 3, color: Colors.yellow);
}
return null; // defer to the default
}),
),
child: Text('Text Button'),
)
```
Although all of the examples have created a ButtonStyle locally and only applied it to one button, they could have configured the `ThemeData.textButtonTheme` instead and applied the style to all TextButtons. And, of course, all of this works for all of the ButtonStyleButton classes, not just TextButton.
## `foregroundBuilder`
Creates a Widget that contains the button's child parameter. The returned widget is clipped by the button's [ButtonStyle.shape] inset by the button's [ButtonStyle.padding] and aligned by the button's [ButtonStyle.alignment].
The `foregroundBuilder` can be used to wrap the button's child, e.g. with a border or a `ShaderMask` or as a state-dependent substitute for the child.
This example adds a border that's just applied to the child. The border only appears when the button is hovered/pressed.
![border-fg](https://github.com/flutter/flutter/assets/1377460/687a3245-fe68-4983-a04e-5fcc77f8aa21)
```dart
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
final ColorScheme colorScheme = Theme.of(context).colorScheme;
return DecoratedBox(
decoration: BoxDecoration(
border: states.contains(MaterialState.hovered)
? Border(bottom: BorderSide(color: colorScheme.primary))
: Border(), // essentially "no border"
),
child: child,
);
},
),
child: Text('Text Button'),
)
```
The foregroundBuilder can be used with `ShaderMask` to change the way the button's child is rendered. In this example the ShaderMask's gradient causes the button's child to fade out on top.
![shader_mask_fg](https://github.com/flutter/flutter/assets/1377460/54010f24-e65d-4551-ae58-712135df3d8d)
```dart
ElevatedButton(
onPressed: () { },
style: ElevatedButton.styleFrom(
foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
final ColorScheme colorScheme = Theme.of(context).colorScheme;
return ShaderMask(
shaderCallback: (Rect bounds) {
return LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: <Color>[
colorScheme.primary,
colorScheme.primaryContainer,
],
).createShader(bounds);
},
blendMode: BlendMode.srcATop,
child: child,
);
},
),
child: const Text('Elevated Button'),
)
```
A commonly requested configuration for butttons has the developer provide images, one for pressed/hovered/normal state. You can use the foregroundBuilder to create a button that fades between a normal image and another image when the button is pressed. In this case the foregroundBuilder doesn't use the child it's passed, even though we've provided the required TextButton child parameter.
![image-button](https://github.com/flutter/flutter/assets/1377460/f5b1a22f-43ce-4be3-8e70-06de4c958380)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
final String url = states.contains(MaterialState.pressed) ? smiley2Url : smiley1Url;
return AnimatedContainer(
width: 100,
height: 100,
duration: Duration(milliseconds: 300),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(url),
fit: BoxFit.contain,
),
),
);
},
),
child: Text('No Child'),
)
```
In this example the button's default overlay appears when the button is hovered and pressed. Another image can be used to indicate the hovered state and the default overlay can be defeated by specifying `Colors.transparent` for the `overlayColor`:
![image-per-state](https://github.com/flutter/flutter/assets/1377460/7ab9da2f-f661-4374-b395-c2e0c7c4cf13)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
overlayColor: Colors.transparent,
foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
String url = states.contains(MaterialState.hovered) ? smiley3Url : smiley1Url;
if (states.contains(MaterialState.pressed)) {
url = smiley2Url;
}
return AnimatedContainer(
width: 100,
height: 100,
duration: Duration(milliseconds: 300),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(url),
fit: BoxFit.contain,
),
),
);
},
),
child: Text('No Child'),
)
```
This PR fixes CupertinoTabView's handling of Android back button with PopScope and nested navigators by calling `NavigatorState.maybePop` instead of `NavigatorState.pop`, so that the Navigator pops only when it should.
Fix#139050
This PR is to add 19 new `ColorScheme` roles following the Material Design 3 specs. This PR doesn't apply the new colors to `ThemeData` or any widgets.
This PR is created to split the big change in #138521, once this is merged, another PR that contains the rest of the changes(apply new color roles to widgets and deprecate 3 more colors) will follow.
**Tone-based surface colors** (7 colors):
* surfaceBright
* surfaceDim
* surfaceContainer
* surfaceContainerLowest
* surfaceContainerLow
* surfaceContainerHigh
* surfaceContainerHighest
**Accent color add-ons** (12 colors):
* primary/secondary/tertiary-Fixed
* primary/secondary/tertiary-FixedDim
* onPrimary/onSecondary/onTertiary-Fixed
* onPrimary/onSecondary/onTertiary-FixedVariant
Please checkout this [design doc](https://docs.google.com/document/d/1ODqivpM_6c490T4j5XIiWCDKo5YqHy78YEFqDm4S8h4/edit?usp=sharing) for more information:)
## Description
This changes the factory constructors for `TextButton.icon`, `ElevatedButton.icon`, `FilledButton.icon`, and `FilledButton.tonalIcon` to take nullable icons. If the icon is null, then the "regular" version of the button is created.
## Tests
- Added tests for all four constructors.
The regular chip and the action chip templates were referencing non existent M3 design tokens.
Fixes https://github.com/flutter/flutter/issues/141288
The `ActionChip` doesn't have any visual difference. Even though the template and file changes, the default `labelStyle` color already uses `onSurface`.
For the reviewer, I've changed the `action_chip_test` to expect a color from the colorScheme so that it is more explicit that the color might not be the same as the labelLarge default in the global textTheme, even if for this case the color is the same.
The regular `Chip` does have visual differences, in particular, the label and trailing icon colors, which were not following the specification. In order to fix this, the regular chip now is based from the `filter-chip` spec as described in the linked issue.
## Before
![image](https://github.com/flutter/flutter/assets/22084723/d602ef42-625a-4b5c-b63b-c46cb2070d80)
## After
![image](https://github.com/flutter/flutter/assets/22084723/dddb754f-fd29-4c4c-96cc-e7f508219f12)
Fixes https://github.com/flutter/flutter/issues/139456, https://github.com/flutter/flutter/issues/130335, https://github.com/flutter/flutter/issues/89563.
Two new properties have been added to ButtonStyle to make it possible to insert arbitrary state-dependent widgets in a button's background or foreground. These properties can be specified for an individual button, using the style parameter, or for all buttons using a button theme's style parameter.
The new ButtonStyle properties are `backgroundBuilder` and `foregroundBuilder` and their (function) types are:
```dart
typedef ButtonLayerBuilder = Widget Function(
BuildContext context,
Set<MaterialState> states,
Widget? child
);
```
The new builder functions are called whenever the button is built and the `states` parameter communicates the pressed/hovered/etc state fo the button.
## `backgroundBuilder`
Creates a widget that becomes the child of the button's Material and whose child is the rest of the button, including the button's `child` parameter. By default the returned widget is clipped to the Material's ButtonStyle.shape.
The `backgroundBuilder` can be used to add a gradient to the button's background. Here's an example that creates a yellow/orange gradient background:
![opaque-gradient-bg](https://github.com/flutter/flutter/assets/1377460/80df8368-e7cf-49ef-aee7-2776a573644c)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
return DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(colors: [Colors.orange, Colors.yellow]),
),
child: child,
);
},
),
child: Text('Text Button'),
)
```
Because the background widget becomes the child of the button's Material, if it's opaque (as it is in this case) then it obscures the overlay highlights which are painted on the button's Material. To ensure that the highlights show through one can decorate the background with an `Ink` widget. This version also overrides the overlay color to be (shades of) red, because that makes the highlights look a little nicer with the yellow/orange background.
![ink-gradient-bg](https://github.com/flutter/flutter/assets/1377460/68a49733-f30e-44a1-a948-dc8cc95e1716)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
overlayColor: Colors.red,
backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
return Ink(
decoration: BoxDecoration(
gradient: LinearGradient(colors: [Colors.orange, Colors.yellow]),
),
child: child,
);
},
),
child: Text('Text Button'),
)
```
Now the button's overlay highlights are painted on the Ink widget. An Ink widget isn't needed if the background is sufficiently translucent. This version of the example creates a translucent backround widget.
![translucent-graident-bg](https://github.com/flutter/flutter/assets/1377460/3b016e1f-200a-4d07-8111-e20d29f18014)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
overlayColor: Colors.red,
backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
return DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(colors: [
Colors.orange.withOpacity(0.5),
Colors.yellow.withOpacity(0.5),
]),
),
child: child,
);
},
),
child: Text('Text Button'),
)
```
One can also decorate the background with an image. In this example, the button's background is an burlap texture image. The foreground color has been changed to black to make the button's text a little clearer relative to the mottled brown backround.
![burlap-bg](https://github.com/flutter/flutter/assets/1377460/f2f61ab1-10d9-43a4-bd63-beecdce33b45)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
foregroundColor: Colors.black,
backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
return Ink(
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(burlapUrl),
fit: BoxFit.cover,
),
),
child: child,
);
},
),
child: Text('Text Button'),
)
```
The background widget can depend on the `states` parameter. In this example the blue/orange gradient flips horizontally when the button is hovered/pressed.
![gradient-flip](https://github.com/flutter/flutter/assets/1377460/c6c6fe26-ae47-445b-b82d-4605d9583bd8)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
final Color color1 = Colors.blue.withOpacity(0.5);
final Color color2 = Colors.orange.withOpacity(0.5);
return DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: switch (states.contains(MaterialState.hovered)) {
true => <Color>[color1, color2],
false => <Color>[color2, color1],
},
),
),
child: child,
);
},
),
child: Text('Text Button'),
)
```
The preceeding examples have not included a BoxDecoration border because ButtonStyle already supports `ButtonStyle.shape` and `ButtonStyle.side` parameters that can be uesd to define state-dependent borders. Borders defined with the ButtonStyle side parameter match the button's shape. To add a border that changes color when the button is hovered or pressed, one must specify the side property using `copyWith`, since there's no `styleFrom` shorthand for this case.
![border-gradient-bg](https://github.com/flutter/flutter/assets/1377460/63cffcd3-0dcf-4eb1-aed5-d14adf1e57f6)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
foregroundColor: Colors.indigo,
backgroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
final Color color1 = Colors.blue.withOpacity(0.5);
final Color color2 = Colors.orange.withOpacity(0.5);
return DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: switch (states.contains(MaterialState.hovered)) {
true => <Color>[color1, color2],
false => <Color>[color2, color1],
},
),
),
child: child,
);
},
).copyWith(
side: MaterialStateProperty.resolveWith<BorderSide?>((Set<MaterialState> states) {
if (states.contains(MaterialState.hovered)) {
return BorderSide(width: 3, color: Colors.yellow);
}
return null; // defer to the default
}),
),
child: Text('Text Button'),
)
```
Although all of the examples have created a ButtonStyle locally and only applied it to one button, they could have configured the `ThemeData.textButtonTheme` instead and applied the style to all TextButtons. And, of course, all of this works for all of the ButtonStyleButton classes, not just TextButton.
## `foregroundBuilder`
Creates a Widget that contains the button's child parameter. The returned widget is clipped by the button's [ButtonStyle.shape] inset by the button's [ButtonStyle.padding] and aligned by the button's [ButtonStyle.alignment].
The `foregroundBuilder` can be used to wrap the button's child, e.g. with a border or a `ShaderMask` or as a state-dependent substitute for the child.
This example adds a border that's just applied to the child. The border only appears when the button is hovered/pressed.
![border-fg](https://github.com/flutter/flutter/assets/1377460/687a3245-fe68-4983-a04e-5fcc77f8aa21)
```dart
ElevatedButton(
onPressed: () {},
style: ElevatedButton.styleFrom(
foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
final ColorScheme colorScheme = Theme.of(context).colorScheme;
return DecoratedBox(
decoration: BoxDecoration(
border: states.contains(MaterialState.hovered)
? Border(bottom: BorderSide(color: colorScheme.primary))
: Border(), // essentially "no border"
),
child: child,
);
},
),
child: Text('Text Button'),
)
```
The foregroundBuilder can be used with `ShaderMask` to change the way the button's child is rendered. In this example the ShaderMask's gradient causes the button's child to fade out on top.
![shader_mask_fg](https://github.com/flutter/flutter/assets/1377460/54010f24-e65d-4551-ae58-712135df3d8d)
```dart
ElevatedButton(
onPressed: () { },
style: ElevatedButton.styleFrom(
foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
final ColorScheme colorScheme = Theme.of(context).colorScheme;
return ShaderMask(
shaderCallback: (Rect bounds) {
return LinearGradient(
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
colors: <Color>[
colorScheme.primary,
colorScheme.primaryContainer,
],
).createShader(bounds);
},
blendMode: BlendMode.srcATop,
child: child,
);
},
),
child: const Text('Elevated Button'),
)
```
A commonly requested configuration for butttons has the developer provide images, one for pressed/hovered/normal state. You can use the foregroundBuilder to create a button that fades between a normal image and another image when the button is pressed. In this case the foregroundBuilder doesn't use the child it's passed, even though we've provided the required TextButton child parameter.
![image-button](https://github.com/flutter/flutter/assets/1377460/f5b1a22f-43ce-4be3-8e70-06de4c958380)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
final String url = states.contains(MaterialState.pressed) ? smiley2Url : smiley1Url;
return AnimatedContainer(
width: 100,
height: 100,
duration: Duration(milliseconds: 300),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(url),
fit: BoxFit.contain,
),
),
);
},
),
child: Text('No Child'),
)
```
In this example the button's default overlay appears when the button is hovered and pressed. Another image can be used to indicate the hovered state and the default overlay can be defeated by specifying `Colors.transparent` for the `overlayColor`:
![image-per-state](https://github.com/flutter/flutter/assets/1377460/7ab9da2f-f661-4374-b395-c2e0c7c4cf13)
```dart
TextButton(
onPressed: () {},
style: TextButton.styleFrom(
overlayColor: Colors.transparent,
foregroundBuilder: (BuildContext context, Set<MaterialState> states, Widget? child) {
String url = states.contains(MaterialState.hovered) ? smiley3Url : smiley1Url;
if (states.contains(MaterialState.pressed)) {
url = smiley2Url;
}
return AnimatedContainer(
width: 100,
height: 100,
duration: Duration(milliseconds: 300),
decoration: BoxDecoration(
image: DecorationImage(
image: NetworkImage(url),
fit: BoxFit.contain,
),
),
);
},
),
child: Text('No Child'),
)
```
## Description
Fixes a paragraph in the `showDialog` docs that had strange placement due to evolution of the docs. Fixed some missing words too.
## Related Issues
- Fixes https://github.com/flutter/flutter/issues/142097
Refactors `ShaderTarget` to make it opaque as to whether it's using Impeller or SkSL and instead has it focus on the target platform it's generating for.
ImpellerC includes SkSL right now whether you ask for it or not.
The tester target also might need SkSL or Vulkan depending on whether `--enable-impeller` is passed.
Fixes https://github.com/flutter/flutter/issues/142480.
This fixes a crash occurring during hot reload when a `ViewAnchor` is used between a `ParentDataWidget` (like `Positioned`) and its closest `RenderObject` descendant. Prior to the fix, the `ParentDataWidget` was accidentally applying its parent data to the render object in the `ViewAnchor.view` slot, which crashed because that render object wasn't (and shouldn't be) setup to accept parent data (after all, it is in a different render tree). Instead, the parent data should only be applied to the render object in the `ViewAnchor.child` slot. Luckily, with `Element.renderObjectAttachingChild` we already have API in place to walk the widget tree such as that only `RenderObjectWidgets` from the same render tree are considered.
Fixes https://github.com/flutter/flutter/issues/142045
The intent of using `??=` was that if the tooltip is already scheduled for showing, rescheduling another show does nothing. But if the tooltip is already scheduled for dismissing, the `??=` won't cancel the dismiss timer and as a result the tooltip won't show. So the `??=` is now replaced by `=` to keep it consistent with the `_scheduleDismissTooltip` implementation.
While looking into resolving https://github.com/flutter/flutter/issues/117903, I found the massive test file `app_bar_test.dart` and found it unwieldy to work with. So before proposing a solution to #117903, which would touch many of these tests, I figured a clean up would be best first.
This splits up `app_bar_test.dart` with a new file `app_bar_sliver_test.dart`, and adds `app_bar_utils.dart` for shared test methods.
It basically moves all SliverAppBar tests into their own file, leaving just AppBar tests in the original file.
Children should be omitted from debugFillProperties (if they really need to be included they should be in debugDescribeChildren, but in general for widgets we don't bother including them since they are eventually included anyway).
toStrings should not contain newlines (or, ideally, should use Diagnosticable).
Also some minor tweaks to match grammar and style guide conventions.
This change uses `CapturedTheme`s to capture the themes from the context the selection handles were built in and wraps the handles with them so they can correctly inherit `Theme`s from local `Theme` widgets.
`CapturedTheme`s only captures `InheritedTheme`s, so this change also makes `_InheritedCupertinoTheme` an `InheritedTheme`. This is so we can capture themes declared under a `CupertinoTheme`, for example `primaryColor` is used as the selection handle color.
Fixes#74890
Fixes https://github.com/flutter/flutter/issues/142183
This fixes a bug in the SliverGeometry of SliverMainAxisGroup. The cacheExtent represents how many pixels the sliver has consumed in the SliverConstraints.remainingCacheExtent. Since it was not set, slivers that came after a SliverMainAxisGroup that filled the whole screen did not properly lay out their own children, in some cases making lazy sliver more eager than they should be.
This PR is adding a flag parameter to the `TextField` widget. This flag controls whether the TextField ignores pointers. The flag takes priority over other TextField behaviors such as enabled, so it can be useful when trying to have a disabled TextField that can be scrolled (behavior observed using TextArea on the web).
Adding a flag parameter to `TextField` helps with more customization and flexibility to the widget which can improve user experience. I am open to other ideas.
Fixes issue #140147
Before:
https://github.com/flutter/flutter/assets/66151079/293e5b4e-3126-4a00-824d-1530aeaa494b
After:
https://github.com/flutter/flutter/assets/66151079/08c1af09-3bf9-4b49-b684-dda4dd920503
Usage:
```dart
child: TextField(
ignorePointer: false,
enabled: false,
),
```
This PR is the fourth step in the journey to solve issue #136139 and make the entire Flutter repo more readable.
(previous pull requests: #139048, #139882, #141591)
This one is covering files in `packages/flutter/lib/src/foundation/` and `packages/flutter/lib/src/material/`.
The `material/` directory is pretty big though, so for now I just did the files that start with `a`, `b`, and `c`.
This PR increases Android's `minSdkVersion` to 21.
There are two changes in this PR aside from simply increasing the number
from 19 to 21 everywhere.
First, tests using `flutter_gallery` fail without updating the
lockfiles. The changes in the PR are the results of running
`dev/tools/bin/generate_gradle_lockfiles.dart` on that app.
Second, from
[here](https://developer.android.com/build/multidex#mdex-pre-l):
> if your minSdkVersion is 21 or higher, multidex is enabled by default
and you don't need the multidex library.
As a result, the `multidex` option everywhere is obsolete. This PR
removes all logic and tests related to that option that I could find.
`Google testing` and `customer_tests` pass on this PR, so it seems like
this won't be too breaking if it is at all. If needed I'll give this
some time to bake in the framework before landing the flutter/engine
PRs.
Context: https://github.com/flutter/flutter/issues/138117,
https://github.com/flutter/flutter/issues/141277, b/319373605
Reverts flutter/flutter#142339
In the original change one of the tests included the same view twice which resulted in a different failure than the expected one. The second commit contains the fix for this. I don't understand how this wasn't caught presubmit on CI.
It fixes assertion failure due to unstable state of children list during reordering in `RenderTwoDimensionalViewport.parentDataOf`. This changes the assertion to check debug orphan list and `keepAlive` bucket in addition to children list to determine whether child belongs to this render object or not.
- Fixes#141101
Reverts flutter/flutter#141484
Initiated by: eliasyishak
This change reverts the following previous change:
Original Description:
The existing `runApp` bootstraps the widget tree and renders the provided widget into the default view (which is currently the implicit View from `PlatformDispatcher.implicitView` and - in the future - may be a default-created window). Apps, that want more control over the View they are rendered in, need a new way to bootstrap the widget tree: `runWidget`. It does not make any assumptions about the View the provided widget is rendered into. Instead, it is up to the caller to include a View widget in the provided widget tree that specifies where content should be rendered. In the future, this may enable developers to create a custom window for their app instead of relying on the default-created one.
The existing `runApp` bootstraps the widget tree and renders the provided widget into the default view (which is currently the implicit View from `PlatformDispatcher.implicitView` and - in the future - may be a default-created window). Apps, that want more control over the View they are rendered in, need a new way to bootstrap the widget tree: `runWidget`. It does not make any assumptions about the View the provided widget is rendered into. Instead, it is up to the caller to include a View widget in the provided widget tree that specifies where content should be rendered. In the future, this may enable developers to create a custom window for their app instead of relying on the default-created one.
This PR fixes 2 small mistakes in `FlutterExtension`:
- all fields must be `public` in order to be used in Gradle Kotlin DSL the same as in Gradle Groovy DSL
- using `logger` instead of `project.logger` throws an error when executed
This PR re-adds a subset of changes from #141541 which broke the tree and has been reverted.
fix https://github.com/flutter/flutter/issues/121493
`SegmentedButton` uses `TextButton` for each segments. When we have `MaterialTapTargetSize.padded` for `TextButton`, we make sure the minimum tap target size is 48.0( this value can be adjusted by visual density), even tough the actual button size is smaller. When `SegmentedButton` paints segments by using `MultiChildRenderObjectWidget`, it also includes the tap target size so the button that it actually draws always has the same height as the height of the tap target size.
To fix it, this PR firstly calculate the actual height of a text button in `SegmentedButton` class, then we can get the height delta if there is. Then the the value of (Segmented button render box height - the delta) would be the actual button size that we should see.
For now, we are not able to customize the min, max, fixed size in [`SegmentedButton` style](https://api.flutter.dev/flutter/material/SegmentedButton/style.html). So the standard button height is always 40 and can only be customized by `style.visualDensity` and `style.tapTargetSize`; `SegmentedButton` only simulates the `TextButton` behavior when `TextButton`'s height is its default value.
![Screenshot 2024-01-25 at 11 45 42â¯AM](https://github.com/flutter/flutter/assets/36861262/7451fa96-6d45-4cd3-a894-ca71e776c8ef)
https://github.com/flutter/flutter/assets/36861262/15ca6034-e6e0-4cc6-8fe3-808b4bd6a920
It's now possible to natively compile a flutter app for windows-arm64. Cross-compilation is not yet implemented.
Uses arm64 artifacts now available for Dart/Flutter. Platform detection is based on Abi class, provided by Dart. Depending if Dart is an arm64 or x64 binary, the Abi is set accordingly. Initial bootstrap of dart artifacts (update_dart_sdk.ps1) is checking PROCESSOR_ARCHITECTURE environment variable, which is the way to detect host architecture on Windows.
This is available only for master channel (on other channels, it fallbacks to windows-x64).
On windows-x64, it produces an x64 app. On windows-arm64, it produces an arm64 app.
Fixes https://github.com/flutter/flutter/issues/141764
Translation suggestion here:
https://tc.corp.google.com/btviewer/edittranslation?project=Flutter&msgId=8222331119728136330&language=zh-CN
## 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] All existing and new tests are passing.
The legacy welcome message would be printed even if `CI=true` confusing
parsers of the output.
This fixes: https://github.com/flutter/flutter/issues/139737
---------
Co-authored-by: eliasyishak <42216813+eliasyishak@users.noreply.github.com>
Part of work on [#101077](https://github.com/flutter/flutter/pull/141194). This is done as a separate PR to avoid a massive diff.
## Context
1. The `FakeCommand` class accepts a list of patterns that's used to match a command given to its `FakeProcessManager`. Since `FakeCommand` can match a list of patterns, not just specifically strings, it can be used to match commands where the exact value of some arguments can't (easily) known ahead of time. For example, a part of the tool may invoke a command with an argument that is the path of a temporarily file that has a randomly-generated basename.
2. The `FakeCommand` class provides on `onRun` parameter, which is a callback that is run when the `FakeProcessManager` runs a command that matches the `FakeCommand` in question.
## Issue
In the event that a `FakeCommand` is constructed using patterns, the test code can't know the exact values used for arguments in the command. This PR proposes changing the type of `onRun` from `VoidCallback?` to `void Function(List<String>)?`. When run, the value `List<String>` parameter will be the full command that the `FakeCommand` matched.
Example:
```dart
FakeCommand(
command: <Pattern>[
artifacts.getArtifactPath(Artifact.engineDartBinary),
'run',
'vector_graphics_compiler',
RegExp(r'--input=/.*\.temp'),
RegExp(r'--output=/.*\.temp'),
],
onRun: (List<String> command) {
final outputPath = (() {
// code to parse `--output` from `command`
})();
testFileSystem.file(outputPath).createSync(recursive: true);
},
)
```
This PR adds a test that reproduces the problem described in the linked issue: hot restart on the web seems to not update if the app being run is `const`.
The new test is expected to fail, until the `const` issue with hot restart in the web is resolved.
Expected failure mode is a 15s timeout in the following test:
```
02:31 +3 ~1 -1: Hot reload (index.html: Default) (with `const MyApp()`)): newly added code executes during hot restart [E]
TimeoutException after 0:00:15.000000: Future not completed
dart:async _startMicrotaskLoop
...
```
(And then a bunch of output that I'm not 100% sure is intended :))
## Issues
* #141588
Fixes#129590
* Consider `AxisDirection` when calculating scroll offset used in determining TextSelection during a drag/long press drag. Previously it seems that we were assuming the direction was always vertical 30cc831985/packages/flutter/lib/src/widgets/text_selection.dart (L2842-L2844) .
* SelectableText now considers RenderEditable offset changes and Scrollable offset changes when calculating the TextSelection during a long press drag.
Much of the new wording here is borrowed from [ChipTheme], [SliderTheme], or [RadioThemeData], which I think are pretty good. I believe a lot of other theme classes have similar wording too. I've also made some tweaks of my own, notably the references to [MaterialApp.theme].
This started from a desire to have clearer cross-references pointing at what to do with a FooThemeData to make it take effect:
https://github.com/flutter/flutter/pull/135879#discussion_r1355851481
but then as I started writing I kept finding more and more small things I wanted to adjust, including a couple of bits that were extraneous or obsolete.
Part of work on https://github.com/flutter/flutter/pull/141194
The [`AssetBundle`](0833929c99/packages/flutter_tools/lib/src/asset.dart (L80)) class contains two members, `entries` and `entryKinds`. `entries` contains asset data indexed by asset key. `entryKinds` contains the "kinds" of these assets, again indexed by asset key.
**Change.** Rather than have two separate maps, this PR proposes combining these maps into one by wrapping the asset data and kind into a single data type `AssetBundleEntry`.
**Purpose.** In https://github.com/flutter/flutter/pull/141194, I am considering associating more information with an asset. In particular, what transformers are meant to be applied to it when copying it to the build output. Rather than adding another map member onto `AssetBundle` (e.g. `entryTransformers`), I decided to make things neater by introducing the `AssetBundleEntry` type.
Fixes#141347
This PR is to add a "clear text" tooltip for the clear button on `SearchAnchor`'s search view and also add a `clearButtonTooltip` entry for `material_localizations`.
This is part 2 of a broken down version of the #140101 refactor.
This particular change wasn't in that original refactor but is a note to myself so that I remember how to test each of these changes in the future.
Reverts flutter/flutter#141541
Initiated by: yusuf-goog
This change reverts the following previous change:
Original Description:
This PR introduces the first app in this repo that fully uses Gradle Kotlin DSL.
It also fixes a bug I found in the process – fields of `FlutterExtensions` must be `public`.
Part of #137040 and #80374
- Rename _filterPluginsByPlatform to _createPluginMapOfPlatform
- Move method in chronological order
- Cleanup platform strings
This PR introduces the first app in this repo that fully uses Gradle Kotlin DSL.
It also fixes a bug I found in the process â fields of `FlutterExtensions` must be `public`.
## Description
This removes an unneeded expectation in the test for the AppLifecycleListener. It's unneeded because the test immediately resets the state anyhow. I'm removing it because the web implementation sets the value when initializing, so it's never initially null there.
## Related PR
- https://github.com/flutter/engine/pull/44720#issuecomment-1898482363
It's confusing that `debugPrint` also prints in release mode, given that a lot (most?) other things prefixed with `debug` don't do anything in release mode. Therefore, this adds some documentation that this is indeed logging in release mode and adds an example how to disable this.
*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
When a `TextField` is rendered before a `Navigator`, it breaks in semantics mode. This is because the framework generates the incorrect semantics tree (excludes the TextField) and when that tree gets sent to the engine, we don't get the signal to create the corresponding `<input>` element.
This happens for a few reasons:
* `ModalBarrier` uses `BlockSemantics` to drop the semantics of routes beneath the current route in `Navigator`
* `ModalBarrier` mistakenly recognizes the widget outside of the `Navigator` to be its sibling
* So we end up dropping the semantics node of the `TextField` rendered before it.
The fix is to let `Navigator` generate a semantics node so that `ModalBarrier` doesn't mistakenly think widgets outside of `Navigator` are its siblings.
`Navigator` doesn't currently do this, which causes all the nodes generated from its widget subtree to be directly attached to the parent semantics node above `Navigator` - since this is also the parent of `TextField`, it considers them siblings.
Fixes https://github.com/flutter/flutter/issues/129324
This PR adds the Dart VM `vm:platform-const-if` pragma introduced in
https://github.com/dart-lang/sdk/commit/57a1168875 to the
`defaultTargetPlatform` property, allowing it to be computed as if it
was a constant field in non-debug AOT builds. In particular, this means
that platform-specific code executed conditionally based on this
property can be tree-shaken in release builds. Note that this PR changes
`defaultTargetPlatform` to only allow overriding via
`debugDefaultTargetPlatformOverride` in debug builds, and makes it so
that compilation throws an error if code assigns
to`debugDefaultTargetPlatformOverride` in other build modes.
Related issue: #14233
## 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] All existing and new tests are passing.
Fixes https://github.com/flutter/flutter/issues/141827
Reland: https://dart-review.googlesource.com/c/sdk/+/346960 has rolled into g3, so the imports should now resolve in g3 as well.
> [!CAUTION]
> _Do NOT merge if "Google Testing" bot didn't run!_
Rolls the packages from https://github.com/dart-lang/native in the native assets implementation.
Most notable we're refactoring `package:native_assets_cli` for `build.dart` use.
Therefore, all imports to that package for Flutter/Dart should be to the implementation internals that are no longer visible for `build.dart` writers. Hence all the import updates.
No behavior in Flutter apps should change.
This PR also updates the template to use the latests version of `package:native_assets_cli` which no longer exposes all the implementation details.
On `Podfile`:
```ruby
flutter_application_path = '../flutter_module'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')
target 'OCProject' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
# Pods for OCProject
# install_all_flutter_pods(flutter_application_path)
# install_flutter_engine_pod(flutter_application_path)
# install_flutter_application_pod(flutter_application_path)
install_flutter_plugin_pods(flutter_application_path)
end
post_install do |installer|
flutter_post_install(installer)
end
```
Encountering the following error after executing `pod install`:
```shell
pod install
[!] Invalid `Podfile` file: undefined method `flutter_relative_path_from_podfile' for #<Pod::Podfile:0x000000010e74c520 @defined_in_file=#<Pathname:/Users/lxf/gitHub/flutter_hybrid_bug/OCProject/Podfile>, @internal_hash={}, @root_target_definitions=[#<Pod::Podfile::TargetDefinition label=Pods>], @current_target_definition=#<Pod::Podfile::TargetDefinition label=Pods>>
relative = flutter_relative_path_from_podfile(export_script_directory)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^.
# from /Users/lxf/gitHub/flutter_hybrid_bug/OCProject/Podfile:17
# -------------------------------------------
# # install_flutter_plugin_pods(flutter_application_path)
> install_flutter_application_pod(flutter_application_path)
#
# -------------------------------------------
```
The `flutter_relative_path_from_podfile` method is in `flutter_tools/bin/podhelper.rb`, but now `flutter_tools/bin/podhelper.rb` is only required in `install_all_flutter_pods` in `podhelper.rb.tmpl`.
Sometimes we only need to use the `install_flutter_plugin_pods` method in podhelper.rb. For example, using `Shorebird` in an iOS hybird app scenario, we need to build `Flutter.xcframework` and `App.xcframework` and embed them into the iOS native project. In order to avoid unnecessary conflicts, use `install_flutter_plugin_pods` method to install Flutter plugin pods.
[Shorebird - Code Push In Hybrid Apps](https://docs.shorebird.dev/guides/hybrid-app/ios)
So I adjust the position of `require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)`.
Remove more `textScaleFactor` references from flutter/flutter.
- Some changes are related to label scaling: the padding EdgeInsets values of some chip subclasses scale linearly between predetermined "max" padding values and "min" padding values. Before they scale with the `textScaleFactor` scalar, now they scale with the font size and are still capped at the original "max" and "min" values.
- The rest of them are tests or size heuristics that depend on `textScaleFactor`, these are replaced by an effective text scale factor computed using a default font size (which is determined in a pretty random fashion, but it will only make a difference on Android 14+).
No API changes in this batch. There are still some references left that I intend to remove in a different batch that would introduce API changes.
packages Roller breakage
https://ci.chromium.org/ui/p/flutter/builders/try/Linux_android%20android_build_all_packages%20master/5504/overview
Fixes flutter/flutter/issues/141897
```
FAILURE: Build failed with an exception.
* Where:
Script '/b/s/w/ir/x/w/flutter/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy' line: 168
* What went wrong:
Could not compile script '/b/s/w/ir/x/w/flutter/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy'.
> startup failed:
script '/b/s/w/ir/x/w/flutter/packages/flutter_tools/gradle/src/main/groovy/flutter.groovy': 168: primitive type parameters not allowed here;
solution: use the corresponding wrapper type, such as Integer for int @ line 168, column 41.
e static final Map<String, int> ABI_VERS
```
Covered by tests in packages.
Packages the native assets for iOS and MacOS in frameworks.
Issue:
* https://github.com/flutter/flutter/issues/140544
* https://github.com/flutter/flutter/issues/129757
## Details
* [x] This packages dylibs from the native assets feature in frameworks. It packages every dylib in a separate framework.
* [x] The dylib name is updated to use `@rpath` instead of `@executable_path`.
* [x] The dylibs for flutter-tester are no longer modified to change the install name. (Previously it was wrongly updating the install name to the location the dylib would have once deployed in an app.)
* [x] Use symlinking on MacOS.
Much nicer calling API and simplifies evolving this API in the future.
I wish we could write a dart fix for this, but that's blocked on https://github.com/dart-lang/sdk/issues/54668.
The old doc says that, AutomatedTestWidgetsFlutterBinding for `flutter test` and LiveTestWidgetsFlutterBinding for `flutter run`. However, suppose we `flutter test integration_test/simple_test.dart` with the following code:
```
void main() {
testWidgets('hi', (WidgetTester tester) async {
print('hi ${TestWidgetsFlutterBinding.instance} ${Platform.operatingSystem}');
});
}
```
We will see: `hi <IntegrationTestWidgetsFlutterBinding> ios`. Therefore, we see `IntegrationTestWidgetsFlutterBinding` is used in a `flutter test` command, which is contrary to the documentation.
Includes the Engine roll from
https://github.com/flutter/flutter/pull/141841
A new version of Dart is having trouble with the tool integration test
test `passing one file with errors are detected`:
https://ci.chromium.org/ui/p/flutter/builders/try/Mac%20tool_integration_tests_2_4/31851/overview.
However the analysis server emits the expected errors when we give it
both the file without issues and the file with issues.
My guess is that the analysis server has changed it's behavior slightly
when supplied with a single malformed file.
Since the Dart roll is >20 dev versions behind, and this is the only
failing presubmit test, and it's testing something a bit weird, I
suggest we investigate the right way to test the thing that test was
attempting to cover as a follow-up.
- Unskip `text_style_test` for CanvasKit.
- Remove no longer necessary `kIsWeb` checks in a few tests.
This PR depends on https://github.com/flutter/engine/pull/49786, which rolled into the framework. If the engine PR needs to be reverted, this PR will need to be reverted too.
This PR improves the distance between the label and the icon in the Tab widget.
I updated the margin to 2 pixels, taken from the Figma design page for Material 3. On Material 2 I left the default value of 10 pixels.
Related to #128696 (In particular, the distance between label and icon)
Here are some screenshots for comparison. I looked a bit into the other mentioned issue of the tab height not following the M3 spec. Flutter uses 72 and the spec uses 64. But because Tab is a PreferredSizeWidget, I don't think there is an easy way to provide a different size depending on `ThemeData.useMaterial3`, because there is no `BuildContext` available.
I provide a sample image for the 64 height as well for context on the linked issue, even though it's not part of the PR changes.
The screenshots are taken side by side with the image at: https://m3.material.io/components/tabs/guidelines
## Original
![original](https://github.com/flutter/flutter/assets/22084723/f52d46bb-eaf9-4519-976e-9ea07c021e14)
## New (tab height = 72, Flutter default for 8 years)
![new_72](https://github.com/flutter/flutter/assets/22084723/8c9d3510-eaca-4b7d-92d8-0d06a7e75136)
## New (tab height = 64, M3 spec)
![new_64](https://github.com/flutter/flutter/assets/22084723/f8811b70-766f-4a4f-b069-33673b1e3744)
Reverts flutter/flutter#137618
Initiated by: Jasguerrero
This change reverts the following previous change:
Original Description:
It's now possible to natively compile a flutter app for
windows-arm64. Cross-compilation is not yet implemented.
Uses arm64 artifacts now available for Dart/Flutter.
Platform detection is based on Abi class, provided by Dart. Depending if
Dart is an arm64 or x64 binary, the Abi is set accordingly.
Initial bootstrap of dart artifacts (update_dart_sdk.ps1) is checking
PROCESSOR_ARCHITECTURE environment variable, which is the way to detect
host architecture on Windows.
This is available only for master channel (on other channels, it
fallbacks to windows-x64).
On windows-x64, it produces an x64 app. On windows-arm64, it produces an
arm64 app.
It's now possible to natively compile a flutter app for
windows-arm64. Cross-compilation is not yet implemented.
Uses arm64 artifacts now available for Dart/Flutter.
Platform detection is based on Abi class, provided by Dart. Depending if
Dart is an arm64 or x64 binary, the Abi is set accordingly.
Initial bootstrap of dart artifacts (update_dart_sdk.ps1) is checking
PROCESSOR_ARCHITECTURE environment variable, which is the way to detect
host architecture on Windows.
This is available only for master channel (on other channels, it
fallbacks to windows-x64).
On windows-x64, it produces an x64 app. On windows-arm64, it produces an
arm64 app.
Previously `TextField`s error `cursorColor` was being derived without taking into account any `InputDecorationTheme` defaults. This change respects `InputDecorationTheme` defaults when deriving the error `cursorColor`.
Fixes#140607
Move static methods together.
Fix property uses of duplicate strings.
Add types wherever obvious
Fix format depth
Add whitespace to top and bottom of classes
Ignore line length for file
Ignore prefer single quote for file
Ignore correction for getFoo used instead of foo
Loosely related to flutter/flutter/issues/123934
This disables the expectation for `TileMode` stringification because
https://github.com/flutter/engine/pull/49786 is about to fix it (as in,
the test would fail when the engine fix lands).
Fixes#140046
This PR is to add a `headerHeight` property to `SearchAnchor` and `SearchViewThemeData` so the header height on the search view can be customized.
Rolls the packages from https://github.com/dart-lang/native in the native assets implementation.
Most notable we're refactoring `package:native_assets_cli` for `build.dart` use.
Therefore, all imports to that package for Flutter/Dart should be to the implementation internals that are no longer visible for `build.dart` writers. Hence all the import updates.
No behavior in Flutter apps should change.
This PR also updates the template to use the latests version of `package:native_assets_cli` which no longer exposes all the implementation details.
## Description
This adds a check to make sure that the `--empty` flag isn't applied to non-app templates.
## Related Issues
- Fixes https://github.com/flutter/flutter/issues/141592
## Tests
- Added a test.
I continued [my mission](https://github.com/flutter/flutter/pull/141431) to find as many typos as I could. This time it's a smaller set than before.
There is no need for issues since it's a typo fix.
`swift-format` alphabetizes imports. Alphabetize them in swift template files and integration tests.
I found this as part of https://github.com/flutter/flutter/issues/41129 running `swift-import` on packages.
## Description
This PR addresses issue #141061, which requested the addition of a 'color' property to buttons extending _ActionButton. The 'color' property has been introduced to enhance customization options for these buttons.
## Issues Fixed
- Fixes#141061
Reverts flutter/flutter#141526
Initiated by: CaseyHillers
This change reverts the following previous change:
Original Description:
### Description
- Adds `BoxPainter` creation and disposal events dispatching for memory leak tracking as part of https://github.com/flutter/flutter/issues/141198
### Tests
- Updates `decoration_test.dart` to test `BoxPainter` object creation and disposal events dispatching.
Added missing required newline at end of some `.gitignore` files. All other `.gitignore` files ends with a newline except the changed ones, hence the PR.
> *List which issues are fixed by this PR. You must list at least one issue. An issue is not required if the PR fixes something trivial like a typo.*
**Not listing any issues because of trivial fixes as mentioned above.**
There's no issue for this PR. I can create one if requested.
## Summary
This PR makes public fields of `FlutterExtension` non-static. The aim is to make migrating from Gradle Groovy DSL to Gradle Kotlin DSL easier for Flutter developers, because...
### Without this PR
**android/app/build.gradle.kts**
```kotlin
plugins {
id "com.android.application"
id "dev.flutter.flutter-gradle-plugin"
}
android {
namespace = "io.flutter.examples.hello_world"
compileSdk = FlutterExtension.compileSdkVersion
defaultConfig {
applicationId = "io.flutter.examples.hello_world"
minSdk = FlutterExtension.minSdkVersion
targetSdk = FlutterExtension.targetSdkVersion
// ...
}
}
// ...
```
Groovy and Java allow accessing static fields of a class through its instance, but Kotlin is being more "correct" and disallows that.
### With this PR
Thanks to this PR, the user won't have to replace `flutter` with FlutterExtension in some places, thus decreasing possible confusion.
```kotlin
plugins {
id "com.android.application"
id "dev.flutter.flutter-gradle-plugin"
}
android {
namespace = "io.flutter.examples.hello_world"
compileSdk = flutter.compileSdkVersion
defaultConfig {
applicationId = "io.flutter.examples.hello_world"
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
// ...
}
}
// ...
```
Fixes #140770 and #103124
Adds the possibility of passing a height and width to icons. And also a margin for the distance of the lines between the icons.
fixes [Invisible SliverAppBar title in Material 3 light theme](https://github.com/flutter/flutter/issues/138296)
fixes [`FlexibleSpaceBar` title is misaligned without the leading widget](https://github.com/flutter/flutter/issues/138608)
Previous attempt https://github.com/flutter/flutter/pull/138611
---
### Description
- fixes the `FlexibleSpaceBar` centered title position when there is a leading widget.
- fixes the `FlexibleSpaceBar` title color for Material 3.
- Added documentation when using a long `FlexibleSpaceBar` title and update its test.
- Improved documentation of default title padding.
### Code sample
### Code sample
<details>
<summary>expand to view the code sample</summary>
```dart
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: Example(),
);
}
}
class Example extends StatelessWidget {
const Example({super.key});
@override
Widget build(BuildContext context) {
return const Scaffold(
body: SafeArea(
child: CustomScrollView(
slivers: <Widget>[
SliverAppBar(
leading: Icon(Icons.favorite_rounded),
flexibleSpace: FlexibleSpaceBar(
title: ColoredBox(
color: Color(0xffff0000),
child: Text('SliverAppBar'),
),
),
),
],
)),
);
}
}
```
</details>
### Before
![Screenshot 2024-01-03 at 18 02 25](https://github.com/flutter/flutter/assets/48603081/92ae1062-c78f-4005-8e28-85af617acd60)
### After
![Screenshot 2024-01-03 at 18 02 16](https://github.com/flutter/flutter/assets/48603081/2ef97108-9b50-44f7-a303-018ff1b28db6)
This should wait for some upstream work, just don't want to lose it locally for now. I'll switch this from draft and update the description when it's ready.
While working in https://pub.dev/packages/two_dimensional_scrollables, I found I could eliminate some casts if we added covariants here in the framework.
Much of the 2D aPI in the framework is abstract, so I think it make sense to add these and make it easier/cleaner for subclasses using the APIs.
I made a similar change in https://github.com/flutter/flutter/pull/131358, this would cover all of the cases I could find so its nice and accommodating now.
This PR fixes scrolling issues with `NestedScrollView` using the `BouncingScrollPhysics`. In one of the steps of the calculation, we can reach a state where the position of the inner scrollable is set to a `double` value that falls within `precisionErrorTolerance` of `0` but we were using `==` with `0` rather than checking for a precision. My posts in the linked issue show the current behavior, and how I reached to conclusion (the code in this PR). This PR only addresses the "jumping" of the outer scrollable.
Fixes#136199
I have not finished a test for this since I have never done so and therefore have 0 experience writing tests in Flutter, so any help there would be appreciated. I am also not sure how to test double precision errors in general. I did run all the nested_scroll_view_tests.dart locally and there are no failures.
Fixes#141140.
This ensures that if you call `.copyWith` and pass a `debugLabel`, the `debugLabel` won't be ignored, even if the receiver (the TextStyle you're calling `.copyWith` on) doesn't have a `debugLabel`.
The debugLabel field was added in #12552. I skimmed the discussion there and didn't find anything indicating that the param was being ignored on purpose.
I added a test case that passes with the new code and fails with the old code.
Replace `as Map<Object?, Object?>` to handle nullable case
Fixes runtime issue in Wasm
*Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.*
*List which issues are fixed by this PR. You must list at least one issue. An issue is not required if the PR fixes something trivial like a typo.*
*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*
This reverts commit
d24c01bd0c.
The original change was reverted because it caused some apps to get
stuck on the splash screen on some phones.
An investigation determined that this was due to a rounding error.
Example: The device reports a physical size of 1008.0 x 2198.0 with a
dpr of 1.912500023841858. Flutter would translate that to a logical size
of 527.0588169589221 x 1149.2810314243163 and use that as the input for
its layout algorithm. Since the constraints here are tight, the layout
algorithm would determine that the resulting logical size of the root
render object must be 527.0588169589221 x 1149.2810314243163.
Translating this back to physical pixels by applying the dpr resulted in
a physical size of 1007.9999999999999 x 2198.0 for the frame. Android
now rejected that frame because it didn't match the expected size of
1008.0 x 2198.0 and since no frame had been rendered would never take
down the splash screen.
Prior to dynamically sized views, this wasn't an issue because we would
hard-code the frame size to whatever the requested size was.
Changes in this PR over the original PR:
* The issue has been fixed now by constraining the calculated physical
size to the input physical constraints which makes sure that we always
end up with a size that is acceptable to the operating system.
* The `ViewConfiguration` was refactored to use the slightly more
convenient `BoxConstraints` over the `ViewConstraints` to represent
constraints. Both essentially represent the same thing, but
`BoxConstraints` are more powerful and we avoid a couple of translations
between the two by translating the` ViewConstraints` from the
`FlutterView` to `BoxConstraints` directly when the `ViewConfiguration`
is created.
All changes over the original PR are contained in the second commit of
this PR.
Fixes b/316813075
Part of https://github.com/flutter/flutter/issues/134501.
Introduced `validateGranually` which, apart from announcing the errors to the UI, returns a `Map<Key, bool>` providing more granular validation details: The results of calling `validate` on each `FormField` and their corresponding widget keys.
* related issue: #135363
fixes [`RouteObserver` example throws an error](https://github.com/flutter/flutter/issues/141078)
### Description
This updates the `RouteObserver` example from snippet to Dartpad example and fixes the error when running the code snippet
## Description
This PR adds custom system-wide text selection toolbar buttons on Android for `SelectableRegion` and `SelectionArea`.
https://github.com/flutter/flutter/pull/139738 adds those buttons for `EditableText` (which is used by `TextField` and `SelectableText` but not by `SelectionArea`).
## Related Issue
Step 5 for https://github.com/flutter/flutter/issues/139361
## Tests
Adds 2 tests.
## Description
This PR fixes an issue related to the spell check implementation usage of Regex (searched text should be escaped).
## Related Issue
Fixes https://github.com/flutter/flutter/issues/136032.
## Tests
Adds 1 test.
Support for FFI calls with @Native external functions through Native assets on Android add to app. This enables bundling native code without any build-system boilerplate code.
For more info see:
* https://github.com/flutter/flutter/issues/129757
## Implementation details for Android add2app
The `.so` files are bundled with the same mechanism that bundles `libapp.so`.
(#139572) I would like to request an update to the document to resolve confusion.
I actually modified the code by applying priority as in the comment in [#139572](https://github.com/flutter/flutter/issues/139572) as shown below, but I thought that if 'OutlinedBorder' was used for 'shape', the default value of side for 'OutlinedBorder' was also the developer's intention.
```
OutlinedBorder _getShape(ThemeData theme, ChipThemeData chipTheme, ChipThemeData chipDefaults) {
final BorderSide? resolvedSide =
MaterialStateProperty.resolveAs<BorderSide?>(widget.side, materialStates)
?? MaterialStateProperty.resolveAs<BorderSide?>(chipTheme.side, materialStates);
final BorderSide? resolvedShapeSide =
MaterialStateProperty.resolveAs<BorderSide?>(widget.shape?.side, materialStates)
?? MaterialStateProperty.resolveAs<BorderSide?>(chipTheme.shape?.side, materialStates);
final OutlinedBorder resolvedShape =
MaterialStateProperty.resolveAs<OutlinedBorder?>(widget.shape, materialStates)
?? MaterialStateProperty.resolveAs<OutlinedBorder?>( chipTheme.shape, materialStates)
?? MaterialStateProperty.resolveAs<OutlinedBorder?>(chipDefaults.shape, materialStates)
// TODO(tahatesser): Remove this fallback when Material 2 is deprecated.
?? const StadiumBorder();
// If the side is provided, shape uses the provided side.
if (resolvedSide != null) {
return resolvedShape.copyWith(side: resolvedSide);
}
if (resolvedShapeSide != null) {
return resolvedShape.copyWith(side: resolvedShapeSide);
}
// If the side is not provided
// then the shape's side is used. Otherwise, the default side is used.
return resolvedShape.copyWith(side: chipDefaults.side);
}
```
(in `chip.dart`)
However, (#133856) PR seems to be intended to ignore this and use the aspect of `chipDefault.side` even if the developer specifies `shape.side` as [Border.none] without explicitly applying `side` .
This is probably because the default value of OutlinedBorder is [Border.none].
I think this is an area that can cause enough confusion, but there are a lot of things that need to be modified to reduce confusion through code changes, and the impact on existing code is likely to be significant.
I also confirmed that this is not accurately explained in the API Docs.
So rather than modifying the code, I decided to add additional explanation to the `shape` comment.
If the results are different from what you intended or the updated content is strange, please review. ð
Changes drag release logic so that an armed refresh is only canceled if the user has scrolled back up beyond the point where the refresh indicator was armed. (Fixes https://github.com/flutter/flutter/issues/138848.)
This is the minimal change I found could be made to restore something like the behavior that I would expect.
This may still need a bit of work, because it only masks the second issue I mentioned, that releasing a drag can cause the scroll position to be animated back up from the release point. There is actually a bug about that: https://github.com/flutter/flutter/issues/6052. I would like to see that bug fixed too. This PR doesn't address that, but makes it harder to hit that issue.
@Piinks this is a recreation of #139015 (since I couldn't figure out some issue with a git detached branch, so I fixed the PR and I'm re-submitting it). This version includes one line that was somehow accidentally dropped from the original PR. This will hopefully fix the test failures.
However, I don't have a clue how to write a test for a Flutter UI widget. I'll try to figure that out, but also I don't have a lot of time to work on this. I would appreciate at least some user testing to verify that the new behavior is much more intuitive than the old behavior.
- [?] All existing and new tests are passing.
Fix and unskip the following CanvasKit tests:
- `test/painting/decoration_test.dart`
- `test/rendering/layers_test.dart`
- `test/widgets/app_overrides_test.dart`
[Fix] Consistency in ButtonStyleButton related Tests:
- Replaced the usage of ElevatedButton with FilledButton in FilledButton's test.
- Replaced the usage of TextButton.styleFrom with FilledButton.styleFrom in FilledButton's test.
- Replaced the usage of TextButton.styleFrom with ElevatedButton.styleFrom in ElevatedButton's test.
Currently podhelper.rb will always point plugin builds at the cached engine artifacts, even when using `--local-engine`. In most cases this is fine, since when the final build actually runs it will be using the engine bundled into the app build, which will be the correct local engine build. When trying to test a local engine build with API additions against a local plugin modified to use those additions to ensure that they are working as expected, however, compilation will fail, because the new APIs won't be present in the plugin build.
This fixes that for macOS, and adds a TODO for iOS (which is more complicated to fix due to the host vs target build distinction).
macOS portion of https://github.com/flutter/flutter/issues/132228
Change the following in the `flutter create` templates. I didn't make any auto-migrations for existing apps because none seem that critical:
1. Turn on `ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS` in iOS and macOS.
1. Turn on `BuildIndependentTargetsInParallel` in macOS template. https://github.com/flutter/flutter/pull/125827/files#r1181817619
1. Turn on `DEAD_CODE_STRIPPING` in macOS template.
1. Set `ENABLE_USER_SCRIPT_SANDBOXING=NO` in iOS and macOS template. `flutter` scripts don't work with this on. This might require a migration in the future to explicitly turn this one off. However at least for now if the setting isn't present it defaults to `NO`.
Add migration for `LastUpgradeVersion` so users won't see these validation issues in Xcode.
Run migrator on all the example apps. A few aren't Flutter apps so I edited them in Xcode.
Fixes https://github.com/flutter/flutter/issues/140253
See also https://github.com/flutter/flutter/issues/125817 and https://github.com/flutter/flutter/pull/90304.
fixes https://github.com/flutter/flutter/issues/138289
---
SegmentedButtom.styleFrom has been added to the segment button, so there is no longer any need to the button style from the beginning. It works like ElevatedButton.styleFrom only I added selectedForegroundColor, selectedBackgroundColor. In this way, the user will be able to change the color first without checking the MaterialState states. I added tests of the same controls.
#129215 I opened this problem myself, but I was rejected because I handled too many items in a PR. For now, I wrote a structure that only handles MaterialStates instead of users.
old (still avaliable)
<img width="626" alt="image" src="https://github.com/flutter/flutter/assets/65075121/9446b13b-c355-4d20-bda2-c47a23d42d4f">
new (just an option for developer)
<img width="483" alt="image" src="https://github.com/flutter/flutter/assets/65075121/0a645257-4c83-4029-9484-bd746c02265f">
### Code sample
<details>
<summary>expand to view the code sample</summary>
```dart
import 'package:flutter/material.dart';
/// Flutter code sample for [SegmentedButton].
void main() {
runApp(const SegmentedButtonApp());
}
enum Calendar { day, week, month, year }
class SegmentedButtonApp extends StatefulWidget {
const SegmentedButtonApp({super.key});
@override
State<SegmentedButtonApp> createState() => _SegmentedButtonAppState();
}
class _SegmentedButtonAppState extends State<SegmentedButtonApp> {
Calendar calendarView = Calendar.day;
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(useMaterial3: true),
home: Scaffold(
body: Center(
child: SegmentedButton<Calendar>(
style: SegmentedButton.styleFrom(
foregroundColor: Colors.amber,
visualDensity: VisualDensity.comfortable,
),
// style: const ButtonStyle(
// foregroundColor: MaterialStatePropertyAll<Color>(Colors.deepPurple),
// visualDensity: VisualDensity.comfortable,
// ),
segments: const <ButtonSegment<Calendar>>[
ButtonSegment<Calendar>(
value: Calendar.day,
label: Text('Day'),
icon: Icon(Icons.calendar_view_day)),
ButtonSegment<Calendar>(
value: Calendar.week,
label: Text('Week'),
icon: Icon(Icons.calendar_view_week)),
ButtonSegment<Calendar>(
value: Calendar.month,
label: Text('Month'),
icon: Icon(Icons.calendar_view_month)),
ButtonSegment<Calendar>(
value: Calendar.year,
label: Text('Year'),
icon: Icon(Icons.calendar_today)),
],
selected: <Calendar>{calendarView},
onSelectionChanged: (Set<Calendar> newSelection) {
setState(() {
calendarView = newSelection.first;
});
},
),
),
),
);
}
}
```
</details>
Fixes https://github.com/flutter/flutter/issues/140665 by replacing use of `setUpAll` and `teardownAll` with `setUp` and `teardown` respectively.
My theory has to how this issue happened (and how this PR fixes it) is that `setUpAll` is not guaranteed to run after any `setUp` in any parent test groups. However, `setUp` is guaranteed to run after any set-up callbacks in parent groups. From the [documentation](https://api.flutter.dev/flutter/flutter_test/setUp.html):
> If this is called within a test group, it applies only to tests in that group. The body will be run after any set-up callbacks in parent groups or at the top level.
Meanwhile, [`setUpAll`](https://api.flutter.dev/flutter/flutter_test/setUpAll.html) has a weaker documented guarantee that applies only to other `setUpAll` calls:
> If this is called within a test group, The body will run before all tests in that group. It will be run after any [setUpAll](https://api.flutter.dev/flutter/flutter_test/setUpAll.html) callbacks in parent groups or at the top level. It won't be run if none of the tests in the group are run.
Fixes https://github.com/flutter/flutter/issues/131435, https://github.com/flutter/flutter/issues/104594, https://github.com/flutter/flutter/issues/43400
Currently the method we use for text span hit testing `TextPainter.getPositionForOffset` always returns the closest `TextPosition`, even when the given offset is far away from the text.
The new TextPaintes method tells you the layout bounds `(width = letterspacing / 2 + x_advance + letterspacing / 2, height = font ascent + font descent)` of a character, the PR changes the hit testing implementation such that a TextSpan is only considered hit if the point-down event landed in one of its character's layout bounds.
Potential issues:
In theory since the text is baseline aligned, we should use the max ascent and max descent of each character to calculate the height of the text span's hit-test region, in case some characters in the span have to fall back to a different font, but that will be slower and it typically doesn't make a huge difference.
This is a breaking change.
*Replace this paragraph with a description of what this PR is changing or adding, and why. Consider including before/after screenshots.*
*List which issues are fixed by this PR. You must list at least one issue. An issue is not required if the PR fixes something trivial like a typo.*
*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*