diff --git a/engine/src/flutter/lib/ui/fixtures/ui_test.dart b/engine/src/flutter/lib/ui/fixtures/ui_test.dart index e682d59bd5984..8e099e5676b2e 100644 --- a/engine/src/flutter/lib/ui/fixtures/ui_test.dart +++ b/engine/src/flutter/lib/ui/fixtures/ui_test.dart @@ -373,10 +373,9 @@ external void validateConfiguration(); Future encodeImageProducesExternalUint8List() async { final PictureRecorder pictureRecorder = PictureRecorder(); final Canvas canvas = Canvas(pictureRecorder); - final Paint paint = - Paint() - ..color = Color.fromRGBO(255, 255, 255, 1.0) - ..style = PaintingStyle.fill; + final Paint paint = Paint() + ..color = Color.fromRGBO(255, 255, 255, 1.0) + ..style = PaintingStyle.fill; final Offset c = Offset(50.0, 50.0); canvas.drawCircle(c, 25.0, paint); final Picture picture = pictureRecorder.endRecording(); @@ -406,10 +405,9 @@ external void _validateNotNull(Object? object); Future toByteDataWithoutGPU() async { final PictureRecorder pictureRecorder = PictureRecorder(); final Canvas canvas = Canvas(pictureRecorder); - final Paint paint = - Paint() - ..color = Color.fromRGBO(255, 255, 255, 1.0) - ..style = PaintingStyle.fill; + final Paint paint = Paint() + ..color = Color.fromRGBO(255, 255, 255, 1.0) + ..style = PaintingStyle.fill; final Offset c = Offset(50.0, 50.0); canvas.drawCircle(c, 25.0, paint); final Picture picture = pictureRecorder.endRecording(); @@ -432,10 +430,9 @@ Future toByteDataWithoutGPU() async { Future toByteDataRetries() async { final PictureRecorder pictureRecorder = PictureRecorder(); final Canvas canvas = Canvas(pictureRecorder); - final Paint paint = - Paint() - ..color = Color.fromRGBO(255, 255, 255, 1.0) - ..style = PaintingStyle.fill; + final Paint paint = Paint() + ..color = Color.fromRGBO(255, 255, 255, 1.0) + ..style = PaintingStyle.fill; final Offset c = Offset(50.0, 50.0); canvas.drawCircle(c, 25.0, paint); final Picture picture = pictureRecorder.endRecording(); @@ -456,10 +453,9 @@ Future toByteDataRetries() async { Future toByteDataRetryOverflows() async { final PictureRecorder pictureRecorder = PictureRecorder(); final Canvas canvas = Canvas(pictureRecorder); - final Paint paint = - Paint() - ..color = Color.fromRGBO(255, 255, 255, 1.0) - ..style = PaintingStyle.fill; + final Paint paint = Paint() + ..color = Color.fromRGBO(255, 255, 255, 1.0) + ..style = PaintingStyle.fill; final Offset c = Offset(50.0, 50.0); canvas.drawCircle(c, 25.0, paint); final Picture picture = pictureRecorder.endRecording(); @@ -496,10 +492,9 @@ Future toByteDataRetryOverflows() async { Future toImageRetries() async { final PictureRecorder pictureRecorder = PictureRecorder(); final Canvas canvas = Canvas(pictureRecorder); - final Paint paint = - Paint() - ..color = Color.fromRGBO(255, 255, 255, 1.0) - ..style = PaintingStyle.fill; + final Paint paint = Paint() + ..color = Color.fromRGBO(255, 255, 255, 1.0) + ..style = PaintingStyle.fill; final Offset c = Offset(50.0, 50.0); canvas.drawCircle(c, 25.0, paint); final Picture picture = pictureRecorder.endRecording(); @@ -519,10 +514,9 @@ Future toImageRetries() async { Future toImageRetryOverflows() async { final PictureRecorder pictureRecorder = PictureRecorder(); final Canvas canvas = Canvas(pictureRecorder); - final Paint paint = - Paint() - ..color = Color.fromRGBO(255, 255, 255, 1.0) - ..style = PaintingStyle.fill; + final Paint paint = Paint() + ..color = Color.fromRGBO(255, 255, 255, 1.0) + ..style = PaintingStyle.fill; final Offset c = Offset(50.0, 50.0); canvas.drawCircle(c, 25.0, paint); final Picture picture = pictureRecorder.endRecording(); diff --git a/engine/src/flutter/lib/ui/hooks.dart b/engine/src/flutter/lib/ui/hooks.dart index a95ee2aa3c844..bcf9a1191525f 100644 --- a/engine/src/flutter/lib/ui/hooks.dart +++ b/engine/src/flutter/lib/ui/hooks.dart @@ -129,10 +129,9 @@ List _decodeDisplayFeatures({ bounds[rectOffset + 3] / devicePixelRatio, ), type: DisplayFeatureType.values[type[i]], - state: - state[i] < DisplayFeatureState.values.length - ? DisplayFeatureState.values[state[i]] - : DisplayFeatureState.unknown, + state: state[i] < DisplayFeatureState.values.length + ? DisplayFeatureState.values[state[i]] + : DisplayFeatureState.unknown, ), ); } diff --git a/engine/src/flutter/lib/ui/platform_dispatcher.dart b/engine/src/flutter/lib/ui/platform_dispatcher.dart index 5bf5b47722ca0..ceae0769b21bb 100644 --- a/engine/src/flutter/lib/ui/platform_dispatcher.dart +++ b/engine/src/flutter/lib/ui/platform_dispatcher.dart @@ -531,21 +531,19 @@ class PlatformDispatcher { return PointerDataPacket(data: data); } - static ChannelCallback _keyDataListener(KeyDataCallback onKeyData, Zone zone) => ( - ByteData? packet, - PlatformMessageResponseCallback callback, - ) { - _invoke1( - (KeyData keyData) { - final bool handled = onKeyData(keyData); - final Uint8List response = Uint8List(1); - response[0] = handled ? 1 : 0; - callback(response.buffer.asByteData()); - }, - zone, - _unpackKeyData(packet!), - ); - }; + static ChannelCallback _keyDataListener(KeyDataCallback onKeyData, Zone zone) => + (ByteData? packet, PlatformMessageResponseCallback callback) { + _invoke1( + (KeyData keyData) { + final bool handled = onKeyData(keyData); + final Uint8List response = Uint8List(1); + response[0] = handled ? 1 : 0; + callback(response.buffer.asByteData()); + }, + zone, + _unpackKeyData(packet!), + ); + }; /// A callback that is invoked when key data is available. /// @@ -577,12 +575,11 @@ class PlatformDispatcher { int offset = 0; final int charDataSize = packet.getUint64(kStride * offset++, _kFakeHostEndian); - final String? character = - charDataSize == 0 - ? null - : utf8.decoder.convert( - packet.buffer.asUint8List(kStride * (offset + _kKeyDataFieldCount), charDataSize), - ); + final String? character = charDataSize == 0 + ? null + : utf8.decoder.convert( + packet.buffer.asUint8List(kStride * (offset + _kKeyDataFieldCount), charDataSize), + ); final KeyData keyData = KeyData( timeStamp: Duration(microseconds: packet.getUint64(kStride * offset++, _kFakeHostEndian)), diff --git a/examples/api_windowing/.gitignore b/examples/api_windowing/.gitignore new file mode 100644 index 0000000000000..3820a95c65c3e --- /dev/null +++ b/examples/api_windowing/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ +/coverage/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/examples/api_windowing/.metadata b/examples/api_windowing/.metadata new file mode 100644 index 0000000000000..1babbda168913 --- /dev/null +++ b/examples/api_windowing/.metadata @@ -0,0 +1,45 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "9846826cc39313b1935d557a9787892fe0e51d37" + channel: "[user-branch]" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + base_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + - platform: android + create_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + base_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + - platform: ios + create_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + base_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + - platform: linux + create_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + base_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + - platform: macos + create_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + base_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + - platform: web + create_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + base_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + - platform: windows + create_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + base_revision: 9846826cc39313b1935d557a9787892fe0e51d37 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/examples/api_windowing/README.md b/examples/api_windowing/README.md new file mode 100644 index 0000000000000..b4c6479ac0f27 --- /dev/null +++ b/examples/api_windowing/README.md @@ -0,0 +1,16 @@ +# api_windowing + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/examples/api_windowing/analysis_options.yaml b/examples/api_windowing/analysis_options.yaml new file mode 100644 index 0000000000000..0d2902135caec --- /dev/null +++ b/examples/api_windowing/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +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.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 + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/examples/api_windowing/lib/material/tooltip/tooltip.0.dart b/examples/api_windowing/lib/material/tooltip/tooltip.0.dart new file mode 100644 index 0000000000000..b469458189de0 --- /dev/null +++ b/examples/api_windowing/lib/material/tooltip/tooltip.0.dart @@ -0,0 +1,45 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/material.dart'; + +/// Flutter code sample for [Tooltip]. + +void main() { + final RegularWindowController controller = RegularWindowController( + contentSize: WindowSizing(preferredSize: Size(640, 480)), + ); + runWidget( + RegularWindow(controller: controller, child: const TooltipExampleApp()), + ); +} + +class TooltipExampleApp extends StatelessWidget { + const TooltipExampleApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: ThemeData( + tooltipTheme: const TooltipThemeData(preferBelow: false), + ), + home: Scaffold( + appBar: AppBar(title: const Text('Tooltip Sample')), + body: const Center(child: TooltipSample()), + ), + ); + } +} + +class TooltipSample extends StatelessWidget { + const TooltipSample({super.key}); + + @override + Widget build(BuildContext context) { + return const Tooltip( + message: 'I am a Tooltip', + child: Text('Hover over the text to show a tooltip.'), + ); + } +} diff --git a/examples/api_windowing/macos/.gitignore b/examples/api_windowing/macos/.gitignore new file mode 100644 index 0000000000000..746adbb6b9e14 --- /dev/null +++ b/examples/api_windowing/macos/.gitignore @@ -0,0 +1,7 @@ +# Flutter-related +**/Flutter/ephemeral/ +**/Pods/ + +# Xcode-related +**/dgph +**/xcuserdata/ diff --git a/examples/api_windowing/macos/Flutter/Flutter-Debug.xcconfig b/examples/api_windowing/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 0000000000000..c2efd0b608ba8 --- /dev/null +++ b/examples/api_windowing/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/examples/api_windowing/macos/Flutter/Flutter-Release.xcconfig b/examples/api_windowing/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 0000000000000..c2efd0b608ba8 --- /dev/null +++ b/examples/api_windowing/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1 @@ +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/examples/api_windowing/macos/Runner.xcodeproj/project.pbxproj b/examples/api_windowing/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000..c1e14c02ab186 --- /dev/null +++ b/examples/api_windowing/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,705 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXAggregateTarget section */ + 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { + isa = PBXAggregateTarget; + buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; + buildPhases = ( + 33CC111E2044C6BF0003C045 /* ShellScript */, + ); + dependencies = ( + ); + name = "Flutter Assemble"; + productName = FLX; + }; +/* End PBXAggregateTarget section */ + +/* Begin PBXBuildFile section */ + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC10EC2044A3C60003C045; + remoteInfo = Runner; + }; + 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC111A2044C6BA0003C045; + remoteInfo = FLX; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 33CC110E2044A8840003C045 /* Bundle Framework */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Bundle Framework"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; + 33CC10ED2044A3C60003C045 /* multi_window_ref_app.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "multi_window_ref_app.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; + 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; + 33CC10F72044A3C60003C045 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = Runner/Info.plist; sourceTree = ""; }; + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainFlutterWindow.swift; sourceTree = ""; }; + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; + 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; + 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; + 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 331C80D2294CF70F00263BE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C80D6294CF71000263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C80D7294CF71000263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 33BA886A226E78AF003329D5 /* Configs */ = { + isa = PBXGroup; + children = ( + 33E5194F232828860026EE4D /* AppInfo.xcconfig */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 333000ED22D3DE5D00554162 /* Warnings.xcconfig */, + ); + path = Configs; + sourceTree = ""; + }; + 33CC10E42044A3C60003C045 = { + isa = PBXGroup; + children = ( + 33FAB671232836740065AC1E /* Runner */, + 33CEB47122A05771004F2AC0 /* Flutter */, + 331C80D6294CF71000263BE5 /* RunnerTests */, + 33CC10EE2044A3C60003C045 /* Products */, + D73912EC22F37F3D000D13A0 /* Frameworks */, + ); + sourceTree = ""; + }; + 33CC10EE2044A3C60003C045 /* Products */ = { + isa = PBXGroup; + children = ( + 33CC10ED2044A3C60003C045 /* multi_window_ref_app.app */, + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 33CC11242044D66E0003C045 /* Resources */ = { + isa = PBXGroup; + children = ( + 33CC10F22044A3C60003C045 /* Assets.xcassets */, + 33CC10F42044A3C60003C045 /* MainMenu.xib */, + 33CC10F72044A3C60003C045 /* Info.plist */, + ); + name = Resources; + path = ..; + sourceTree = ""; + }; + 33CEB47122A05771004F2AC0 /* Flutter */ = { + isa = PBXGroup; + children = ( + 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */, + 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, + 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, + 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, + ); + path = Flutter; + sourceTree = ""; + }; + 33FAB671232836740065AC1E /* Runner */ = { + isa = PBXGroup; + children = ( + 33CC10F02044A3C60003C045 /* AppDelegate.swift */, + 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */, + 33E51913231747F40026EE4D /* DebugProfile.entitlements */, + 33E51914231749380026EE4D /* Release.entitlements */, + 33CC11242044D66E0003C045 /* Resources */, + 33BA886A226E78AF003329D5 /* Configs */, + ); + path = Runner; + sourceTree = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C80D4294CF70F00263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C80D1294CF70F00263BE5 /* Sources */, + 331C80D2294CF70F00263BE5 /* Frameworks */, + 331C80D3294CF70F00263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C80DA294CF71000263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + ); + buildRules = ( + ); + dependencies = ( + 33CC11202044C79F0003C045 /* PBXTargetDependency */, + ); + name = Runner; + productName = Runner; + productReference = 33CC10ED2044A3C60003C045 /* multi_window_ref_app.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 33CC10E52044A3C60003C045 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastSwiftUpdateCheck = 0920; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C80D4294CF70F00263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 33CC10EC2044A3C60003C045; + }; + 33CC10EC2044A3C60003C045 = { + CreatedOnToolsVersion = 9.2; + LastSwiftMigration = 1100; + ProvisioningStyle = Automatic; + SystemCapabilities = { + com.apple.Sandbox = { + enabled = 1; + }; + }; + }; + 33CC111A2044C6BA0003C045 = { + CreatedOnToolsVersion = 9.2; + ProvisioningStyle = Manual; + }; + }; + }; + buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 33CC10E42044A3C60003C045; + productRefGroup = 33CC10EE2044A3C60003C045 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 33CC10EC2044A3C60003C045 /* Runner */, + 331C80D4294CF70F00263BE5 /* RunnerTests */, + 33CC111A2044C6BA0003C045 /* Flutter Assemble */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C80D3294CF70F00263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10EB2044A3C60003C045 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, + 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; + }; + 33CC111E2044C6BF0003C045 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + Flutter/ephemeral/FlutterInputs.xcfilelist, + ); + inputPaths = ( + Flutter/ephemeral/tripwire, + ); + outputFileListPaths = ( + Flutter/ephemeral/FlutterOutputs.xcfilelist, + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C80D1294CF70F00263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 33CC10E92044A3C60003C045 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, + 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, + 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC10EC2044A3C60003C045 /* Runner */; + targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; + }; + 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; + targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { + isa = PBXVariantGroup; + children = ( + 33CC10F52044A3C60003C045 /* Base */, + ); + name = MainMenu.xib; + path = Runner; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 331C80DB294CF71000263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.multiWindowRefApp.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/multi_window_ref_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/multi_window_ref_app"; + }; + name = Debug; + }; + 331C80DC294CF71000263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.multiWindowRefApp.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/multi_window_ref_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/multi_window_ref_app"; + }; + name = Release; + }; + 331C80DD294CF71000263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.multiWindowRefApp.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/multi_window_ref_app.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/multi_window_ref_app"; + }; + name = Profile; + }; + 338D0CE9231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + 338D0CEA231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Profile; + }; + 338D0CEB231458BD00FA5F75 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Profile; + }; + 33CC10F92044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 33CC10FA2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CODE_SIGN_IDENTITY = "-"; + COPY_PHASE_STRIP = NO; + DEAD_CODE_STRIPPING = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.15; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Release; + }; + 33CC10FC2044A3C60003C045 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 33CC10FD2044A3C60003C045 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/../Frameworks", + ); + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 33CC111C2044C6BA0003C045 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Manual; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 33CC111D2044C6BA0003C045 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C80DB294CF71000263BE5 /* Debug */, + 331C80DC294CF71000263BE5 /* Release */, + 331C80DD294CF71000263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10F92044A3C60003C045 /* Debug */, + 33CC10FA2044A3C60003C045 /* Release */, + 338D0CE9231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC10FC2044A3C60003C045 /* Debug */, + 33CC10FD2044A3C60003C045 /* Release */, + 338D0CEA231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 33CC111C2044C6BA0003C045 /* Debug */, + 33CC111D2044C6BA0003C045 /* Release */, + 338D0CEB231458BD00FA5F75 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 33CC10E52044A3C60003C045 /* Project object */; +} diff --git a/examples/api_windowing/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/api_windowing/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000000..18d981003d68d --- /dev/null +++ b/examples/api_windowing/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/examples/api_windowing/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/examples/api_windowing/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000000000..e7813cac2f1bf --- /dev/null +++ b/examples/api_windowing/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/api_windowing/macos/Runner.xcworkspace/contents.xcworkspacedata b/examples/api_windowing/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000000..1d526a16ed0f1 --- /dev/null +++ b/examples/api_windowing/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/examples/api_windowing/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/api_windowing/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000000..18d981003d68d --- /dev/null +++ b/examples/api_windowing/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/examples/api_windowing/macos/Runner/AppDelegate.swift b/examples/api_windowing/macos/Runner/AppDelegate.swift new file mode 100644 index 0000000000000..84cd1f9d64f7b --- /dev/null +++ b/examples/api_windowing/macos/Runner/AppDelegate.swift @@ -0,0 +1,25 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Cocoa +import FlutterMacOS + +@main +class AppDelegate: FlutterAppDelegate { + override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { + return true + } + + override func applicationSupportsSecureRestorableState(_ app: NSApplication) -> Bool { + return true + } + + var engine : FlutterEngine?; + + + override func applicationDidFinishLaunching(_ notification: Notification) { + engine = FlutterEngine(name: "project", project: nil); + engine?.run(withEntrypoint:nil); + } +} diff --git a/examples/api_windowing/macos/Runner/Assets.xcassets/Contents.json b/examples/api_windowing/macos/Runner/Assets.xcassets/Contents.json new file mode 100644 index 0000000000000..73c00596a7fca --- /dev/null +++ b/examples/api_windowing/macos/Runner/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/examples/api_windowing/macos/Runner/Base.lproj/MainMenu.xib b/examples/api_windowing/macos/Runner/Base.lproj/MainMenu.xib new file mode 100644 index 0000000000000..a62d87856b51b --- /dev/null +++ b/examples/api_windowing/macos/Runner/Base.lproj/MainMenu.xib @@ -0,0 +1,332 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/api_windowing/macos/Runner/Configs/AppInfo.xcconfig b/examples/api_windowing/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000000000..35840c478829e --- /dev/null +++ b/examples/api_windowing/macos/Runner/Configs/AppInfo.xcconfig @@ -0,0 +1,14 @@ +// Application-level settings for the Runner target. +// +// This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the +// future. If not, the values below would default to using the project name when this becomes a +// 'flutter create' template. + +// The application's name. By default this is also the title of the Flutter window. +PRODUCT_NAME = multi_window_ref_app + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.example.multiWindowRefApp + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2025 com.example. All rights reserved. diff --git a/examples/api_windowing/macos/Runner/Configs/Debug.xcconfig b/examples/api_windowing/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000000000..36b0fd9464f45 --- /dev/null +++ b/examples/api_windowing/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/examples/api_windowing/macos/Runner/Configs/Release.xcconfig b/examples/api_windowing/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000000000..dff4f49561c81 --- /dev/null +++ b/examples/api_windowing/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/examples/api_windowing/macos/Runner/Configs/Warnings.xcconfig b/examples/api_windowing/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000000000..42bcbf4780b18 --- /dev/null +++ b/examples/api_windowing/macos/Runner/Configs/Warnings.xcconfig @@ -0,0 +1,13 @@ +WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings +GCC_WARN_UNDECLARED_SELECTOR = YES +CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES +CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_PRAGMA_PACK = YES +CLANG_WARN_STRICT_PROTOTYPES = YES +CLANG_WARN_COMMA = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES +GCC_WARN_SHADOW = YES +CLANG_WARN_UNREACHABLE_CODE = YES diff --git a/examples/api_windowing/macos/Runner/DebugProfile.entitlements b/examples/api_windowing/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000000000..dddb8a30c851e --- /dev/null +++ b/examples/api_windowing/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,12 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + + diff --git a/examples/api_windowing/macos/Runner/Info.plist b/examples/api_windowing/macos/Runner/Info.plist new file mode 100644 index 0000000000000..4789daa6a443e --- /dev/null +++ b/examples/api_windowing/macos/Runner/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIconFile + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSMinimumSystemVersion + $(MACOSX_DEPLOYMENT_TARGET) + NSHumanReadableCopyright + $(PRODUCT_COPYRIGHT) + NSMainNibFile + MainMenu + NSPrincipalClass + NSApplication + + diff --git a/examples/api_windowing/macos/Runner/MainFlutterWindow.swift b/examples/api_windowing/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000000000..a6a6b9af83072 --- /dev/null +++ b/examples/api_windowing/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,19 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/examples/api_windowing/macos/Runner/Release.entitlements b/examples/api_windowing/macos/Runner/Release.entitlements new file mode 100644 index 0000000000000..852fa1a4728ae --- /dev/null +++ b/examples/api_windowing/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/examples/api_windowing/macos/RunnerTests/RunnerTests.swift b/examples/api_windowing/macos/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000000000..eeb5f29483661 --- /dev/null +++ b/examples/api_windowing/macos/RunnerTests/RunnerTests.swift @@ -0,0 +1,16 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import Cocoa +import FlutterMacOS +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/examples/api_windowing/pubspec.yaml b/examples/api_windowing/pubspec.yaml new file mode 100644 index 0000000000000..d584cc37809e8 --- /dev/null +++ b/examples/api_windowing/pubspec.yaml @@ -0,0 +1,89 @@ +name: api_windowing +description: "A new Flutter project." +# The following line prevents the package from being accidentally published to +# pub.dev using `flutter pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +# In Windows, build-name is used as the major, minor, and patch parts +# of the product and file versions while build-number is used as the build suffix. +version: 1.0.0+1 + +environment: + sdk: ^3.9.0-293.0.dev + +# Dependencies specify other packages that your package needs in order to work. +# To automatically upgrade your package dependencies to the latest versions +# consider running `flutter pub upgrade --major-versions`. Alternatively, +# dependencies can be manually updated by changing the version numbers below to +# the latest version available on pub.dev. To see which dependencies have newer +# versions available, run `flutter pub outdated`. +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.8 + +dev_dependencies: + flutter_test: + sdk: flutter + + # The "flutter_lints" package below contains a set of recommended lints to + # encourage good coding practices. The lint set provided by the package is + # 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: ^5.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter packages. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/to/resolution-aware-images + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/to/asset-from-package + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/to/font-from-package diff --git a/examples/api_windowing/test/widget_test.dart b/examples/api_windowing/test/widget_test.dart new file mode 100644 index 0000000000000..4ec0163757271 --- /dev/null +++ b/examples/api_windowing/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility in the flutter_test package. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:api_windowing/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(const MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/packages/flutter/lib/src/material/tooltip.dart b/packages/flutter/lib/src/material/tooltip.dart index dcfef71e3efcd..d444b0b019b3d 100644 --- a/packages/flutter/lib/src/material/tooltip.dart +++ b/packages/flutter/lib/src/material/tooltip.dart @@ -472,6 +472,119 @@ class Tooltip extends StatefulWidget { } } +class _TooltipStateController { + _TooltipStateController({required this.useWindowing}) { + if (useWindowing) { + tooltipWindowController = _TooltipWindowControllerInternal(); + } else { + overlayPortalController = OverlayPortalController(); + } + } + + final bool useWindowing; + late final _TooltipWindowControllerInternal? tooltipWindowController; + late final OverlayPortalController? overlayPortalController; + + bool get isShowing { + if (useWindowing) { + return tooltipWindowController!.isShowing; + } else { + return overlayPortalController!.isShowing; + } + } + + void show() { + if (useWindowing) { + tooltipWindowController!.show(); + } else { + overlayPortalController!.show(); + } + } + + void hide() { + if (useWindowing) { + tooltipWindowController!.hide(); + } else { + overlayPortalController!.hide(); + } + } +} + +class _TooltipWindowControllerInternal { + late final _TooltipWindowWrapperState state; + + bool get isShowing => state.shown; + + void show() { + state.show(); + } + + void hide() { + state.hide(); + } +} + +class _TooltipWindowWrapper extends StatefulWidget { + _TooltipWindowWrapper({required this.controller, required this.builder, required this.child}); + + final _TooltipWindowControllerInternal controller; + final WidgetBuilder builder; + final Widget child; + + @override + State<_TooltipWindowWrapper> createState() => _TooltipWindowWrapperState(); +} + +class _TooltipWindowWrapperState extends State<_TooltipWindowWrapper> { + bool shown = false; + + @override + void initState() { + super.initState(); + widget.controller.state = this; + } + + @override + Widget build(BuildContext context) { + final FlutterView parent = + WindowControllerContext.of(context)?.rootView ?? PlatformDispatcher.instance.implicitView!; + final RenderBox? box = context.findRenderObject() as RenderBox?; + final Offset? position = box?.localToGlobal(Offset.zero); + const WindowPositionerAnchor parentAnchor = WindowPositionerAnchor.top; + const WindowPositionerAnchor childAnchor = WindowPositionerAnchor.bottom; + + return ViewAnchor( + view: shown + ? TooltipWindow( + controller: TooltipWindowController( + parent: parent, + anchorRect: Rect.fromPoints( + position ?? Offset(0, 0), + position != null && box != null + ? Offset(position.dx + box.size.width, position.dy + box.size.height) + : Offset(100, 100), + ), + positioner: const WindowPositioner( + parentAnchor: parentAnchor, + childAnchor: childAnchor, + ), + ), + child: widget.builder(context), + ) + : null, + child: widget.child, + ); + } + + void show() { + setState(() => shown = true); + } + + void hide() { + setState(() => shown = false); + } +} + /// Contains the state for a [Tooltip]. /// /// This class can be used to programmatically show the Tooltip, see the @@ -490,7 +603,7 @@ class TooltipState extends State with SingleTickerProviderStateMixin { static const bool _defaultEnableFeedback = true; static const TextAlign _defaultTextAlign = TextAlign.start; - final OverlayPortalController _overlayController = OverlayPortalController(); + final _TooltipStateController _overlayController = _TooltipStateController(useWindowing: true); // From InheritedWidgets late bool _visible; @@ -827,12 +940,15 @@ class TooltipState extends State with SingleTickerProviderStateMixin { } Widget _buildTooltipOverlay(BuildContext context) { - final OverlayState overlayState = Overlay.of(context, debugRequiredFor: widget); - final RenderBox box = this.context.findRenderObject()! as RenderBox; - final Offset target = box.localToGlobal( - box.size.center(Offset.zero), - ancestor: overlayState.context.findRenderObject(), - ); + Offset target = Offset.zero; + if (!_overlayController.useWindowing) { + final OverlayState overlayState = Overlay.of(context, debugRequiredFor: widget); + final RenderBox box = this.context.findRenderObject()! as RenderBox; + target = box.localToGlobal( + box.size.center(Offset.zero), + ancestor: overlayState.context.findRenderObject(), + ); + } final (TextStyle defaultTextStyle, BoxDecoration defaultDecoration) = switch (Theme.of( context, @@ -889,6 +1005,7 @@ class TooltipState extends State with SingleTickerProviderStateMixin { widget.verticalOffset ?? tooltipTheme.verticalOffset ?? _defaultVerticalOffset, preferBelow: widget.preferBelow ?? tooltipTheme.preferBelow ?? _defaultPreferBelow, ignorePointer: widget.ignorePointer ?? widget.message != null, + isWindowing: _overlayController.useWindowing, ); return SelectionContainer.maybeOf(context) == null @@ -947,8 +1064,16 @@ class TooltipState extends State with SingleTickerProviderStateMixin { ), ); } + + if (_overlayController.useWindowing) { + return _TooltipWindowWrapper( + controller: _overlayController.tooltipWindowController!, + builder: _buildTooltipOverlay, + child: result, + ); + } return OverlayPortal( - controller: _overlayController, + controller: _overlayController.overlayPortalController!, overlayChildBuilder: _buildTooltipOverlay, child: result, ); @@ -1015,6 +1140,7 @@ class _TooltipOverlay extends StatelessWidget { required this.verticalOffset, required this.preferBelow, required this.ignorePointer, + required this.isWindowing, this.onEnter, this.onExit, }); @@ -1033,6 +1159,7 @@ class _TooltipOverlay extends StatelessWidget { final PointerEnterEventListener? onEnter; final PointerExitEventListener? onExit; final bool ignorePointer; + final bool isWindowing; @override Widget build(BuildContext context) { @@ -1062,6 +1189,11 @@ class _TooltipOverlay extends StatelessWidget { if (onEnter != null || onExit != null) { result = _ExclusiveMouseRegion(onEnter: onEnter, onExit: onExit, child: result); } + + if (isWindowing) { + return result; + } + return Positioned.fill( bottom: MediaQuery.maybeViewInsetsOf(context)?.bottom ?? 0.0, child: CustomSingleChildLayout(