From 540a5130c51a1523340a9a34370433046a0f1a5a Mon Sep 17 00:00:00 2001 From: Peter Kammer Date: Tue, 13 Oct 2026 14:00:11 -0700 Subject: [PATCH 1/7] [tabs_overlay] Update SDK constraint, dependencies, and lints 1. Copied analysis_options.yaml from `flutter create` (Flutter 3.47.7). (Adds analyzer excludes and updates lint doc link) 2. Updated pubspec.yaml to - Raise SDK constraint to ^3.13.0 to match material_ui. - Remove unused cupertino_icons. 3. flutter pub upgrade --major-versions - raises flutter_lints from ^2.0.3 to ^6.0.0 - archive 3.3.2 is no longer a dependency, which resolves GHSA-9v85-q87q-g4vg and GHSA-r285-q736-9v95 --- tabs_overlay/analysis_options.yaml | 9 +- tabs_overlay/pubspec.lock | 217 ++++++++++++++--------------- tabs_overlay/pubspec.yaml | 9 +- 3 files changed, 114 insertions(+), 121 deletions(-) diff --git a/tabs_overlay/analysis_options.yaml b/tabs_overlay/analysis_options.yaml index 61b6c4d..0da40e9 100644 --- a/tabs_overlay/analysis_options.yaml +++ b/tabs_overlay/analysis_options.yaml @@ -9,12 +9,17 @@ # packages, and plugins designed to encourage good coding practices. include: package:flutter_lints/flutter.yaml +analyzer: + exclude: + - build/** + - android/** + - ios/** + linter: # The lint rules applied to this project can be customized in the # section below to disable rules from the `package:flutter_lints/flutter.yaml` # included above or to enable additional rules. A list of all available lints - # and their documentation is published at - # https://dart-lang.github.io/linter/lints/index.html. + # and their documentation is published at https://dart.dev/lints. # # Instead of disabling a lint rule for the entire project in the # section below, it can also be suppressed for a single line of code diff --git a/tabs_overlay/pubspec.lock b/tabs_overlay/pubspec.lock index 043d158..26087a6 100644 --- a/tabs_overlay/pubspec.lock +++ b/tabs_overlay/pubspec.lock @@ -1,86 +1,62 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: - archive: - dependency: transitive - description: - name: archive - sha256: "80e5141fafcb3361653ce308776cfd7d45e6e9fbb429e14eec571382c0c5fecb" - url: "https://pub.dartlang.org" - source: hosted - version: "3.3.2" async: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 - url: "https://pub.dartlang.org" + sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 + url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.13.1" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dartlang.org" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" characters: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c - url: "https://pub.dartlang.org" + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.4.1" clock: dependency: transitive description: name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dartlang.org" + sha256: e51d50bca3217c9a9fa2b41a30e4a38971133f5f9ec7a3d57bae095007f1d28e + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.1.3" collection: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 - url: "https://pub.dartlang.org" + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" source: hosted - version: "1.17.0" - crypto: - dependency: transitive - description: - name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.6" + version: "1.19.1" fake_async: dependency: transitive description: name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dartlang.org" + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.3" file: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" - url: "https://pub.dartlang.org" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.1" flutter: dependency: "direct main" description: flutter @@ -95,10 +71,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 - url: "https://pub.dartlang.org" + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" + url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "6.0.0" flutter_test: dependency: "direct dev" description: flutter @@ -114,162 +90,179 @@ packages: description: flutter source: sdk version: "0.0.0" - js: + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + url: "https://pub.dev" + source: hosted + version: "11.0.2" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: dependency: transitive description: - name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" - url: "https://pub.dartlang.org" + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "3.0.2" lints: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" - url: "https://pub.dartlang.org" + sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df" + url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "6.1.0" matcher: dependency: transitive description: name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" - url: "https://pub.dartlang.org" + sha256: "31bd099b47c10cd1aeb55146a2d46ce0277630ecef3f7dae54ad7873f36696cd" + url: "https://pub.dev" source: hosted - version: "0.12.13" + version: "0.12.20" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 - url: "https://pub.dartlang.org" + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.13.0" meta: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" - url: "https://pub.dartlang.org" + sha256: "307249ce4ff29d58a18e97f6345f539382eb9c9c29ecda628900f31de0443dd9" + url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.19.0" path: dependency: transitive description: name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b - url: "https://pub.dartlang.org" + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.9.1" platform: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" - url: "https://pub.dartlang.org" + sha256: a36d119c13416516a7b5913fbe8af8531e11633d784c550b2125f76c758524ec + url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.2.0" process: dependency: transitive description: name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" - url: "https://pub.dartlang.org" + sha256: "4242ba3508d37e01808bdf71ad1d5bb93a8d671bf2e7450e6b1b353fb0808891" + url: "https://pub.dev" source: hosted - version: "4.2.4" + version: "5.0.6" sky_engine: dependency: transitive description: flutter source: sdk - version: "0.0.99" + version: "0.0.0" source_span: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 - url: "https://pub.dartlang.org" + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" + url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.2" stack_trace: dependency: transitive description: name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 - url: "https://pub.dartlang.org" + sha256: "277654b3034d17ac6f9f1cb5595db011b1d5d41e8806866db28e0abaa101c490" + url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.12.2" stream_channel: dependency: transitive description: name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" - url: "https://pub.dartlang.org" + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.4" string_scanner: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dartlang.org" + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.4.1" sync_http: dependency: transitive description: name: sync_http sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" - url: "https://pub.dartlang.org" + url: "https://pub.dev" source: hosted version: "0.3.1" term_glyph: dependency: transitive description: name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dartlang.org" + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" test_api: dependency: transitive description: name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 - url: "https://pub.dartlang.org" + sha256: "2a122cbe059f8b610d3a5415f42e255b6c17b1f21eee1d960f31080237fb4f11" + url: "https://pub.dev" source: hosted - version: "0.4.16" - typed_data: - dependency: transitive - description: - name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" + version: "0.7.12" vector_math: dependency: transitive description: name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dartlang.org" + sha256: "92b9910f66ed1057fd4da7b040ae7c74cafacf885bdc81be496928d5049b032d" + url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.4.3" vm_service: dependency: transitive description: name: vm_service - sha256: e7fb6c2282f7631712b69c19d1bff82f3767eea33a2321c14fa59ad67ea391c7 - url: "https://pub.dartlang.org" + sha256: "5f37239c4851efcef929cea7824e76df7f2f0970aef85d66bbc430afa40e72f0" + url: "https://pub.dev" source: hosted - version: "9.4.0" + version: "15.3.0" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" webdriver: dependency: transitive description: name: webdriver - sha256: ef67178f0cc7e32c1494645b11639dd1335f1d18814aa8435113a92e9ef9d841 - url: "https://pub.dartlang.org" + sha256: "28b82ec894fed45dd71c23ba62d1af973ed97dd59a4f5790a4d38b0b13e5657e" + url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.2.0" sdks: - dart: ">=2.17.0-0 <3.0.0" + dart: ">=3.13.0 <4.0.0" + flutter: ">=3.18.0-18.0.pre.54" diff --git a/tabs_overlay/pubspec.yaml b/tabs_overlay/pubspec.yaml index 7eb466c..feb5dbb 100644 --- a/tabs_overlay/pubspec.yaml +++ b/tabs_overlay/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.15.0 <3.0.0" + sdk: ^3.13.0 # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -30,11 +30,6 @@ dependencies: flutter: sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.6 - dev_dependencies: integration_test: sdk: flutter @@ -46,7 +41,7 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^2.0.3 + flutter_lints: ^6.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec From e4fc39ef1a1663672c0897ca3f8b83daee129f57 Mon Sep 17 00:00:00 2001 From: Peter Kammer Date: Tue, 13 Oct 2026 14:44:48 -0700 Subject: [PATCH 2/7] [tabs_overlay] Use super parameters Identified with `flutter analyze` and updated with `dart fix --apply --code=use_super_parameters` --- tabs_overlay/lib/main.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tabs_overlay/lib/main.dart b/tabs_overlay/lib/main.dart index 9f6be6d..8efdfdc 100644 --- a/tabs_overlay/lib/main.dart +++ b/tabs_overlay/lib/main.dart @@ -5,7 +5,7 @@ void main() { } class MyApp extends StatelessWidget { - const MyApp({Key? key}) : super(key: key); + const MyApp({super.key}); static const List myTabs = [ Tab(text: 'Tab 1'), From 5b8cee9d49ed157519e610a63527a0bdaf4cfb48 Mon Sep 17 00:00:00 2001 From: Peter Kammer Date: Tue, 13 Oct 2026 15:05:12 -0700 Subject: [PATCH 3/7] [tabs_overlay] Format with dart format Generated with `dart format` (Dart 3.13.5) --- tabs_overlay/integration_test/smoke_test.dart | 10 +++++++--- tabs_overlay/lib/main.dart | 5 +---- tabs_overlay/test/smoke_test.dart | 10 +++++++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/tabs_overlay/integration_test/smoke_test.dart b/tabs_overlay/integration_test/smoke_test.dart index 9ef2b58..b1228cb 100644 --- a/tabs_overlay/integration_test/smoke_test.dart +++ b/tabs_overlay/integration_test/smoke_test.dart @@ -6,12 +6,16 @@ import 'package:tabs_overlay/main.dart' as app; void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - testWidgets('smoke test - app runs and can swipe the tabs', - (WidgetTester tester) async { + testWidgets('smoke test - app runs and can swipe the tabs', ( + WidgetTester tester, + ) async { app.main(); await tester.pumpAndSettle(); await tester.fling( - find.text('Flutter tab 1'), const Offset(-300.0, 0.0), 1000.0); + find.text('Flutter tab 1'), + const Offset(-300.0, 0.0), + 1000.0, + ); expect(find.text('Flutter tab 2'), findsOneWidget); }); } diff --git a/tabs_overlay/lib/main.dart b/tabs_overlay/lib/main.dart index 8efdfdc..fe9b02d 100644 --- a/tabs_overlay/lib/main.dart +++ b/tabs_overlay/lib/main.dart @@ -7,10 +7,7 @@ void main() { class MyApp extends StatelessWidget { const MyApp({super.key}); - static const List myTabs = [ - Tab(text: 'Tab 1'), - Tab(text: 'Tab 2'), - ]; + static const List myTabs = [Tab(text: 'Tab 1'), Tab(text: 'Tab 2')]; @override Widget build(BuildContext context) { diff --git a/tabs_overlay/test/smoke_test.dart b/tabs_overlay/test/smoke_test.dart index 46f8bba..7b4bdcb 100644 --- a/tabs_overlay/test/smoke_test.dart +++ b/tabs_overlay/test/smoke_test.dart @@ -2,12 +2,16 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:tabs_overlay/main.dart'; void main() { - testWidgets('smoke test - app runs and can swipe the tabs', - (WidgetTester tester) async { + testWidgets('smoke test - app runs and can swipe the tabs', ( + WidgetTester tester, + ) async { await tester.pumpWidget(const MyApp()); await tester.pumpAndSettle(); await tester.fling( - find.text('Flutter tab 1'), const Offset(-300.0, 0.0), 1000.0); + find.text('Flutter tab 1'), + const Offset(-300.0, 0.0), + 1000.0, + ); expect(find.text('Flutter tab 2'), findsOneWidget); }); } From 0aaa2b27e63de31eea681eb56ba3fb26317edf0a Mon Sep 17 00:00:00 2001 From: Peter Kammer Date: Wed, 14 Oct 2026 10:55:38 -0700 Subject: [PATCH 4/7] [tabs_overlay] Apply Flutter's automatic iOS project migrations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Generated by `flutter build ios --simulator --debug` on Flutter 3.47.7 No hand edits. Tool output: ``` Resolving dependencies... Downloading packages... material_color_utilities 0.13.0 (0.13.1 available) test_api 0.7.12 (0.7.15 available) Got dependencies! 2 packages have newer versions incompatible with dependency constraints. Try `flutter pub outdated` for more information. Building com.example.tabsOverlay for simulator (ios)... Updating minimum iOS deployment target to 15.0. Upgrading project.pbxproj Upgrading AppFrameworkInfo.plist Updating project for Xcode compatibility. Upgrading project.pbxproj Upgrading Runner.xcscheme Upgrading Info.plist Removing script build phase dependency analysis. Adding input path to Thin Binary build phase. ios/Runner/AppDelegate.swift uses the deprecated @UIApplicationMain attribute, updating. Adding Swift Package Manager integration... 4.4s Upgrading Runner.xcscheme To ensure your app continues to launch on upcoming iOS versions, UIScene lifecycle support will soon be required. Please see https://flutter.dev/to/uiscene-migration for the migration guide. Running Xcode build... Xcode build done. 20.2s ✓ Built build/ios/iphonesimulator/Runner.app ``` --- .../ios/Flutter/AppFrameworkInfo.plist | 2 -- .../ios/Runner.xcodeproj/project.pbxproj | 35 ++++++++++++++++--- .../xcshareddata/xcschemes/Runner.xcscheme | 23 +++++++++++- tabs_overlay/ios/Runner/AppDelegate.swift | 2 +- tabs_overlay/ios/Runner/Info.plist | 4 +++ 5 files changed, 57 insertions(+), 9 deletions(-) diff --git a/tabs_overlay/ios/Flutter/AppFrameworkInfo.plist b/tabs_overlay/ios/Flutter/AppFrameworkInfo.plist index 8d4492f..391a902 100644 --- a/tabs_overlay/ios/Flutter/AppFrameworkInfo.plist +++ b/tabs_overlay/ios/Flutter/AppFrameworkInfo.plist @@ -20,7 +20,5 @@ ???? CFBundleVersion 1.0 - MinimumOSVersion - 9.0 diff --git a/tabs_overlay/ios/Runner.xcodeproj/project.pbxproj b/tabs_overlay/ios/Runner.xcodeproj/project.pbxproj index 21d9954..c00705e 100644 --- a/tabs_overlay/ios/Runner.xcodeproj/project.pbxproj +++ b/tabs_overlay/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -14,6 +14,7 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */ = {isa = PBXBuildFile; productRef = 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -44,6 +45,7 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = FlutterGeneratedPluginSwiftPackage; path = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -51,6 +53,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 78A318202AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -60,6 +63,7 @@ 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( + 78E0A7A72DC9AD7400C4905E /* FlutterGeneratedPluginSwiftPackage */, 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 9740EEB21CF90195004384FC /* Debug.xcconfig */, 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, @@ -105,6 +109,9 @@ /* Begin PBXNativeTarget section */ 97C146ED1CF9000F007C117D /* Runner */ = { + packageProductDependencies = ( + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */, + ); isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( @@ -128,9 +135,12 @@ /* Begin PBXProject section */ 97C146E61CF9000F007C117D /* Project object */ = { + packageReferences = ( + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */, + ); isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -174,10 +184,12 @@ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -188,6 +200,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -276,7 +289,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -354,7 +367,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -403,7 +416,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -483,6 +496,18 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ +/* Begin XCLocalSwiftPackageReference section */ + 781AD8BC2B33823900A9FFBB /* XCLocalSwiftPackageReference "Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = Flutter/ephemeral/Packages/FlutterGeneratedPluginSwiftPackage; + }; +/* End XCLocalSwiftPackageReference section */ +/* Begin XCSwiftPackageProductDependency section */ + 78A3181F2AECB46A00862997 /* FlutterGeneratedPluginSwiftPackage */ = { + isa = XCSwiftPackageProductDependency; + productName = FlutterGeneratedPluginSwiftPackage; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 97C146E61CF9000F007C117D /* Project object */; } diff --git a/tabs_overlay/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/tabs_overlay/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index c87d15a..5db441f 100644 --- a/tabs_overlay/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/tabs_overlay/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,10 +1,28 @@ + + + + + + + + + + diff --git a/tabs_overlay/ios/Runner/AppDelegate.swift b/tabs_overlay/ios/Runner/AppDelegate.swift index d2a14bf..793cbed 100644 --- a/tabs_overlay/ios/Runner/AppDelegate.swift +++ b/tabs_overlay/ios/Runner/AppDelegate.swift @@ -1,7 +1,7 @@ import UIKit import Flutter -@UIApplicationMain +@main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, diff --git a/tabs_overlay/ios/Runner/Info.plist b/tabs_overlay/ios/Runner/Info.plist index 5e5acc4..e4ef79c 100644 --- a/tabs_overlay/ios/Runner/Info.plist +++ b/tabs_overlay/ios/Runner/Info.plist @@ -43,5 +43,9 @@ UIViewControllerBasedStatusBarAppearance + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + From a8e9255da0ba575000792e62378809ad9df48796 Mon Sep 17 00:00:00 2001 From: Peter Kammer Date: Wed, 14 Oct 2026 13:04:11 -0700 Subject: [PATCH 5/7] [tabs_overlay] Recreate the Android project from Flutter 3.47 template The old project (Gradle 6.7, AGP 4.1.0, `apply from: flutter.gradle`) no longer builds with current Flutter. Steps, run from the tabs_overlay directory: 1. rm -rf android 2. flutter create --platforms=android --org com.example \ --project-name tabs_overlay . 3. git restore pubspec.lock .metadata # unrelated from flutter create 4. rm test/widget_test.dart # template sample test # Restore the app's native code and theme 5. git restore android/app/src/main/kotlin \ android/app/src/main/res/layout \ android/app/src/main/res/values # Drop the template's night theme (see below) 6. rm -r android/app/src/main/res/values-night Why remove values-night: The template's values-night/styles.xml redefines LaunchTheme and NormalTheme on Theme.Black.NoTitleBar, which isn't an AppCompat theme. MainActivity is an AppCompatActivity, so in dark mode the app would crash ("You need to use a Theme.AppCompat theme (or descendant) with this activity"). The app's own values/styles.xml already handles dark mode through Theme.MaterialComponents.DayNight. No hand edits. Doesn't build on its own. The template has no AndroidX dependencies. The next commit will add those. --- tabs_overlay/android/app/build.gradle | 71 ------------------- tabs_overlay/android/app/build.gradle.kts | 49 +++++++++++++ .../android/app/src/debug/AndroidManifest.xml | 6 +- .../android/app/src/main/AndroidManifest.xml | 17 ++++- .../app/src/profile/AndroidManifest.xml | 6 +- tabs_overlay/android/build.gradle | 31 -------- tabs_overlay/android/build.gradle.kts | 24 +++++++ tabs_overlay/android/gradle.properties | 7 +- .../gradle/wrapper/gradle-wrapper.properties | 3 +- tabs_overlay/android/settings.gradle | 11 --- tabs_overlay/android/settings.gradle.kts | 26 +++++++ 11 files changed, 125 insertions(+), 126 deletions(-) delete mode 100644 tabs_overlay/android/app/build.gradle create mode 100644 tabs_overlay/android/app/build.gradle.kts delete mode 100644 tabs_overlay/android/build.gradle create mode 100644 tabs_overlay/android/build.gradle.kts delete mode 100644 tabs_overlay/android/settings.gradle create mode 100644 tabs_overlay/android/settings.gradle.kts diff --git a/tabs_overlay/android/app/build.gradle b/tabs_overlay/android/app/build.gradle deleted file mode 100644 index 5442473..0000000 --- a/tabs_overlay/android/app/build.gradle +++ /dev/null @@ -1,71 +0,0 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - -android { - compileSdkVersion flutter.compileSdkVersion - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = '1.8' - } - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.tabs_overlay" - minSdkVersion 21 - targetSdkVersion flutter.targetSdkVersion - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - } - - buildTypes { - release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug - } - } -} - -flutter { - source '../..' -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - implementation 'com.google.android.material:material:1.4.0' - implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1' - implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1' -} diff --git a/tabs_overlay/android/app/build.gradle.kts b/tabs_overlay/android/app/build.gradle.kts new file mode 100644 index 0000000..4dbfe28 --- /dev/null +++ b/tabs_overlay/android/app/build.gradle.kts @@ -0,0 +1,49 @@ +plugins { + id("com.android.application") + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id("dev.flutter.flutter-gradle-plugin") +} + +android { + namespace = "com.example.tabs_overlay" + compileSdk = flutter.compileSdkVersion + ndkVersion = flutter.ndkVersion + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "com.example.tabs_overlay" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = flutter.minSdkVersion + targetSdk = flutter.targetSdkVersion + // Uses the version code from pubspec.yaml. When using split APKs, 1000 * ABI_VERSION + // is added automatically by Flutter. (https://developer.android.com/studio/build/configure-apk-splits#configure-APK-versions) + // You can force using the value of versionCode by specifying the `-P force-version-code-ignoring-abi=true` + // flag during build. + versionCode = flutter.versionCode + versionName = flutter.versionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig = signingConfigs.getByName("debug") + } + } +} + +kotlin { + compilerOptions { + jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17 + } +} + +flutter { + source = "../.." +} diff --git a/tabs_overlay/android/app/src/debug/AndroidManifest.xml b/tabs_overlay/android/app/src/debug/AndroidManifest.xml index d1aa1d6..399f698 100644 --- a/tabs_overlay/android/app/src/debug/AndroidManifest.xml +++ b/tabs_overlay/android/app/src/debug/AndroidManifest.xml @@ -1,6 +1,6 @@ - - diff --git a/tabs_overlay/android/app/src/main/AndroidManifest.xml b/tabs_overlay/android/app/src/main/AndroidManifest.xml index 2895d60..c19f4f8 100644 --- a/tabs_overlay/android/app/src/main/AndroidManifest.xml +++ b/tabs_overlay/android/app/src/main/AndroidManifest.xml @@ -1,6 +1,5 @@ - - + @@ -8,6 +7,7 @@ android:name=".MainActivity" android:exported="true" android:launchMode="singleTop" + android:taskAffinity="" android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" @@ -31,4 +31,15 @@ android:name="flutterEmbedding" android:value="2" /> + + + + + + + diff --git a/tabs_overlay/android/app/src/profile/AndroidManifest.xml b/tabs_overlay/android/app/src/profile/AndroidManifest.xml index d1aa1d6..399f698 100644 --- a/tabs_overlay/android/app/src/profile/AndroidManifest.xml +++ b/tabs_overlay/android/app/src/profile/AndroidManifest.xml @@ -1,6 +1,6 @@ - - diff --git a/tabs_overlay/android/build.gradle b/tabs_overlay/android/build.gradle deleted file mode 100644 index 10ab8e5..0000000 --- a/tabs_overlay/android/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -buildscript { - ext.kotlin_version = '1.4.32' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/tabs_overlay/android/build.gradle.kts b/tabs_overlay/android/build.gradle.kts new file mode 100644 index 0000000..dbee657 --- /dev/null +++ b/tabs_overlay/android/build.gradle.kts @@ -0,0 +1,24 @@ +allprojects { + repositories { + google() + mavenCentral() + } +} + +val newBuildDir: Directory = + rootProject.layout.buildDirectory + .dir("../../build") + .get() +rootProject.layout.buildDirectory.value(newBuildDir) + +subprojects { + val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name) + project.layout.buildDirectory.value(newSubprojectBuildDir) +} +subprojects { + project.evaluationDependsOn(":app") +} + +tasks.register("clean") { + delete(rootProject.layout.buildDirectory) +} diff --git a/tabs_overlay/android/gradle.properties b/tabs_overlay/android/gradle.properties index 94adc3a..e96108c 100644 --- a/tabs_overlay/android/gradle.properties +++ b/tabs_overlay/android/gradle.properties @@ -1,3 +1,6 @@ -org.gradle.jvmargs=-Xmx1536M +org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError android.useAndroidX=true -android.enableJetifier=true +# This newDsl flag was added by the Flutter template +android.newDsl=false +# This builtInKotlin flag was added by the Flutter template +android.builtInKotlin=false diff --git a/tabs_overlay/android/gradle/wrapper/gradle-wrapper.properties b/tabs_overlay/android/gradle/wrapper/gradle-wrapper.properties index bc6a58a..a20f2c4 100644 --- a/tabs_overlay/android/gradle/wrapper/gradle-wrapper.properties +++ b/tabs_overlay/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-all.zip diff --git a/tabs_overlay/android/settings.gradle b/tabs_overlay/android/settings.gradle deleted file mode 100644 index 44e62bc..0000000 --- a/tabs_overlay/android/settings.gradle +++ /dev/null @@ -1,11 +0,0 @@ -include ':app' - -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() - -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } - -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/tabs_overlay/android/settings.gradle.kts b/tabs_overlay/android/settings.gradle.kts new file mode 100644 index 0000000..b28021a --- /dev/null +++ b/tabs_overlay/android/settings.gradle.kts @@ -0,0 +1,26 @@ +pluginManagement { + val flutterSdkPath = + run { + val properties = java.util.Properties() + file("local.properties").inputStream().use { properties.load(it) } + val flutterSdkPath = properties.getProperty("flutter.sdk") + require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" } + flutterSdkPath + } + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id("dev.flutter.flutter-plugin-loader") version "1.0.0" + id("com.android.application") version "9.1.0" apply false + id("org.jetbrains.kotlin.android") version "2.4.0" apply false +} + +include(":app") From 397eb20303fdde692702209cf7fad7e9c33152ab Mon Sep 17 00:00:00 2001 From: Peter Kammer Date: Wed, 14 Oct 2026 13:56:54 -0700 Subject: [PATCH 6/7] [tabs_overlay] Add AndroidX dependencies and adapt to lifecycle 2.7 Hand edits to make the native side build: - android/app/build.gradle.kts: add in dependencies old project declared. - material (keep at 1.4.0 rather than risk changing native tab appearance) - lifecycle moves explicitly to 2.7.0 to match flutter embedding - explicit kotlin-stdlib-jdk7 isn't needed. It's included by the Kotlin Gradle plugin. - PageViewModel.kt: Transformations.map has moved from a static call to an extension function on LiveData. After this commit the app builds/runs. --- tabs_overlay/android/app/build.gradle.kts | 6 ++++++ .../main/kotlin/com/example/tabs_overlay/PageViewModel.kt | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tabs_overlay/android/app/build.gradle.kts b/tabs_overlay/android/app/build.gradle.kts index 4dbfe28..13860fa 100644 --- a/tabs_overlay/android/app/build.gradle.kts +++ b/tabs_overlay/android/app/build.gradle.kts @@ -47,3 +47,9 @@ kotlin { flutter { source = "../.." } + +dependencies { + implementation("com.google.android.material:material:1.4.0") + implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.7.0") + implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0") +} diff --git a/tabs_overlay/android/app/src/main/kotlin/com/example/tabs_overlay/PageViewModel.kt b/tabs_overlay/android/app/src/main/kotlin/com/example/tabs_overlay/PageViewModel.kt index f8553bd..71ce723 100644 --- a/tabs_overlay/android/app/src/main/kotlin/com/example/tabs_overlay/PageViewModel.kt +++ b/tabs_overlay/android/app/src/main/kotlin/com/example/tabs_overlay/PageViewModel.kt @@ -2,12 +2,12 @@ package com.example.tabs_overlay import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.Transformations import androidx.lifecycle.ViewModel +import androidx.lifecycle.map class PageViewModel : ViewModel() { private val _index = MutableLiveData() - val text: LiveData = Transformations.map(_index) { + val text: LiveData = _index.map { "Android tab $it" } From 9319b19c888ea57b422c2b8392580786b61bd630 Mon Sep 17 00:00:00 2001 From: Peter Kammer Date: Thu, 15 Oct 2026 10:20:59 -0700 Subject: [PATCH 7/7] [tabs_overlay] Line up the native and Flutter tab bars on Android 15+ With targetSdk 36 (Flutter 3.47's default), Android 15+ draws the app edge to edge, under the status bar. Flutter's AppBar insets itself for the status bar, but the native AppBarLayout didn't, so it sat a status bar's height higher. The opaque native page covered Flutter's tab bar, and touches on the native tabs missed Flutter's tabs underneath. --- tabs_overlay/android/app/src/main/res/layout/activity_main.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/tabs_overlay/android/app/src/main/res/layout/activity_main.xml b/tabs_overlay/android/app/src/main/res/layout/activity_main.xml index c48706d..47ca7e4 100644 --- a/tabs_overlay/android/app/src/main/res/layout/activity_main.xml +++ b/tabs_overlay/android/app/src/main/res/layout/activity_main.xml @@ -19,6 +19,7 @@