From 8ef31d6021646e856b67a9b195fb89ef8c84d999 Mon Sep 17 00:00:00 2001 From: Jason Rai Date: Tue, 8 Feb 2022 10:29:52 -0500 Subject: [PATCH 01/19] chore: update and fix tests (#107) * update and fix tests * minor * use v2 * add config * again --- .github/workflows/test.yml | 10 +---- codecov.yml | 18 +++++++++ .../main/res/drawable/launch_background.xml | 12 ------ .../app/src/main/res/values/styles.xml | 8 ---- .../example_old/ios/Runner/AppDelegate.swift | 13 ------- .../ios/Runner/Runner-Bridging-Header.h | 1 - flutter_keyboard_visibility/pubspec.yaml | 3 +- .../flutter_keyboard_visibility_test.dart | 9 +++-- ...lutter_keyboard_visibility_test.mocks.dart | 37 +++++++++++++++++++ 9 files changed, 65 insertions(+), 46 deletions(-) create mode 100644 codecov.yml delete mode 100644 flutter_keyboard_visibility/example_old/android/app/src/main/res/drawable/launch_background.xml delete mode 100644 flutter_keyboard_visibility/example_old/android/app/src/main/res/values/styles.xml delete mode 100644 flutter_keyboard_visibility/example_old/ios/Runner/AppDelegate.swift delete mode 100644 flutter_keyboard_visibility/example_old/ios/Runner/Runner-Bridging-Header.h create mode 100644 flutter_keyboard_visibility/test/flutter_keyboard_visibility_test.mocks.dart diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b0e7fd5..98d78af 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -22,11 +22,9 @@ jobs: working-directory: ./flutter_keyboard_visibility - run: flutter pub get working-directory: ./flutter_keyboard_visibility/example - - run: flutter pub get - working-directory: ./flutter_keyboard_visibility/example_old - - run: flutter test --no-sound-null-safety --coverage + - run: flutter test --coverage working-directory: ./flutter_keyboard_visibility - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v2 with: token: ${{ secrets.CODECOV_TOKEN }} file: ./flutter_keyboard_visibility/coverage/lcov.info @@ -47,8 +45,6 @@ jobs: working-directory: ./flutter_keyboard_visibility - run: flutter pub get working-directory: ./flutter_keyboard_visibility/example - - run: flutter pub get - working-directory: ./flutter_keyboard_visibility/example_old - run: flutter analyze working-directory: ./flutter_keyboard_visibility_platform_interface - run: flutter analyze @@ -57,5 +53,3 @@ jobs: working-directory: ./flutter_keyboard_visibility - run: flutter analyze working-directory: ./flutter_keyboard_visibility/example - - run: flutter analyze - working-directory: ./flutter_keyboard_visibility/example_old diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..b9acfd9 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,18 @@ +codecov: + require_ci_to_pass: yes + +coverage: + range: 70..100 + round: down + precision: 2 + status: + project: + default: + target: 70% + threshold: 5% + branches: + - master + patch: off + +comment: + layout: 'reach, diff, files' \ No newline at end of file diff --git a/flutter_keyboard_visibility/example_old/android/app/src/main/res/drawable/launch_background.xml b/flutter_keyboard_visibility/example_old/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f..0000000 --- a/flutter_keyboard_visibility/example_old/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/flutter_keyboard_visibility/example_old/android/app/src/main/res/values/styles.xml b/flutter_keyboard_visibility/example_old/android/app/src/main/res/values/styles.xml deleted file mode 100644 index 00fa441..0000000 --- a/flutter_keyboard_visibility/example_old/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/flutter_keyboard_visibility/example_old/ios/Runner/AppDelegate.swift b/flutter_keyboard_visibility/example_old/ios/Runner/AppDelegate.swift deleted file mode 100644 index 70693e4..0000000 --- a/flutter_keyboard_visibility/example_old/ios/Runner/AppDelegate.swift +++ /dev/null @@ -1,13 +0,0 @@ -import UIKit -import Flutter - -@UIApplicationMain -@objc class AppDelegate: FlutterAppDelegate { - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? - ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } -} diff --git a/flutter_keyboard_visibility/example_old/ios/Runner/Runner-Bridging-Header.h b/flutter_keyboard_visibility/example_old/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 7335fdf..0000000 --- a/flutter_keyboard_visibility/example_old/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" \ No newline at end of file diff --git a/flutter_keyboard_visibility/pubspec.yaml b/flutter_keyboard_visibility/pubspec.yaml index 2de7c99..2560b31 100644 --- a/flutter_keyboard_visibility/pubspec.yaml +++ b/flutter_keyboard_visibility/pubspec.yaml @@ -16,7 +16,8 @@ dependencies: sdk: flutter dev_dependencies: - mockito: ^5.0.11 + build_runner: ^2.1.7 + mockito: ^5.0.17 pedantic: ^1.11.1 flutter_test: sdk: flutter diff --git a/flutter_keyboard_visibility/test/flutter_keyboard_visibility_test.dart b/flutter_keyboard_visibility/test/flutter_keyboard_visibility_test.dart index 272b9b4..9220006 100644 --- a/flutter_keyboard_visibility/test/flutter_keyboard_visibility_test.dart +++ b/flutter_keyboard_visibility/test/flutter_keyboard_visibility_test.dart @@ -3,12 +3,12 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import 'package:flutter_test/flutter_test.dart'; -//ignore: import_of_legacy_library_into_null_safe +import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; -class MockKeyboardVisibilityController extends Mock - implements KeyboardVisibilityController {} +import 'flutter_keyboard_visibility_test.mocks.dart'; +@GenerateMocks([KeyboardVisibilityController]) void main() { group('KeyboardVisibilityProvider', () { testWidgets('It reports true when the keyboard is visible', @@ -205,6 +205,8 @@ void main() { }); }); + // TODO this test complains when ran because SizedBox is not hit testable + // since KeyboardDismissOnTap captures the hit with its GestureDetector group('KeyboardDismissOnTap', () { testWidgets('It removes focus when tapped', (WidgetTester tester) async { var focusNode = FocusNode(); @@ -217,6 +219,7 @@ void main() { SizedBox( key: Key('box'), height: 100, + width: 100, ), TextField( focusNode: focusNode, diff --git a/flutter_keyboard_visibility/test/flutter_keyboard_visibility_test.mocks.dart b/flutter_keyboard_visibility/test/flutter_keyboard_visibility_test.mocks.dart new file mode 100644 index 0000000..f3d67aa --- /dev/null +++ b/flutter_keyboard_visibility/test/flutter_keyboard_visibility_test.mocks.dart @@ -0,0 +1,37 @@ +// Mocks generated by Mockito 5.0.17 from annotations +// in flutter_keyboard_visibility/test/flutter_keyboard_visibility_test.dart. +// Do not manually edit this file. + +import 'dart:async' as _i3; + +import 'package:flutter_keyboard_visibility/src/keyboard_visibility_controller.dart' + as _i2; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types + +/// A class which mocks [KeyboardVisibilityController]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockKeyboardVisibilityController extends _i1.Mock + implements _i2.KeyboardVisibilityController { + MockKeyboardVisibilityController() { + _i1.throwOnMissingStub(this); + } + + @override + _i3.Stream get onChange => + (super.noSuchMethod(Invocation.getter(#onChange), + returnValue: Stream.empty()) as _i3.Stream); + @override + bool get isVisible => + (super.noSuchMethod(Invocation.getter(#isVisible), returnValue: false) + as bool); +} From 68feb303bf97cdca5ac184a6644b61a747432e9b Mon Sep 17 00:00:00 2001 From: Florian Andrieu <32484588+Andrflor@users.noreply.github.com> Date: Tue, 15 Feb 2022 17:15:32 +0100 Subject: [PATCH 02/19] Fix #101 Gesture Arena conflicts (#102) * Fix #101 Gesture Arena conflicts * Added ignore keyboard and config * update example app for testing * refactor * docs * docs Co-authored-by: Kensai Co-authored-by: Jason Rai --- .../runConfigurations/demo_with_provider.xml | 6 -- README.md | 27 +++++- flutter_keyboard_visibility/README.md | 28 +++++- .../example/.gitignore | 3 + .../ios/Flutter/AppFrameworkInfo.plist | 2 +- .../example/ios/Podfile.lock | 4 +- .../ios/Runner.xcodeproj/project.pbxproj | 10 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- .../example/lib/demo_with_provider.dart | 56 ----------- .../example/lib/keyboard_dismiss_demo.dart | 95 +++++++++++++++++++ .../example/lib/main.dart | 84 +++++++++++----- .../example/lib/provider_demo.dart | 46 +++++++++ .../lib/src/ui/keyboard_dismiss_on_tap.dart | 95 +++++++++++++++++-- 13 files changed, 346 insertions(+), 112 deletions(-) delete mode 100644 .idea/runConfigurations/demo_with_provider.xml delete mode 100644 flutter_keyboard_visibility/example/lib/demo_with_provider.dart create mode 100644 flutter_keyboard_visibility/example/lib/keyboard_dismiss_demo.dart create mode 100644 flutter_keyboard_visibility/example/lib/provider_demo.dart diff --git a/.idea/runConfigurations/demo_with_provider.xml b/.idea/runConfigurations/demo_with_provider.xml deleted file mode 100644 index 7a6f1dd..0000000 --- a/.idea/runConfigurations/demo_with_provider.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - \ No newline at end of file diff --git a/README.md b/README.md index 7602a16..ead7e59 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,9 @@ Query and/or subscribe to keyboard visibility directly with the ```dart import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; +import 'dart:async'; + +late StreamSubscription keyboardSubscription; @override void initState() { @@ -69,10 +72,16 @@ void initState() { print('Keyboard visibility direct query: ${keyboardVisibilityController.isVisible}'); // Subscribe - keyboardVisibilityController.onChange.listen((bool visible) { - print('Keyboard visibility update. Is visible: ${visible}'); + keyboardSubscription = keyboardVisibilityController.onChange.listen((bool visible) { + print('Keyboard visibility update. Is visible: $visible'); }); } + +@override +void dispose() { + keyboardSubscription.cancel(); + super.dispose(); +} ``` ## Usage: Dismiss keyboard on tap Place a `KeyboardDismissOnTap` near the top of your `Widget` tree. When a user taps outside of the currently focused `Widget`, the `Widget` will drop focus and the keyboard will be dismissed. @@ -87,6 +96,20 @@ Widget build(BuildContext context) { ); } ``` +By default `KeyboardDismissOnTap` will only dismiss taps not captured by other interactive `Widget`s, like buttons. If you would like to dismiss the keyboard for any tap, including taps on interactive `Widget`s, set `dismissOnCapturedTaps` to true. +```dart +import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; + +// Somewhere near the top of your tree... +@override +Widget build(BuildContext context) { + return KeyboardDismissOnTap( + dismissOnCapturedTaps: true, + child: MyDemoPage(), + ); +} +``` +The `IgnoreKeyboardDismiss` `Widget` can be used to further refine which taps do and do not dismiss the keyboard. Checkout the example app for more detail. ## Testing Call `KeyboardVisibility.setVisibilityForTesting(value)` to set a custom value to use during `flutter test` ```dart diff --git a/flutter_keyboard_visibility/README.md b/flutter_keyboard_visibility/README.md index 1e2973b..80d3f15 100644 --- a/flutter_keyboard_visibility/README.md +++ b/flutter_keyboard_visibility/README.md @@ -4,6 +4,10 @@ React to keyboard visibility changes. +### Note about Flutter Web support + +Web support is an open issue [here](https://github.com/MisterJimson/flutter_keyboard_visibility/issues/10). Currently this library will just return `false` for keyboard visibility on web. + ## Install [Install the package](https://pub.dev/packages/flutter_keyboard_visibility/install) ## Usage: React to Keyboard Visibility Changes @@ -16,11 +20,11 @@ import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; @override Widget build(BuildContext context) { return KeyboardVisibilityBuilder( - builder: (context, isKeyboardVisible) { - return Text( - 'The keyboard is: ${isKeyboardVisible ? 'VISIBLE' : 'NOT VISIBLE'}', - ); - } + builder: (context, isKeyboardVisible) { + return Text( + 'The keyboard is: ${isKeyboardVisible ? 'VISIBLE' : 'NOT VISIBLE'}', + ); + } ); ``` ### Option 2: Within your `Widget` tree using a provider @@ -92,6 +96,20 @@ Widget build(BuildContext context) { ); } ``` +By default `KeyboardDismissOnTap` will only dismiss taps not captured by other interactive `Widget`s, like buttons. If you would like to dismiss the keyboard for any tap, including taps on interactive `Widget`s, set `dismissOnCapturedTaps` to true. +```dart +import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; + +// Somewhere near the top of your tree... +@override +Widget build(BuildContext context) { + return KeyboardDismissOnTap( + dismissOnCapturedTaps: true, + child: MyDemoPage(), + ); +} +``` +The `IgnoreKeyboardDismiss` `Widget` can be used to further refine which taps do and do not dismiss the keyboard. Checkout the example app for more detail. ## Testing Call `KeyboardVisibility.setVisibilityForTesting(value)` to set a custom value to use during `flutter test` ```dart diff --git a/flutter_keyboard_visibility/example/.gitignore b/flutter_keyboard_visibility/example/.gitignore index a9a6e5d..9e8ba18 100644 --- a/flutter_keyboard_visibility/example/.gitignore +++ b/flutter_keyboard_visibility/example/.gitignore @@ -43,3 +43,6 @@ app.*.map.json # Exceptions to above rules. !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages + +# Not supported yet +.macos/ \ No newline at end of file diff --git a/flutter_keyboard_visibility/example/ios/Flutter/AppFrameworkInfo.plist b/flutter_keyboard_visibility/example/ios/Flutter/AppFrameworkInfo.plist index 6b4c0f7..f2872cf 100644 --- a/flutter_keyboard_visibility/example/ios/Flutter/AppFrameworkInfo.plist +++ b/flutter_keyboard_visibility/example/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 8.0 + 9.0 diff --git a/flutter_keyboard_visibility/example/ios/Podfile.lock b/flutter_keyboard_visibility/example/ios/Podfile.lock index 915381a..2fe037c 100644 --- a/flutter_keyboard_visibility/example/ios/Podfile.lock +++ b/flutter_keyboard_visibility/example/ios/Podfile.lock @@ -14,9 +14,9 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/flutter_keyboard_visibility/ios" SPEC CHECKSUMS: - Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c + Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069 PODFILE CHECKSUM: 8e679eca47255a8ca8067c4c67aab20e64cb974d -COCOAPODS: 1.10.1 +COCOAPODS: 1.11.2 diff --git a/flutter_keyboard_visibility/example/ios/Runner.xcodeproj/project.pbxproj b/flutter_keyboard_visibility/example/ios/Runner.xcodeproj/project.pbxproj index f5b703f..6fca510 100644 --- a/flutter_keyboard_visibility/example/ios/Runner.xcodeproj/project.pbxproj +++ b/flutter_keyboard_visibility/example/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 50; objects = { /* Begin PBXBuildFile section */ @@ -166,7 +166,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1020; + LastUpgradeCheck = 1300; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -333,7 +333,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -412,7 +412,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -461,7 +461,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; diff --git a/flutter_keyboard_visibility/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/flutter_keyboard_visibility/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a28140c..3db53b6 100644 --- a/flutter_keyboard_visibility/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/flutter_keyboard_visibility/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ _MyDemoPageState(); -} - -class _MyDemoPageState extends State { - @override - Widget build(BuildContext context) { - return MaterialApp( - home: Scaffold( - appBar: AppBar( - title: Text('Keyboard Visibility Example'), - ), - body: Center( - child: Padding( - padding: EdgeInsets.all(24.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text('This demo uses KeyboardVisibilityProvider.'), - TextField( - keyboardType: TextInputType.text, - decoration: InputDecoration( - labelText: 'Input box for keyboard test', - ), - ), - Container(height: 60.0), - Text( - 'The keyboard is: ${KeyboardVisibilityProvider.isKeyboardVisible(context) ? 'VISIBLE' : 'NOT VISIBLE'}', - ), - ], - ), - ), - ), - ), - ); - } -} diff --git a/flutter_keyboard_visibility/example/lib/keyboard_dismiss_demo.dart b/flutter_keyboard_visibility/example/lib/keyboard_dismiss_demo.dart new file mode 100644 index 0000000..acc77fd --- /dev/null +++ b/flutter_keyboard_visibility/example/lib/keyboard_dismiss_demo.dart @@ -0,0 +1,95 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; + +class KeyboardDismissDemo extends StatelessWidget { + const KeyboardDismissDemo({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Keyboard Dismiss Demo'), + ), + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + KeyboardDismissOnTap( + child: Container( + height: 80, + width: double.infinity, + color: Colors.red, + child: Center(child: Text('Red dismisses on tap')), + ), + ), + KeyboardDismissOnTap( + child: Container( + height: 80, + width: double.infinity, + color: Colors.blue, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('Button does not dismiss, blue does'), + ElevatedButton( + onPressed: () {}, + child: Text('Button'), + ), + ], + ), + ), + ), + KeyboardDismissOnTap( + dismissOnCapturedTaps: true, + child: Container( + height: 80, + width: double.infinity, + color: Colors.green, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('Button and green both dismiss'), + ElevatedButton( + onPressed: () {}, + child: Text('Button'), + ), + ], + ), + ), + ), + KeyboardDismissOnTap( + child: Container( + height: 80, + width: double.infinity, + color: Colors.orange, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('Orange dismisses, black does not'), + IgnoreKeyboardDismiss( + child: Container( + margin: EdgeInsets.only(top: 4), + height: 40, + width: 40, + color: Colors.black, + ), + ), + ], + ), + ), + ), + Spacer(), + TextField( + keyboardType: TextInputType.text, + decoration: InputDecoration( + labelText: 'Input box for keyboard test', + ), + ), + ], + ), + ), + ), + ); + } +} diff --git a/flutter_keyboard_visibility/example/lib/main.dart b/flutter_keyboard_visibility/example/lib/main.dart index b666e2f..2429e19 100644 --- a/flutter_keyboard_visibility/example/lib/main.dart +++ b/flutter_keyboard_visibility/example/lib/main.dart @@ -1,39 +1,71 @@ import 'package:flutter/material.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; +import 'package:flutter_keyboard_visibility_example/keyboard_dismiss_demo.dart'; +import 'package:flutter_keyboard_visibility_example/provider_demo.dart'; void main() { - runApp(MyApp()); + runApp(App()); } -class MyApp extends StatelessWidget { +class App extends StatelessWidget { + const App({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return MaterialApp( - home: KeyboardDismissOnTap( - child: Scaffold( - appBar: AppBar( - title: Text('Keyboard Visibility Example'), - ), - body: Center( - child: Padding( - padding: EdgeInsets.all(24.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - TextField( - keyboardType: TextInputType.text, - decoration: InputDecoration( - labelText: 'Input box for keyboard test', - ), - ), - Container(height: 60.0), - KeyboardVisibilityBuilder(builder: (context, visible) { - return Text( - 'The keyboard is: ${visible ? 'VISIBLE' : 'NOT VISIBLE'}', + home: Demo(), + ); + } +} + +class Demo extends StatelessWidget { + @override + Widget build(BuildContext context) { + return KeyboardDismissOnTap( + child: Scaffold( + appBar: AppBar( + title: Text('Keyboard Visibility Example'), + ), + body: Center( + child: Padding( + padding: EdgeInsets.all(24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + ElevatedButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => ProviderDemo()), + ); + }, + child: Text('Provider Demo'), + ), + ElevatedButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => KeyboardDismissDemo()), ); - }), - ], - ), + }, + child: Text('KeyboardDismiss Demo'), + ), + Spacer(), + TextField( + keyboardType: TextInputType.text, + decoration: InputDecoration( + labelText: 'Input box for keyboard test', + ), + ), + Container(height: 60.0), + KeyboardVisibilityBuilder(builder: (context, visible) { + return Text( + 'The keyboard is: ${visible ? 'VISIBLE' : 'NOT VISIBLE'}', + ); + }), + Spacer(), + ], ), ), ), diff --git a/flutter_keyboard_visibility/example/lib/provider_demo.dart b/flutter_keyboard_visibility/example/lib/provider_demo.dart new file mode 100644 index 0000000..0d7fb02 --- /dev/null +++ b/flutter_keyboard_visibility/example/lib/provider_demo.dart @@ -0,0 +1,46 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; + +class ProviderDemo extends StatelessWidget { + ProviderDemo({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return KeyboardVisibilityProvider( + child: MyDemoPage(), + ); + } +} + +class MyDemoPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Keyboard Visibility Provider'), + ), + body: Center( + child: Padding( + padding: EdgeInsets.all(24.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('This demo uses KeyboardVisibilityProvider.'), + Container(height: 60.0), + TextField( + keyboardType: TextInputType.text, + decoration: InputDecoration( + labelText: 'Input box for keyboard test', + ), + ), + Container(height: 60.0), + Text( + 'The keyboard is: ${KeyboardVisibilityProvider.isKeyboardVisible(context) ? 'VISIBLE' : 'NOT VISIBLE'}', + ), + ], + ), + ), + ), + ); + } +} diff --git a/flutter_keyboard_visibility/lib/src/ui/keyboard_dismiss_on_tap.dart b/flutter_keyboard_visibility/lib/src/ui/keyboard_dismiss_on_tap.dart index a1b56f1..8ca4442 100644 --- a/flutter_keyboard_visibility/lib/src/ui/keyboard_dismiss_on_tap.dart +++ b/flutter_keyboard_visibility/lib/src/ui/keyboard_dismiss_on_tap.dart @@ -6,29 +6,108 @@ import 'package:flutter/widgets.dart'; /// Place this widget somewhere near the top of your widget /// tree and when the user taps outside of a focused widget, /// the focus will be removed and the keyboard will be hidden. -class KeyboardDismissOnTap extends StatelessWidget { +class KeyboardDismissOnTap extends StatefulWidget { + /// Determines whether taps captures by other [Widget]s should dismiss the + /// keyboard. Defaults to false. + /// + /// A common example of this is buttons. By default buttons + /// capture the tap event and the keyboard won't be dismissed. + final bool dismissOnCapturedTaps; + const KeyboardDismissOnTap({ Key? key, required this.child, + this.dismissOnCapturedTaps = false, }) : super(key: key); final Widget child; - void _hideKeyboard(BuildContext context) { - final currentFocus = FocusScope.of(context); + @override + State createState() => _KeyboardDismissOnTapState(); + + /// Used internally by [IgnoreKeyboardDismiss] to notify this Widget to ignore + /// the next tap. + static void ignoreNextTap(BuildContext context) { + context + .dependOnInheritedWidgetOfExactType< + _KeyboardDismissOnTapInheritedWidget>()! + .ignoreNextTap(); + } +} + +class _KeyboardDismissOnTapState extends State { + bool ignoreNextTap = false; - if (!currentFocus.hasPrimaryFocus && currentFocus.hasFocus) { - FocusManager.instance.primaryFocus?.unfocus(); + void _hideKeyboard(BuildContext context) { + if (ignoreNextTap) { + ignoreNextTap = false; + } else { + final currentFocus = FocusScope.of(context); + if (!currentFocus.hasPrimaryFocus && currentFocus.hasFocus) { + FocusManager.instance.primaryFocus?.unfocus(); + } } } @override Widget build(BuildContext context) { - return GestureDetector( - onTap: () { - _hideKeyboard(context); + return _KeyboardDismissOnTapInheritedWidget( + ignoreNextTap: () { + ignoreNextTap = true; + }, + child: !widget.dismissOnCapturedTaps + ? GestureDetector( + onTap: () { + _hideKeyboard(context); + }, + child: widget.child, + ) + : Listener( + onPointerUp: (_) { + _hideKeyboard(context); + }, + behavior: HitTestBehavior.translucent, + child: widget.child, + ), + ); + } +} + +/// Used to ignore keyboard dismiss requests for a specific Widget or Widget +/// tree. +class IgnoreKeyboardDismiss extends StatelessWidget { + final Widget child; + + const IgnoreKeyboardDismiss({ + Key? key, + required this.child, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return Listener( + onPointerUp: (_) { + KeyboardDismissOnTap.ignoreNextTap(context); }, + behavior: HitTestBehavior.translucent, child: child, ); } } + +/// Used internally by [KeyboardDismissOnTap] and [IgnoreKeyboardDismiss] to +/// communicate ignore requests. +class _KeyboardDismissOnTapInheritedWidget extends InheritedWidget { + _KeyboardDismissOnTapInheritedWidget({ + Key? key, + required this.ignoreNextTap, + required Widget child, + }) : super(key: key, child: child); + + final VoidCallback ignoreNextTap; + + @override + bool updateShouldNotify(_KeyboardDismissOnTapInheritedWidget oldWidget) { + return false; + } +} From 190f5beb6f373c50d7cb90a6ca6fab782ed64bb7 Mon Sep 17 00:00:00 2001 From: Jason Rai Date: Tue, 15 Feb 2022 11:26:06 -0500 Subject: [PATCH 03/19] chore: update version and changelog --- flutter_keyboard_visibility/CHANGELOG.md | 12 ++++++++++++ flutter_keyboard_visibility/pubspec.yaml | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/flutter_keyboard_visibility/CHANGELOG.md b/flutter_keyboard_visibility/CHANGELOG.md index a28dcfc..1e1ac7c 100644 --- a/flutter_keyboard_visibility/CHANGELOG.md +++ b/flutter_keyboard_visibility/CHANGELOG.md @@ -1,3 +1,15 @@ +## [5.2.0] - February 15, 2022 +Thanks to Andrflor for help with this feature release + +* Added `dismissOnCapturedTaps` option to KeyboardDismissOnTap +* Added `IgnoreKeyboardDismiss` Widget + +## [5.1.1] - January 13, 2022 +Thanks to jpeiffer for this fix + +* Updated Android tooling versions +* Replaced jcenter with mavenCentral + ## [5.1.0] - October 15, 2021 * Removed Android v1 Embedding Support. If you created your Android project before Flutter 1.12 you diff --git a/flutter_keyboard_visibility/pubspec.yaml b/flutter_keyboard_visibility/pubspec.yaml index 2560b31..1fe62bc 100644 --- a/flutter_keyboard_visibility/pubspec.yaml +++ b/flutter_keyboard_visibility/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_keyboard_visibility description: Flutter plugin for discovering the state of the soft-keyboard visibility on Android and iOS. -version: 5.1.0 +version: 5.2.0 homepage: https://github.com/MisterJimson/flutter_keyboard_visibility repository: https://github.com/MisterJimson/flutter_keyboard_visibility From 5811d59f5c2eae4f3f361da49f0a99910fe10711 Mon Sep 17 00:00:00 2001 From: Jason Rai Date: Tue, 15 Feb 2022 11:32:50 -0500 Subject: [PATCH 04/19] codecov --- codecov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codecov.yml b/codecov.yml index b9acfd9..b7ab168 100644 --- a/codecov.yml +++ b/codecov.yml @@ -2,7 +2,7 @@ codecov: require_ci_to_pass: yes coverage: - range: 70..100 + range: 55..100 round: down precision: 2 status: From 9c753c56a880efa320e0d8656dcaf5d4ad465d5e Mon Sep 17 00:00:00 2001 From: Jason Rai Date: Mon, 13 Jun 2022 13:54:29 -0400 Subject: [PATCH 05/19] feat: improving testing capability and correct docs (#113) --- flutter_keyboard_visibility/README.md | 40 +++++++++++++- .../lib/flutter_keyboard_visibility.dart | 5 +- .../lib/src/keyboard_visibility_handler.dart | 8 +-- .../src/keyboard_visibility_test_util.dart | 15 +++++ .../src/ui/keyboard_visibility_builder.dart | 10 ++-- .../flutter_keyboard_visibility_test.dart | 55 +++++++++++++++++++ 6 files changed, 121 insertions(+), 12 deletions(-) create mode 100644 flutter_keyboard_visibility/lib/src/keyboard_visibility_test_util.dart diff --git a/flutter_keyboard_visibility/README.md b/flutter_keyboard_visibility/README.md index 80d3f15..445deb1 100644 --- a/flutter_keyboard_visibility/README.md +++ b/flutter_keyboard_visibility/README.md @@ -111,11 +111,47 @@ Widget build(BuildContext context) { ``` The `IgnoreKeyboardDismiss` `Widget` can be used to further refine which taps do and do not dismiss the keyboard. Checkout the example app for more detail. ## Testing -Call `KeyboardVisibility.setVisibilityForTesting(value)` to set a custom value to use during `flutter test` +### Testing using mocks +`KeyboardVisibilityProvider` and `KeyboardVisibilityBuilder` accept a `controller` parameter that allow you to mock or replace the logic for reporting keyboard visibility updates. +```dart +@GenerateMocks([KeyboardVisibilityController]) +void main() { + testWidgets('It reports true when the keyboard is visible', (WidgetTester tester) async { + // Pretend that the keyboard is visible. + var mockController = MockKeyboardVisibilityController(); + when(mockController.onChange) + .thenAnswer((_) => Stream.fromIterable([true])); + when(mockController.isVisible).thenAnswer((_) => true); + + // Build a Widget tree and query KeyboardVisibilityProvider + // for the visibility of the keyboard. + bool? isKeyboardVisible; + + await tester.pumpWidget( + KeyboardVisibilityProvider( + controller: mockController, + child: Builder( + builder: (BuildContext context) { + isKeyboardVisible = + KeyboardVisibilityProvider.isKeyboardVisible(context); + return SizedBox(); + }, + ), + ), + ); + + // Verify that KeyboardVisibilityProvider reported that the + // keyboard is visible. + expect(isKeyboardVisible, true); + }); +} +``` +### Testing with a global override +Call `KeyboardVisibilityTesting.setVisibilityForTesting(false);` to set a custom value to use during `flutter test`. This is set globally and will override the standard logic of the native platform. ```dart void main() { testWidgets('My Test', (WidgetTester tester) async { - KeyboardVisibility.setVisibilityForTesting(true); + KeyboardVisibilityTesting.setVisibilityForTesting(true); await tester.pumpWidget(MyApp()); }); } diff --git a/flutter_keyboard_visibility/lib/flutter_keyboard_visibility.dart b/flutter_keyboard_visibility/lib/flutter_keyboard_visibility.dart index 7788673..6447339 100644 --- a/flutter_keyboard_visibility/lib/flutter_keyboard_visibility.dart +++ b/flutter_keyboard_visibility/lib/flutter_keyboard_visibility.dart @@ -1,6 +1,7 @@ library flutter_keyboard_visibility; export 'package:flutter_keyboard_visibility/src/keyboard_visibility_controller.dart'; -export 'package:flutter_keyboard_visibility/src/ui/keyboard_visibility_provider.dart'; -export 'package:flutter_keyboard_visibility/src/ui/keyboard_visibility_builder.dart'; +export 'package:flutter_keyboard_visibility/src/keyboard_visibility_test_util.dart'; export 'package:flutter_keyboard_visibility/src/ui/keyboard_dismiss_on_tap.dart'; +export 'package:flutter_keyboard_visibility/src/ui/keyboard_visibility_builder.dart'; +export 'package:flutter_keyboard_visibility/src/ui/keyboard_visibility_provider.dart'; diff --git a/flutter_keyboard_visibility/lib/src/keyboard_visibility_handler.dart b/flutter_keyboard_visibility/lib/src/keyboard_visibility_handler.dart index 9c5b270..7e9922e 100644 --- a/flutter_keyboard_visibility/lib/src/keyboard_visibility_handler.dart +++ b/flutter_keyboard_visibility/lib/src/keyboard_visibility_handler.dart @@ -1,4 +1,5 @@ import 'dart:async'; + import 'package:flutter_keyboard_visibility_platform_interface/flutter_keyboard_visibility_platform_interface.dart'; /// Provides access to the current keyboard visibility state and emits @@ -33,12 +34,11 @@ class KeyboardVisibilityHandler { /// reported exclusively by the `isVisible` getter. static bool? _testIsVisible; - /// Forces `KeyboardVisibility` to report `isKeyboardVisible` + /// Forces `KeyboardVisibilityHandler` to report `isKeyboardVisible` /// for testing purposes. /// - /// `KeyboardVisibility` will continue reporting `isKeyboardVisible` - /// until the value is changed again with this method. To stop - /// using fake values altogether, set `isKeyboardVisible` to null. + /// `KeyboardVisibilityHandler` will continue reporting `isKeyboardVisible` + /// until the value is changed again with this method. static void setVisibilityForTesting(bool isKeyboardVisible) { _updateValue(isKeyboardVisible); } diff --git a/flutter_keyboard_visibility/lib/src/keyboard_visibility_test_util.dart b/flutter_keyboard_visibility/lib/src/keyboard_visibility_test_util.dart new file mode 100644 index 0000000..68634ff --- /dev/null +++ b/flutter_keyboard_visibility/lib/src/keyboard_visibility_test_util.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_keyboard_visibility/src/keyboard_visibility_handler.dart'; + +@visibleForTesting +class KeyboardVisibilityTesting { + /// Forces this library to report a specific value for `isKeyboardVisible` + /// for testing purposes. + /// + /// `KeyboardVisibility` will continue reporting `isKeyboardVisible` + /// until the value is changed again with this method. + @visibleForTesting + static void setVisibilityForTesting(bool isKeyboardVisible) { + KeyboardVisibilityHandler.setVisibilityForTesting(isKeyboardVisible); + } +} diff --git a/flutter_keyboard_visibility/lib/src/ui/keyboard_visibility_builder.dart b/flutter_keyboard_visibility/lib/src/ui/keyboard_visibility_builder.dart index ba0d12a..675617a 100644 --- a/flutter_keyboard_visibility/lib/src/ui/keyboard_visibility_builder.dart +++ b/flutter_keyboard_visibility/lib/src/ui/keyboard_visibility_builder.dart @@ -11,12 +11,14 @@ class KeyboardVisibilityBuilder extends StatelessWidget { KeyboardVisibilityController get _controller => controller ?? KeyboardVisibilityController(); - const KeyboardVisibilityBuilder({Key? key, required this.builder, this.controller}) - : super(key: key); + const KeyboardVisibilityBuilder({ + Key? key, + required this.builder, + this.controller, + }) : super(key: key); /// A builder method that exposes if the native keyboard is visible. - final Widget Function( - BuildContext, bool isKeyboardVisible) builder; + final Widget Function(BuildContext, bool isKeyboardVisible) builder; @override Widget build(BuildContext context) { diff --git a/flutter_keyboard_visibility/test/flutter_keyboard_visibility_test.dart b/flutter_keyboard_visibility/test/flutter_keyboard_visibility_test.dart index 9220006..339e812 100644 --- a/flutter_keyboard_visibility/test/flutter_keyboard_visibility_test.dart +++ b/flutter_keyboard_visibility/test/flutter_keyboard_visibility_test.dart @@ -244,4 +244,59 @@ void main() { expect(focusNode.hasFocus, false); }); }); + + group('KeyboardVisibilityTesting', () { + testWidgets( + 'setVisibilityForTesting allows overriding of value to true for testing', + (WidgetTester tester) async { + // Pretend that the keyboard is visible. + KeyboardVisibilityTesting.setVisibilityForTesting(true); + + // Build a Widget tree and query KeyboardVisibilityProvider + // for the visibility of the keyboard. + bool? isKeyboardVisible; + + await tester.pumpWidget( + KeyboardVisibilityProvider( + child: Builder( + builder: (BuildContext context) { + isKeyboardVisible = + KeyboardVisibilityProvider.isKeyboardVisible(context); + return SizedBox(); + }, + ), + ), + ); + + // Verify that KeyboardVisibilityProvider reported that the + // keyboard is visible. + expect(isKeyboardVisible, true); + }); + testWidgets( + 'setVisibilityForTesting allows overriding of value to false for testing', + (WidgetTester tester) async { + // Pretend that the keyboard is not visible. + KeyboardVisibilityTesting.setVisibilityForTesting(false); + + // Build a Widget tree and query KeyboardVisibilityProvider + // for the visibility of the keyboard. + bool? isKeyboardVisible; + + await tester.pumpWidget( + KeyboardVisibilityProvider( + child: Builder( + builder: (BuildContext context) { + isKeyboardVisible = + KeyboardVisibilityProvider.isKeyboardVisible(context); + return SizedBox(); + }, + ), + ), + ); + + // Verify that KeyboardVisibilityProvider reported that the + // keyboard is visible. + expect(isKeyboardVisible, false); + }); + }); } From 934b1a6ae2c34b872bb16d8a683e82aa44f11ac7 Mon Sep 17 00:00:00 2001 From: Jason Rai Date: Mon, 13 Jun 2022 13:58:11 -0400 Subject: [PATCH 06/19] feat: version 5.3.0 --- flutter_keyboard_visibility/CHANGELOG.md | 4 ++++ flutter_keyboard_visibility/pubspec.yaml | 2 +- pub_get.sh | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/flutter_keyboard_visibility/CHANGELOG.md b/flutter_keyboard_visibility/CHANGELOG.md index 1e1ac7c..0196fe6 100644 --- a/flutter_keyboard_visibility/CHANGELOG.md +++ b/flutter_keyboard_visibility/CHANGELOG.md @@ -1,3 +1,7 @@ +## [5.3.0] - June 13, 2022 + +* Updated testing docs and made minor changes to allow to easier testing. See readme for details. + ## [5.2.0] - February 15, 2022 Thanks to Andrflor for help with this feature release diff --git a/flutter_keyboard_visibility/pubspec.yaml b/flutter_keyboard_visibility/pubspec.yaml index 1fe62bc..d7c039c 100644 --- a/flutter_keyboard_visibility/pubspec.yaml +++ b/flutter_keyboard_visibility/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_keyboard_visibility description: Flutter plugin for discovering the state of the soft-keyboard visibility on Android and iOS. -version: 5.2.0 +version: 5.3.0 homepage: https://github.com/MisterJimson/flutter_keyboard_visibility repository: https://github.com/MisterJimson/flutter_keyboard_visibility diff --git a/pub_get.sh b/pub_get.sh index e817c7d..bcb4706 100755 --- a/pub_get.sh +++ b/pub_get.sh @@ -2,4 +2,4 @@ (cd flutter_keyboard_visibility_platform_interface && flutter pub get) (cd flutter_keyboard_visibility_web && flutter pub get) (cd flutter_keyboard_visibility && flutter pub get) -(cd flutter_keyboard_visibility/example_old && flutter pub get) +(cd flutter_keyboard_visibility/example && flutter pub get) From 4c29336015270a4b03b16f5f1aee00820ce32638 Mon Sep 17 00:00:00 2001 From: Jason Rai Date: Tue, 28 Jun 2022 16:38:13 -0400 Subject: [PATCH 07/19] chore: update android example --- flutter_keyboard_visibility/android/build.gradle | 2 +- flutter_keyboard_visibility/example/android/app/build.gradle | 4 ++-- .../example/android/app/src/main/AndroidManifest.xml | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/flutter_keyboard_visibility/android/build.gradle b/flutter_keyboard_visibility/android/build.gradle index 8ac759e..8b0c21a 100644 --- a/flutter_keyboard_visibility/android/build.gradle +++ b/flutter_keyboard_visibility/android/build.gradle @@ -22,7 +22,7 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { - compileSdkVersion 30 + compileSdkVersion 31 defaultConfig { minSdkVersion 16 diff --git a/flutter_keyboard_visibility/example/android/app/build.gradle b/flutter_keyboard_visibility/example/android/app/build.gradle index ac0e5be..d525c8e 100644 --- a/flutter_keyboard_visibility/example/android/app/build.gradle +++ b/flutter_keyboard_visibility/example/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 30 + compileSdkVersion 31 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 @@ -45,7 +45,7 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.jrai.flutter_keyboard_visibility_example.example" minSdkVersion 16 - targetSdkVersion 30 + targetSdkVersion 31 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } diff --git a/flutter_keyboard_visibility/example/android/app/src/main/AndroidManifest.xml b/flutter_keyboard_visibility/example/android/app/src/main/AndroidManifest.xml index 8fb0104..f14898c 100644 --- a/flutter_keyboard_visibility/example/android/app/src/main/AndroidManifest.xml +++ b/flutter_keyboard_visibility/example/android/app/src/main/AndroidManifest.xml @@ -9,7 +9,8 @@ android:theme="@style/LaunchTheme" android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode" android:hardwareAccelerated="true" - android:windowSoftInputMode="adjustResize"> + android:windowSoftInputMode="adjustResize" + android:exported="true"> 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 literal 0 HcmV?d00001 diff --git a/flutter_keyboard_visibility/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/flutter_keyboard_visibility/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png new file mode 100644 index 0000000000000000000000000000000000000000..0a3f5fa40fb3d1e0710331a48de5d256da3f275d GIT binary patch literal 520 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 literal 0 HcmV?d00001 diff --git a/flutter_keyboard_visibility/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/flutter_keyboard_visibility/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png new file mode 100644 index 0000000000000000000000000000000000000000..2f1632cfddf3d9dade342351e627a0a75609fb46 GIT binary patch literal 2218 zcmV;b2vzrqP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91K%fHv1ONa40RR91KmY&$07g+lumAuE6iGxuRCodHTWf3-RTMruyW6Fu zQYeUM04eX6D5c0FCjKKPrco1(K`<0SL=crI{PC3-^hZU0kQie$gh-5!7z6SH6Q0J% zqot*`H1q{R5fHFYS}dje@;kG=v$L0(yY0?wY2%*c?A&{2?!D*x?m71{of2gv!$5|C z3>qG_BW}7K_yUcT3A5C6QD<+{aq?x;MAUyAiJn#Jv8_zZtQ{P zTRzbL3U9!qVuZzS$xKU10KiW~Bgdcv1-!uAhQxf3a7q+dU6lj?yoO4Lq4TUN4}h{N z*fIM=SS8|C2$(T>w$`t@3Tka!(r!7W`x z-isCVgQD^mG-MJ;XtJuK3V{Vy72GQ83KRWsHU?e*wrhKk=ApIYeDqLi;JI1e zuvv}5^Dc=k7F7?nm3nIw$NVmU-+R>> zyqOR$-2SDpJ}Pt;^RkJytDVXNTsu|mI1`~G7yw`EJR?VkGfNdqK9^^8P`JdtTV&tX4CNcV4 z&N06nZa??Fw1AgQOUSE2AmPE@WO(Fvo`%m`cDgiv(fAeRA%3AGXUbsGw{7Q`cY;1BI#ac3iN$$Hw z0LT0;xc%=q)me?Y*$xI@GRAw?+}>=9D+KTk??-HJ4=A>`V&vKFS75@MKdSF1JTq{S zc1!^8?YA|t+uKigaq!sT;Z!&0F2=k7F0PIU;F$leJLaw2UI6FL^w}OG&!;+b%ya1c z1n+6-inU<0VM-Y_s5iTElq)ThyF?StVcebpGI znw#+zLx2@ah{$_2jn+@}(zJZ{+}_N9BM;z)0yr|gF-4=Iyu@hI*Lk=-A8f#bAzc9f z`Kd6K--x@t04swJVC3JK1cHY-Hq+=|PN-VO;?^_C#;coU6TDP7Bt`;{JTG;!+jj(` zw5cLQ-(Cz-Tlb`A^w7|R56Ce;Wmr0)$KWOUZ6ai0PhzPeHwdl0H(etP zUV`va_i0s-4#DkNM8lUlqI7>YQLf)(lz9Q3Uw`)nc(z3{m5ZE77Ul$V%m)E}3&8L0 z-XaU|eB~Is08eORPk;=<>!1w)Kf}FOVS2l&9~A+@R#koFJ$Czd%Y(ENTV&A~U(IPI z;UY+gf+&6ioZ=roly<0Yst8ck>(M=S?B-ys3mLdM&)ex!hbt+ol|T6CTS+Sc0jv(& z7ijdvFwBq;0a{%3GGwkDKTeG`b+lyj0jjS1OMkYnepCdoosNY`*zmBIo*981BU%%U z@~$z0V`OVtIbEx5pa|Tct|Lg#ZQf5OYMUMRD>Wdxm5SAqV2}3!ceE-M2 z@O~lQ0OiKQp}o9I;?uxCgYVV?FH|?Riri*U$Zi_`V2eiA>l zdSm6;SEm6#T+SpcE8Ro_f2AwxzI z44hfe^WE3!h@W3RDyA_H440cpmYkv*)6m1XazTqw%=E5Xv7^@^^T7Q2wxr+Z2kVYr + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/flutter_keyboard_visibility/example/macos/Runner/Configs/AppInfo.xcconfig b/flutter_keyboard_visibility/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000..a8528fb --- /dev/null +++ b/flutter_keyboard_visibility/example/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 = flutter_keyboard_visibility_example + +// The application's bundle identifier +PRODUCT_BUNDLE_IDENTIFIER = com.jrai.flutterkeyboardvisibilityexample.flutterKeyboardVisibilityExample + +// The copyright displayed in application information +PRODUCT_COPYRIGHT = Copyright © 2022 com.jrai.flutter_keyboard_visibility_example. All rights reserved. diff --git a/flutter_keyboard_visibility/example/macos/Runner/Configs/Debug.xcconfig b/flutter_keyboard_visibility/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000..36b0fd9 --- /dev/null +++ b/flutter_keyboard_visibility/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/flutter_keyboard_visibility/example/macos/Runner/Configs/Release.xcconfig b/flutter_keyboard_visibility/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000..dff4f49 --- /dev/null +++ b/flutter_keyboard_visibility/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/flutter_keyboard_visibility/example/macos/Runner/Configs/Warnings.xcconfig b/flutter_keyboard_visibility/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000..42bcbf4 --- /dev/null +++ b/flutter_keyboard_visibility/example/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/flutter_keyboard_visibility/example/macos/Runner/DebugProfile.entitlements b/flutter_keyboard_visibility/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000..dddb8a3 --- /dev/null +++ b/flutter_keyboard_visibility/example/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/flutter_keyboard_visibility/example/macos/Runner/Info.plist b/flutter_keyboard_visibility/example/macos/Runner/Info.plist new file mode 100644 index 0000000..4789daa --- /dev/null +++ b/flutter_keyboard_visibility/example/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/flutter_keyboard_visibility/example/macos/Runner/MainFlutterWindow.swift b/flutter_keyboard_visibility/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000..2722837 --- /dev/null +++ b/flutter_keyboard_visibility/example/macos/Runner/MainFlutterWindow.swift @@ -0,0 +1,15 @@ +import Cocoa +import FlutterMacOS + +class MainFlutterWindow: NSWindow { + override func awakeFromNib() { + let flutterViewController = FlutterViewController.init() + let windowFrame = self.frame + self.contentViewController = flutterViewController + self.setFrame(windowFrame, display: true) + + RegisterGeneratedPlugins(registry: flutterViewController) + + super.awakeFromNib() + } +} diff --git a/flutter_keyboard_visibility/example/macos/Runner/Release.entitlements b/flutter_keyboard_visibility/example/macos/Runner/Release.entitlements new file mode 100644 index 0000000..852fa1a --- /dev/null +++ b/flutter_keyboard_visibility/example/macos/Runner/Release.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/flutter_keyboard_visibility/example/windows/.gitignore b/flutter_keyboard_visibility/example/windows/.gitignore new file mode 100644 index 0000000..d492d0d --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/flutter_keyboard_visibility/example/windows/CMakeLists.txt b/flutter_keyboard_visibility/example/windows/CMakeLists.txt new file mode 100644 index 0000000..f44f870 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/CMakeLists.txt @@ -0,0 +1,101 @@ +# Project-level configuration. +cmake_minimum_required(VERSION 3.14) +project(flutter_keyboard_visibility_example LANGUAGES CXX) + +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "flutter_keyboard_visibility_example") + +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(SET CMP0063 NEW) + +# Define build configuration option. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() +# Define settings for the Profile build mode. +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +# Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build; see runner/CMakeLists.txt. +add_subdirectory("runner") + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/flutter_keyboard_visibility/example/windows/flutter/CMakeLists.txt b/flutter_keyboard_visibility/example/windows/flutter/CMakeLists.txt new file mode 100644 index 0000000..930d207 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/flutter/CMakeLists.txt @@ -0,0 +1,104 @@ +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.14) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + windows-x64 $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/flutter_keyboard_visibility/example/windows/flutter/generated_plugin_registrant.cc b/flutter_keyboard_visibility/example/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..cf70736 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,14 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +#include + +void RegisterPlugins(flutter::PluginRegistry* registry) { + FlutterKeyboardVisibilityPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FlutterKeyboardVisibilityPlugin")); +} diff --git a/flutter_keyboard_visibility/example/windows/flutter/generated_plugin_registrant.h b/flutter_keyboard_visibility/example/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..dc139d8 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/flutter/generated_plugin_registrant.h @@ -0,0 +1,15 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/flutter_keyboard_visibility/example/windows/flutter/generated_plugins.cmake b/flutter_keyboard_visibility/example/windows/flutter/generated_plugins.cmake new file mode 100644 index 0000000..a8c2fe0 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/flutter/generated_plugins.cmake @@ -0,0 +1,24 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + flutter_keyboard_visibility_windows +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) + +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/flutter_keyboard_visibility/example/windows/runner/CMakeLists.txt b/flutter_keyboard_visibility/example/windows/runner/CMakeLists.txt new file mode 100644 index 0000000..17411a8 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/runner/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. +apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the build version. +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") + +# Disable Windows macros that collide with C++ standard library functions. +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") + +# Add dependency libraries and include directories. Add any application-specific +# dependencies here. +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") + +# Run the Flutter tool portions of the build. This must not be removed. +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/flutter_keyboard_visibility/example/windows/runner/Runner.rc b/flutter_keyboard_visibility/example/windows/runner/Runner.rc new file mode 100644 index 0000000..318cd58 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) +#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD +#else +#define VERSION_AS_NUMBER 1,0,0,0 +#endif + +#if defined(FLUTTER_VERSION) +#define VERSION_AS_STRING FLUTTER_VERSION +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.jrai.flutter_keyboard_visibility_example" "\0" + VALUE "FileDescription", "flutter_keyboard_visibility_example" "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "flutter_keyboard_visibility_example" "\0" + VALUE "LegalCopyright", "Copyright (C) 2022 com.jrai.flutter_keyboard_visibility_example. All rights reserved." "\0" + VALUE "OriginalFilename", "flutter_keyboard_visibility_example.exe" "\0" + VALUE "ProductName", "flutter_keyboard_visibility_example" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/flutter_keyboard_visibility/example/windows/runner/flutter_window.cpp b/flutter_keyboard_visibility/example/windows/runner/flutter_window.cpp new file mode 100644 index 0000000..b43b909 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/runner/flutter_window.cpp @@ -0,0 +1,61 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opportunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/flutter_keyboard_visibility/example/windows/runner/flutter_window.h b/flutter_keyboard_visibility/example/windows/runner/flutter_window.h new file mode 100644 index 0000000..6da0652 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/runner/flutter_window.h @@ -0,0 +1,33 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/flutter_keyboard_visibility/example/windows/runner/main.cpp b/flutter_keyboard_visibility/example/windows/runner/main.cpp new file mode 100644 index 0000000..e6b5b17 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/runner/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.CreateAndShow(L"flutter_keyboard_visibility_example", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/flutter_keyboard_visibility/example/windows/runner/resource.h b/flutter_keyboard_visibility/example/windows/runner/resource.h new file mode 100644 index 0000000..66a65d1 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/flutter_keyboard_visibility/example/windows/runner/resources/app_icon.ico b/flutter_keyboard_visibility/example/windows/runner/resources/app_icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c04e20caf6370ebb9253ad831cc31de4a9c965f6 GIT binary patch literal 33772 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 literal 0 HcmV?d00001 diff --git a/flutter_keyboard_visibility/example/windows/runner/runner.exe.manifest b/flutter_keyboard_visibility/example/windows/runner/runner.exe.manifest new file mode 100644 index 0000000..a42ea76 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/runner/runner.exe.manifest @@ -0,0 +1,20 @@ + + + + + PerMonitorV2 + + + + + + + + + + + + + + + diff --git a/flutter_keyboard_visibility/example/windows/runner/utils.cpp b/flutter_keyboard_visibility/example/windows/runner/utils.cpp new file mode 100644 index 0000000..f5bf9fa --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/runner/utils.cpp @@ -0,0 +1,64 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr); + std::string utf8_string; + if (target_length == 0 || target_length > utf8_string.max_size()) { + return utf8_string; + } + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, utf8_string.data(), + target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/flutter_keyboard_visibility/example/windows/runner/utils.h b/flutter_keyboard_visibility/example/windows/runner/utils.h new file mode 100644 index 0000000..3879d54 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/runner/utils.h @@ -0,0 +1,19 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/flutter_keyboard_visibility/example/windows/runner/win32_window.cpp b/flutter_keyboard_visibility/example/windows/runner/win32_window.cpp new file mode 100644 index 0000000..c10f08d --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/runner/win32_window.cpp @@ -0,0 +1,245 @@ +#include "win32_window.h" + +#include + +#include "resource.h" + +namespace { + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + FreeLibrary(user32_module); + } +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + return OnCreate(); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} diff --git a/flutter_keyboard_visibility/example/windows/runner/win32_window.h b/flutter_keyboard_visibility/example/windows/runner/win32_window.h new file mode 100644 index 0000000..17ba431 --- /dev/null +++ b/flutter_keyboard_visibility/example/windows/runner/win32_window.h @@ -0,0 +1,98 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates and shows a win32 window with |title| and position and size using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size to will treat the width height passed in to this function + // as logical pixels and scale to appropriate for the default monitor. Returns + // true if the window was created successfully. + bool CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responsponds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_ diff --git a/flutter_keyboard_visibility/pubspec.yaml b/flutter_keyboard_visibility/pubspec.yaml index d7c039c..519aeb6 100644 --- a/flutter_keyboard_visibility/pubspec.yaml +++ b/flutter_keyboard_visibility/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_keyboard_visibility description: Flutter plugin for discovering the state of the soft-keyboard visibility on Android and iOS. -version: 5.3.0 +version: 5.4.0 homepage: https://github.com/MisterJimson/flutter_keyboard_visibility repository: https://github.com/MisterJimson/flutter_keyboard_visibility @@ -11,7 +11,10 @@ environment: dependencies: meta: ">=1.0.0 <2.0.0" flutter_keyboard_visibility_platform_interface: ^2.0.0 + flutter_keyboard_visibility_linux: ^1.0.0 + flutter_keyboard_visibility_macos: ^1.0.0 flutter_keyboard_visibility_web: ^2.0.0 + flutter_keyboard_visibility_windows: ^1.0.0 flutter: sdk: flutter @@ -31,4 +34,10 @@ flutter: ios: pluginClass: FlutterKeyboardVisibilityPlugin web: - default_package: flutter_keyboard_visibility_web \ No newline at end of file + default_package: flutter_keyboard_visibility_web + macos: + default_package: flutter_keyboard_visibility_macos + linux: + default_package: flutter_keyboard_visibility_linux + windows: + default_package: flutter_keyboard_visibility_windows \ No newline at end of file diff --git a/flutter_keyboard_visibility_linux/.gitignore b/flutter_keyboard_visibility_linux/.gitignore new file mode 100644 index 0000000..60d5593 --- /dev/null +++ b/flutter_keyboard_visibility_linux/.gitignore @@ -0,0 +1,16 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +pubspec.lock + +build/ + +*.iml + +.idea/ + +.flutter-plugins +.flutter-plugins-dependencies \ No newline at end of file diff --git a/flutter_keyboard_visibility_linux/CHANGELOG.md b/flutter_keyboard_visibility_linux/CHANGELOG.md new file mode 100644 index 0000000..078deac --- /dev/null +++ b/flutter_keyboard_visibility_linux/CHANGELOG.md @@ -0,0 +1,3 @@ +## [1.0.0] - October 4, 2022 + +* Initial support so Flutter apps that run on Linux won't encounter errors. Visibility is returned as false. \ No newline at end of file diff --git a/flutter_keyboard_visibility_linux/LICENSE b/flutter_keyboard_visibility_linux/LICENSE new file mode 100644 index 0000000..ef62255 --- /dev/null +++ b/flutter_keyboard_visibility_linux/LICENSE @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2022 Jason Rai +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/flutter_keyboard_visibility_linux/README.md b/flutter_keyboard_visibility_linux/README.md new file mode 100644 index 0000000..c94cb61 --- /dev/null +++ b/flutter_keyboard_visibility_linux/README.md @@ -0,0 +1,6 @@ +# Flutter Keyboard Visibility Linux +Linux support for Flutter Keyboard Visibility + +See the full plugin [here](https://pub.dev/packages/flutter_keyboard_visibility); +## Status +Currently just returns false for visibility. In the future we would like to offer virtual keyboard detection. \ No newline at end of file diff --git a/flutter_keyboard_visibility_linux/analysis_options.yaml b/flutter_keyboard_visibility_linux/analysis_options.yaml new file mode 100644 index 0000000..b4ab8c9 --- /dev/null +++ b/flutter_keyboard_visibility_linux/analysis_options.yaml @@ -0,0 +1,5 @@ +include: package:pedantic/analysis_options.yaml + +analyzer: + strong-mode: + implicit-casts: false diff --git a/flutter_keyboard_visibility_linux/lib/flutter_keyboard_visibility_linux.dart b/flutter_keyboard_visibility_linux/lib/flutter_keyboard_visibility_linux.dart new file mode 100644 index 0000000..2094929 --- /dev/null +++ b/flutter_keyboard_visibility_linux/lib/flutter_keyboard_visibility_linux.dart @@ -0,0 +1,21 @@ +import 'package:flutter_keyboard_visibility_platform_interface/flutter_keyboard_visibility_platform_interface.dart'; + +/// The Linux implementation of the [FlutterKeyboardVisibilityPlatform] of the +/// FlutterKeyboardVisibility plugin. +class FlutterKeyboardVisibilityPluginLinux + extends FlutterKeyboardVisibilityPlatform { + + /// Factory method that initializes the FlutterKeyboardVisibility plugin + /// platform with an instance of the plugin for Linux. + static void registerWith() { + FlutterKeyboardVisibilityPlatform.instance = + FlutterKeyboardVisibilityPluginLinux(); + } + + /// Emits changes to keyboard visibility from the platform. Linux is not + /// implemented yet so false is returned. + @override + Stream get onChange async* { + yield false; + } +} diff --git a/flutter_keyboard_visibility_linux/pubspec.yaml b/flutter_keyboard_visibility_linux/pubspec.yaml new file mode 100644 index 0000000..744940a --- /dev/null +++ b/flutter_keyboard_visibility_linux/pubspec.yaml @@ -0,0 +1,26 @@ +name: flutter_keyboard_visibility_linux +description: An implementation for the linux platform of `flutter_keyboard_visibility' +version: 1.0.0 +homepage: https://github.com/MisterJimson/flutter_keyboard_visibility +repository: https://github.com/MisterJimson/flutter_keyboard_visibility + +environment: + sdk: '>=2.12.0 <3.0.0' + flutter: '>=1.20.0' + +flutter: + plugin: + implements: flutter_keyboard_visibility + platforms: + linux: + dartPluginClass: FlutterKeyboardVisibilityPluginLinux + +dependencies: + flutter_keyboard_visibility_platform_interface: ^2.0.0 + flutter: + sdk: flutter + +dev_dependencies: + pedantic: ^1.11.0 + flutter_test: + sdk: flutter diff --git a/flutter_keyboard_visibility_macos/.gitignore b/flutter_keyboard_visibility_macos/.gitignore new file mode 100644 index 0000000..60d5593 --- /dev/null +++ b/flutter_keyboard_visibility_macos/.gitignore @@ -0,0 +1,16 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +pubspec.lock + +build/ + +*.iml + +.idea/ + +.flutter-plugins +.flutter-plugins-dependencies \ No newline at end of file diff --git a/flutter_keyboard_visibility_macos/CHANGELOG.md b/flutter_keyboard_visibility_macos/CHANGELOG.md new file mode 100644 index 0000000..701d4ad --- /dev/null +++ b/flutter_keyboard_visibility_macos/CHANGELOG.md @@ -0,0 +1,3 @@ +## [1.0.0] - October 4, 2022 + +* Initial support so Flutter apps that run on macOS won't encounter errors. Visibility is returned as false. \ No newline at end of file diff --git a/flutter_keyboard_visibility_macos/LICENSE b/flutter_keyboard_visibility_macos/LICENSE new file mode 100644 index 0000000..ef62255 --- /dev/null +++ b/flutter_keyboard_visibility_macos/LICENSE @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2022 Jason Rai +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/flutter_keyboard_visibility_macos/README.md b/flutter_keyboard_visibility_macos/README.md new file mode 100644 index 0000000..f8c41e0 --- /dev/null +++ b/flutter_keyboard_visibility_macos/README.md @@ -0,0 +1,6 @@ +# Flutter Keyboard Visibility Web +macOS support for Flutter Keyboard Visibility + +See the full plugin [here](https://pub.dev/packages/flutter_keyboard_visibility); +## Status +Currently just returns false for visibility. In the future we would like to offer virtual keyboard detection. \ No newline at end of file diff --git a/flutter_keyboard_visibility_macos/analysis_options.yaml b/flutter_keyboard_visibility_macos/analysis_options.yaml new file mode 100644 index 0000000..b4ab8c9 --- /dev/null +++ b/flutter_keyboard_visibility_macos/analysis_options.yaml @@ -0,0 +1,5 @@ +include: package:pedantic/analysis_options.yaml + +analyzer: + strong-mode: + implicit-casts: false diff --git a/flutter_keyboard_visibility_macos/lib/flutter_keyboard_visibility_macos.dart b/flutter_keyboard_visibility_macos/lib/flutter_keyboard_visibility_macos.dart new file mode 100644 index 0000000..56b387b --- /dev/null +++ b/flutter_keyboard_visibility_macos/lib/flutter_keyboard_visibility_macos.dart @@ -0,0 +1,21 @@ +import 'package:flutter_keyboard_visibility_platform_interface/flutter_keyboard_visibility_platform_interface.dart'; + +/// The macOS implementation of the [FlutterKeyboardVisibilityPlatform] of the +/// FlutterKeyboardVisibility plugin. +class FlutterKeyboardVisibilityPluginMacos + extends FlutterKeyboardVisibilityPlatform { + + /// Factory method that initializes the FlutterKeyboardVisibility plugin + /// platform with an instance of the plugin for macOS. + static void registerWith() { + FlutterKeyboardVisibilityPlatform.instance = + FlutterKeyboardVisibilityPluginMacos(); + } + + /// Emits changes to keyboard visibility from the platform. MacOS is not + /// implemented yet so false is returned. + @override + Stream get onChange async* { + yield false; + } +} diff --git a/flutter_keyboard_visibility_macos/pubspec.yaml b/flutter_keyboard_visibility_macos/pubspec.yaml new file mode 100644 index 0000000..8d13094 --- /dev/null +++ b/flutter_keyboard_visibility_macos/pubspec.yaml @@ -0,0 +1,26 @@ +name: flutter_keyboard_visibility_macos +description: An implementation for the macOS platform of `flutter_keyboard_visibility' +version: 1.0.0 +homepage: https://github.com/MisterJimson/flutter_keyboard_visibility +repository: https://github.com/MisterJimson/flutter_keyboard_visibility + +environment: + sdk: '>=2.12.0 <3.0.0' + flutter: ">=1.20.0" + +flutter: + plugin: + implements: flutter_keyboard_visibility + platforms: + macos: + dartPluginClass: FlutterKeyboardVisibilityPluginMacos + +dependencies: + flutter_keyboard_visibility_platform_interface: ^2.0.0 + flutter: + sdk: flutter + +dev_dependencies: + pedantic: ^1.11.0 + flutter_test: + sdk: flutter \ No newline at end of file diff --git a/flutter_keyboard_visibility_web/lib/flutter_keyboard_visibility_web.dart b/flutter_keyboard_visibility_web/lib/flutter_keyboard_visibility_web.dart index 611849b..e3f6ffb 100644 --- a/flutter_keyboard_visibility_web/lib/flutter_keyboard_visibility_web.dart +++ b/flutter_keyboard_visibility_web/lib/flutter_keyboard_visibility_web.dart @@ -4,16 +4,16 @@ import 'package:flutter_web_plugins/flutter_web_plugins.dart'; /// The web implementation of the [FlutterKeyboardVisibilityPlatform] of the /// FlutterKeyboardVisibility plugin. -class FlutterKeyboardVisibilityPlugin +class FlutterKeyboardVisibilityPluginWeb extends FlutterKeyboardVisibilityPlatform { - /// Constructs a [FlutterKeyboardVisibilityPlugin]. - FlutterKeyboardVisibilityPlugin(html.Navigator navigator); + /// Constructs a [FlutterKeyboardVisibilityPluginWeb]. + FlutterKeyboardVisibilityPluginWeb(html.Navigator navigator); /// Factory method that initializes the FlutterKeyboardVisibility plugin /// platform with an instance of the plugin for the web. static void registerWith(Registrar registrar) { FlutterKeyboardVisibilityPlatform.instance = - FlutterKeyboardVisibilityPlugin(html.window.navigator); + FlutterKeyboardVisibilityPluginWeb(html.window.navigator); } /// Emits changes to keyboard visibility from the platform. Web is not diff --git a/flutter_keyboard_visibility_web/pubspec.yaml b/flutter_keyboard_visibility_web/pubspec.yaml index ca216cd..311199a 100644 --- a/flutter_keyboard_visibility_web/pubspec.yaml +++ b/flutter_keyboard_visibility_web/pubspec.yaml @@ -12,7 +12,7 @@ flutter: plugin: platforms: web: - pluginClass: FlutterKeyboardVisibilityPlugin + pluginClass: FlutterKeyboardVisibilityPluginWeb fileName: flutter_keyboard_visibility_web.dart dependencies: diff --git a/flutter_keyboard_visibility_windows/.gitignore b/flutter_keyboard_visibility_windows/.gitignore new file mode 100644 index 0000000..60d5593 --- /dev/null +++ b/flutter_keyboard_visibility_windows/.gitignore @@ -0,0 +1,16 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +pubspec.lock + +build/ + +*.iml + +.idea/ + +.flutter-plugins +.flutter-plugins-dependencies \ No newline at end of file diff --git a/flutter_keyboard_visibility_windows/CHANGELOG.md b/flutter_keyboard_visibility_windows/CHANGELOG.md new file mode 100644 index 0000000..32a674a --- /dev/null +++ b/flutter_keyboard_visibility_windows/CHANGELOG.md @@ -0,0 +1,3 @@ +## [1.0.0] - October 4, 2022 + +* Initial support so Flutter apps that run on Windows won't encounter errors. Visibility is returned as false. \ No newline at end of file diff --git a/flutter_keyboard_visibility_windows/LICENSE b/flutter_keyboard_visibility_windows/LICENSE new file mode 100644 index 0000000..ef62255 --- /dev/null +++ b/flutter_keyboard_visibility_windows/LICENSE @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2022 Jason Rai +All rights reserved. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/flutter_keyboard_visibility_windows/README.md b/flutter_keyboard_visibility_windows/README.md new file mode 100644 index 0000000..fcfcc6c --- /dev/null +++ b/flutter_keyboard_visibility_windows/README.md @@ -0,0 +1,6 @@ +# Flutter Keyboard Visibility Windows +Windows support for Flutter Keyboard Visibility + +See the full plugin [here](https://pub.dev/packages/flutter_keyboard_visibility); +## Status +Currently just returns false for visibility. In the future we would like to offer virtual keyboard detection. \ No newline at end of file diff --git a/flutter_keyboard_visibility_windows/analysis_options.yaml b/flutter_keyboard_visibility_windows/analysis_options.yaml new file mode 100644 index 0000000..b4ab8c9 --- /dev/null +++ b/flutter_keyboard_visibility_windows/analysis_options.yaml @@ -0,0 +1,5 @@ +include: package:pedantic/analysis_options.yaml + +analyzer: + strong-mode: + implicit-casts: false diff --git a/flutter_keyboard_visibility_windows/lib/flutter_keyboard_visibility_windows.dart b/flutter_keyboard_visibility_windows/lib/flutter_keyboard_visibility_windows.dart new file mode 100644 index 0000000..5fc6e37 --- /dev/null +++ b/flutter_keyboard_visibility_windows/lib/flutter_keyboard_visibility_windows.dart @@ -0,0 +1,21 @@ +import 'package:flutter_keyboard_visibility_platform_interface/flutter_keyboard_visibility_platform_interface.dart'; + +/// The Windows implementation of the [FlutterKeyboardVisibilityPlatform] of the +/// FlutterKeyboardVisibility plugin. +class FlutterKeyboardVisibilityPluginWindows + extends FlutterKeyboardVisibilityPlatform { + + /// Factory method that initializes the FlutterKeyboardVisibility plugin + /// platform with an instance of the plugin for Windows. + static void registerWith() { + FlutterKeyboardVisibilityPlatform.instance = + FlutterKeyboardVisibilityPluginWindows(); + } + + /// Emits changes to keyboard visibility from the platform. Windows is not + /// implemented yet so false is returned. + @override + Stream get onChange async* { + yield false; + } +} diff --git a/flutter_keyboard_visibility_windows/pubspec.yaml b/flutter_keyboard_visibility_windows/pubspec.yaml new file mode 100644 index 0000000..cacf776 --- /dev/null +++ b/flutter_keyboard_visibility_windows/pubspec.yaml @@ -0,0 +1,26 @@ +name: flutter_keyboard_visibility_windows +description: An implementation for the Windows platform of `flutter_keyboard_visibility' +version: 1.0.0 +homepage: https://github.com/MisterJimson/flutter_keyboard_visibility +repository: https://github.com/MisterJimson/flutter_keyboard_visibility + +environment: + sdk: '>=2.12.0 <3.0.0' + flutter: '>=1.20.0' + +flutter: + plugin: + implements: flutter_keyboard_visibility + platforms: + windows: + dartPluginClass: FlutterKeyboardVisibilityPluginWindows + +dependencies: + flutter_keyboard_visibility_platform_interface: ^2.0.0 + flutter: + sdk: flutter + +dev_dependencies: + pedantic: ^1.11.0 + flutter_test: + sdk: flutter diff --git a/pub_get.sh b/pub_get.sh index bcb4706..e91a1b2 100755 --- a/pub_get.sh +++ b/pub_get.sh @@ -1,5 +1,8 @@ #!/usr/bin/env bash (cd flutter_keyboard_visibility_platform_interface && flutter pub get) (cd flutter_keyboard_visibility_web && flutter pub get) +(cd flutter_keyboard_visibility_linux && flutter pub get) +(cd flutter_keyboard_visibility_macos && flutter pub get) +(cd flutter_keyboard_visibility_windows && flutter pub get) (cd flutter_keyboard_visibility && flutter pub get) (cd flutter_keyboard_visibility/example && flutter pub get) diff --git a/test_lint.sh b/test_lint.sh index 27f33cb..9d0c7df 100755 --- a/test_lint.sh +++ b/test_lint.sh @@ -1,6 +1,9 @@ #!/usr/bin/env bash (cd flutter_keyboard_visibility_platform_interface && flutter analyze) (cd flutter_keyboard_visibility_web && flutter analyze) +(cd flutter_keyboard_visibility_linux && flutter analyze) +(cd flutter_keyboard_visibility_macos && flutter analyze) +(cd flutter_keyboard_visibility_windows && flutter analyze) (cd flutter_keyboard_visibility && flutter analyze) (cd flutter_keyboard_visibility/example && flutter analyze) (cd flutter_keyboard_visibility/example_old && flutter analyze) From 2392073d0f2874e73ece751e62fd16c4c4796674 Mon Sep 17 00:00:00 2001 From: Jason Rai Date: Thu, 8 Dec 2022 08:49:37 -0500 Subject: [PATCH 11/19] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 175a2e2..08db267 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,6 @@ # Flutter Keyboard Visibility [![pub package](https://img.shields.io/pub/v/flutter_keyboard_visibility.svg?label=flutter_keyboard_visibility&color=blue)](https://pub.dev/packages/flutter_keyboard_visibility) +![ci](https://github.com/MisterJimson/flutter_keyboard_visibility/actions/workflows/test.yml/badge.svg?branch=master) [![codecov](https://codecov.io/gh/MisterJimson/flutter_keyboard_visibility/branch/master/graph/badge.svg)](https://codecov.io/gh/MisterJimson/flutter_keyboard_visibility) React to keyboard visibility changes. From c6be6129cc3a12d0da58b12baf25b5622f045023 Mon Sep 17 00:00:00 2001 From: Jason Rai Date: Thu, 8 Dec 2022 08:51:05 -0500 Subject: [PATCH 12/19] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 08db267..d64dd4b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ React to keyboard visibility changes. ### Note about Flutter Web and Desktop support -Web support is an open issue [here](https://github.com/MisterJimson/flutter_keyboard_visibility/issues/10). Currently this library will just return `false` for keyboard visibility on web and desktop. +Web support is an open issue [here](https://github.com/MisterJimson/flutter_keyboard_visibility/issues/10), desktop support is an open issue [here](https://github.com/MisterJimson/flutter_keyboard_visibility/issues/124). Currently this library will just return `false` for keyboard visibility on web and desktop. ## Install [Install the package](https://pub.dev/packages/flutter_keyboard_visibility/install) From 2ea355f0bd445d788e1afde95ff94d516bc18745 Mon Sep 17 00:00:00 2001 From: PiN73 Date: Tue, 25 Apr 2023 01:47:56 +0300 Subject: [PATCH 13/19] ios: remove unnecessary CoreLocation import (#128) This fixes #127 `NSLocationWhenInUseUsageDescription` warning --- flutter_keyboard_visibility/CHANGELOG.md | 4 ++++ .../ios/Classes/FlutterKeyboardVisibilityPlugin.m | 2 -- flutter_keyboard_visibility/pubspec.yaml | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/flutter_keyboard_visibility/CHANGELOG.md b/flutter_keyboard_visibility/CHANGELOG.md index 11afbdf..df083fa 100644 --- a/flutter_keyboard_visibility/CHANGELOG.md +++ b/flutter_keyboard_visibility/CHANGELOG.md @@ -1,3 +1,7 @@ +## [5.4.1] - March 26, 2023 + +* Fixed `NSLocationWhenInUseUsageDescription` warning on iOS + ## [5.4.0] - October 4, 2022 Thanks to cbenhagen for this feature diff --git a/flutter_keyboard_visibility/ios/Classes/FlutterKeyboardVisibilityPlugin.m b/flutter_keyboard_visibility/ios/Classes/FlutterKeyboardVisibilityPlugin.m index 31dd908..dfa894f 100644 --- a/flutter_keyboard_visibility/ios/Classes/FlutterKeyboardVisibilityPlugin.m +++ b/flutter_keyboard_visibility/ios/Classes/FlutterKeyboardVisibilityPlugin.m @@ -8,8 +8,6 @@ #import "FlutterKeyboardVisibilityPlugin.h" -@import CoreLocation; - @interface FlutterKeyboardVisibilityPlugin() @property (copy, nonatomic) FlutterEventSink flutterEventSink; diff --git a/flutter_keyboard_visibility/pubspec.yaml b/flutter_keyboard_visibility/pubspec.yaml index 519aeb6..71cd915 100644 --- a/flutter_keyboard_visibility/pubspec.yaml +++ b/flutter_keyboard_visibility/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_keyboard_visibility description: Flutter plugin for discovering the state of the soft-keyboard visibility on Android and iOS. -version: 5.4.0 +version: 5.4.1 homepage: https://github.com/MisterJimson/flutter_keyboard_visibility repository: https://github.com/MisterJimson/flutter_keyboard_visibility From b136e23cff85dbb4385738cee82a8d53363cb4ed Mon Sep 17 00:00:00 2001 From: David Martos Date: Thu, 11 May 2023 20:32:41 +0200 Subject: [PATCH 14/19] Add support to Gradle 8+ (#131) * Add support to Gradle 8+ * Add JVM compatibility * commit automatically changed gradle file * remove implicit-casts * update changelong * update changlog --------- Co-authored-by: Jason Rai --- flutter_keyboard_visibility/CHANGELOG.md | 6 ++++++ flutter_keyboard_visibility/analysis_options.yaml | 4 ---- flutter_keyboard_visibility/android/build.gradle | 15 +++++++++++++-- .../example/analysis_options.yaml | 4 ---- .../example/android/app/build.gradle | 2 ++ .../android/app/src/debug/AndroidManifest.xml | 3 +-- .../android/app/src/main/AndroidManifest.xml | 3 +-- .../android/app/src/profile/AndroidManifest.xml | 3 +-- .../example/android/build.gradle | 6 +++--- .../example/android/gradle.properties | 3 +++ .../gradle/wrapper/gradle-wrapper.properties | 3 +-- flutter_keyboard_visibility/pubspec.yaml | 2 +- .../analysis_options.yaml | 4 ---- .../analysis_options.yaml | 4 ---- .../analysis_options.yaml | 4 ---- .../analysis_options.yaml | 4 ---- .../analysis_options.yaml | 4 ---- 17 files changed, 32 insertions(+), 42 deletions(-) diff --git a/flutter_keyboard_visibility/CHANGELOG.md b/flutter_keyboard_visibility/CHANGELOG.md index df083fa..e7b4269 100644 --- a/flutter_keyboard_visibility/CHANGELOG.md +++ b/flutter_keyboard_visibility/CHANGELOG.md @@ -1,3 +1,9 @@ +## [5.4.2] - UNRELEASED +Thanks to davidmartos96 for help with this release + +* Add compatibility with AGP 8 (Android Gradle Plugin). +* Removed implicit-casts lint warning as it's no longer supported + ## [5.4.1] - March 26, 2023 * Fixed `NSLocationWhenInUseUsageDescription` warning on iOS diff --git a/flutter_keyboard_visibility/analysis_options.yaml b/flutter_keyboard_visibility/analysis_options.yaml index b4ab8c9..108d105 100644 --- a/flutter_keyboard_visibility/analysis_options.yaml +++ b/flutter_keyboard_visibility/analysis_options.yaml @@ -1,5 +1 @@ include: package:pedantic/analysis_options.yaml - -analyzer: - strong-mode: - implicit-casts: false diff --git a/flutter_keyboard_visibility/android/build.gradle b/flutter_keyboard_visibility/android/build.gradle index 8b0c21a..012eea4 100644 --- a/flutter_keyboard_visibility/android/build.gradle +++ b/flutter_keyboard_visibility/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:7.0.0' + classpath 'com.android.tools.build:gradle:8.0.1' } } @@ -22,12 +22,23 @@ rootProject.allprojects { apply plugin: 'com.android.library' android { + // Conditional for compatibility with AGP <4.2. + if (project.android.hasProperty("namespace")) { + namespace 'com.jrai.flutter_keyboard_visibility' + } + compileSdkVersion 31 defaultConfig { minSdkVersion 16 } - lintOptions { + + lint { disable 'InvalidPackage' } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } diff --git a/flutter_keyboard_visibility/example/analysis_options.yaml b/flutter_keyboard_visibility/example/analysis_options.yaml index b4ab8c9..108d105 100644 --- a/flutter_keyboard_visibility/example/analysis_options.yaml +++ b/flutter_keyboard_visibility/example/analysis_options.yaml @@ -1,5 +1 @@ include: package:pedantic/analysis_options.yaml - -analyzer: - strong-mode: - implicit-casts: false diff --git a/flutter_keyboard_visibility/example/android/app/build.gradle b/flutter_keyboard_visibility/example/android/app/build.gradle index d525c8e..981474e 100644 --- a/flutter_keyboard_visibility/example/android/app/build.gradle +++ b/flutter_keyboard_visibility/example/android/app/build.gradle @@ -26,6 +26,8 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { + namespace 'com.jrai.flutter_keyboard_visibility_example.example' + compileSdkVersion 31 compileOptions { diff --git a/flutter_keyboard_visibility/example/android/app/src/debug/AndroidManifest.xml b/flutter_keyboard_visibility/example/android/app/src/debug/AndroidManifest.xml index 63c0a1f..f880684 100644 --- a/flutter_keyboard_visibility/example/android/app/src/debug/AndroidManifest.xml +++ b/flutter_keyboard_visibility/example/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,4 @@ - + diff --git a/flutter_keyboard_visibility/example/android/app/src/main/AndroidManifest.xml b/flutter_keyboard_visibility/example/android/app/src/main/AndroidManifest.xml index f14898c..03c8f2f 100644 --- a/flutter_keyboard_visibility/example/android/app/src/main/AndroidManifest.xml +++ b/flutter_keyboard_visibility/example/android/app/src/main/AndroidManifest.xml @@ -1,5 +1,4 @@ - + diff --git a/flutter_keyboard_visibility/example/android/app/src/profile/AndroidManifest.xml b/flutter_keyboard_visibility/example/android/app/src/profile/AndroidManifest.xml index 63c0a1f..f880684 100644 --- a/flutter_keyboard_visibility/example/android/app/src/profile/AndroidManifest.xml +++ b/flutter_keyboard_visibility/example/android/app/src/profile/AndroidManifest.xml @@ -1,5 +1,4 @@ - + diff --git a/flutter_keyboard_visibility/example/android/build.gradle b/flutter_keyboard_visibility/example/android/build.gradle index 91c3537..9086fd0 100644 --- a/flutter_keyboard_visibility/example/android/build.gradle +++ b/flutter_keyboard_visibility/example/android/build.gradle @@ -1,12 +1,12 @@ buildscript { - ext.kotlin_version = '1.5.21' + ext.kotlin_version = '1.8.21' repositories { google() mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:7.0.0' + classpath 'com.android.tools.build:gradle:8.0.1' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -24,6 +24,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/flutter_keyboard_visibility/example/android/gradle.properties b/flutter_keyboard_visibility/example/android/gradle.properties index 94adc3a..b9a9a24 100644 --- a/flutter_keyboard_visibility/example/android/gradle.properties +++ b/flutter_keyboard_visibility/example/android/gradle.properties @@ -1,3 +1,6 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true +android.defaults.buildfeatures.buildconfig=true +android.nonTransitiveRClass=false +android.nonFinalResIds=false diff --git a/flutter_keyboard_visibility/example/android/gradle/wrapper/gradle-wrapper.properties b/flutter_keyboard_visibility/example/android/gradle/wrapper/gradle-wrapper.properties index e6df0b7..da1db5f 100644 --- a/flutter_keyboard_visibility/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/flutter_keyboard_visibility/example/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 +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-all.zip diff --git a/flutter_keyboard_visibility/pubspec.yaml b/flutter_keyboard_visibility/pubspec.yaml index 71cd915..019c30b 100644 --- a/flutter_keyboard_visibility/pubspec.yaml +++ b/flutter_keyboard_visibility/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_keyboard_visibility description: Flutter plugin for discovering the state of the soft-keyboard visibility on Android and iOS. -version: 5.4.1 +version: 5.4.2 homepage: https://github.com/MisterJimson/flutter_keyboard_visibility repository: https://github.com/MisterJimson/flutter_keyboard_visibility diff --git a/flutter_keyboard_visibility_linux/analysis_options.yaml b/flutter_keyboard_visibility_linux/analysis_options.yaml index b4ab8c9..108d105 100644 --- a/flutter_keyboard_visibility_linux/analysis_options.yaml +++ b/flutter_keyboard_visibility_linux/analysis_options.yaml @@ -1,5 +1 @@ include: package:pedantic/analysis_options.yaml - -analyzer: - strong-mode: - implicit-casts: false diff --git a/flutter_keyboard_visibility_macos/analysis_options.yaml b/flutter_keyboard_visibility_macos/analysis_options.yaml index b4ab8c9..108d105 100644 --- a/flutter_keyboard_visibility_macos/analysis_options.yaml +++ b/flutter_keyboard_visibility_macos/analysis_options.yaml @@ -1,5 +1 @@ include: package:pedantic/analysis_options.yaml - -analyzer: - strong-mode: - implicit-casts: false diff --git a/flutter_keyboard_visibility_platform_interface/analysis_options.yaml b/flutter_keyboard_visibility_platform_interface/analysis_options.yaml index b4ab8c9..108d105 100644 --- a/flutter_keyboard_visibility_platform_interface/analysis_options.yaml +++ b/flutter_keyboard_visibility_platform_interface/analysis_options.yaml @@ -1,5 +1 @@ include: package:pedantic/analysis_options.yaml - -analyzer: - strong-mode: - implicit-casts: false diff --git a/flutter_keyboard_visibility_web/analysis_options.yaml b/flutter_keyboard_visibility_web/analysis_options.yaml index b4ab8c9..108d105 100644 --- a/flutter_keyboard_visibility_web/analysis_options.yaml +++ b/flutter_keyboard_visibility_web/analysis_options.yaml @@ -1,5 +1 @@ include: package:pedantic/analysis_options.yaml - -analyzer: - strong-mode: - implicit-casts: false diff --git a/flutter_keyboard_visibility_windows/analysis_options.yaml b/flutter_keyboard_visibility_windows/analysis_options.yaml index b4ab8c9..108d105 100644 --- a/flutter_keyboard_visibility_windows/analysis_options.yaml +++ b/flutter_keyboard_visibility_windows/analysis_options.yaml @@ -1,5 +1 @@ include: package:pedantic/analysis_options.yaml - -analyzer: - strong-mode: - implicit-casts: false From 628b0d164cb98be8103e295fedf249868b91d392 Mon Sep 17 00:00:00 2001 From: Jason Rai Date: Sat, 20 May 2023 09:44:22 -0400 Subject: [PATCH 15/19] fix: gradle 7 compatibility (#133) * update changelog * update sdk constraint * fix: revert gradle versions to 7 * fix: keep example on gradle 8 * fix: update versions --- flutter_keyboard_visibility/CHANGELOG.md | 7 ++++++- flutter_keyboard_visibility/android/build.gradle | 2 +- .../android/gradle/wrapper/gradle-wrapper.properties | 2 +- flutter_keyboard_visibility/example/pubspec.yaml | 2 +- flutter_keyboard_visibility/pubspec.yaml | 4 ++-- flutter_keyboard_visibility_linux/pubspec.yaml | 2 +- flutter_keyboard_visibility_macos/pubspec.yaml | 2 +- .../pubspec.yaml | 2 +- flutter_keyboard_visibility_web/pubspec.yaml | 2 +- flutter_keyboard_visibility_windows/pubspec.yaml | 2 +- 10 files changed, 16 insertions(+), 11 deletions(-) diff --git a/flutter_keyboard_visibility/CHANGELOG.md b/flutter_keyboard_visibility/CHANGELOG.md index e7b4269..a9d35b7 100644 --- a/flutter_keyboard_visibility/CHANGELOG.md +++ b/flutter_keyboard_visibility/CHANGELOG.md @@ -1,4 +1,9 @@ -## [5.4.2] - UNRELEASED +## [5.4.3] - May 12, 2023 +Thanks to fabricio-godoi for reporting this issue. + +* Fixed compatibility with Gradle 7 Android projects (support for Gradle 8 remains in place) + +## [5.4.2] - May 11, 2023 Thanks to davidmartos96 for help with this release * Add compatibility with AGP 8 (Android Gradle Plugin). diff --git a/flutter_keyboard_visibility/android/build.gradle b/flutter_keyboard_visibility/android/build.gradle index 012eea4..96df462 100644 --- a/flutter_keyboard_visibility/android/build.gradle +++ b/flutter_keyboard_visibility/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.0.1' + classpath 'com.android.tools.build:gradle:7.4.2' } } diff --git a/flutter_keyboard_visibility/android/gradle/wrapper/gradle-wrapper.properties b/flutter_keyboard_visibility/android/gradle/wrapper/gradle-wrapper.properties index 01a286e..ceccc3a 100644 --- a/flutter_keyboard_visibility/android/gradle/wrapper/gradle-wrapper.properties +++ b/flutter_keyboard_visibility/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip diff --git a/flutter_keyboard_visibility/example/pubspec.yaml b/flutter_keyboard_visibility/example/pubspec.yaml index 5f7a1ff..1e2386a 100644 --- a/flutter_keyboard_visibility/example/pubspec.yaml +++ b/flutter_keyboard_visibility/example/pubspec.yaml @@ -7,7 +7,7 @@ version: 1.0.0 publish_to: 'none' # Remove this line if you wish to publish to pub.dev environment: - sdk: ">=2.12.0 <3.0.0" + sdk: '>=2.12.0 <4.0.0' dependencies: flutter: diff --git a/flutter_keyboard_visibility/pubspec.yaml b/flutter_keyboard_visibility/pubspec.yaml index 019c30b..1a5d48b 100644 --- a/flutter_keyboard_visibility/pubspec.yaml +++ b/flutter_keyboard_visibility/pubspec.yaml @@ -1,11 +1,11 @@ name: flutter_keyboard_visibility description: Flutter plugin for discovering the state of the soft-keyboard visibility on Android and iOS. -version: 5.4.2 +version: 5.4.3 homepage: https://github.com/MisterJimson/flutter_keyboard_visibility repository: https://github.com/MisterJimson/flutter_keyboard_visibility environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.12.0 <4.0.0' flutter: ">=1.20.0" dependencies: diff --git a/flutter_keyboard_visibility_linux/pubspec.yaml b/flutter_keyboard_visibility_linux/pubspec.yaml index 744940a..9c51e8a 100644 --- a/flutter_keyboard_visibility_linux/pubspec.yaml +++ b/flutter_keyboard_visibility_linux/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/MisterJimson/flutter_keyboard_visibility repository: https://github.com/MisterJimson/flutter_keyboard_visibility environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.12.0 <4.0.0' flutter: '>=1.20.0' flutter: diff --git a/flutter_keyboard_visibility_macos/pubspec.yaml b/flutter_keyboard_visibility_macos/pubspec.yaml index 8d13094..e1217d3 100644 --- a/flutter_keyboard_visibility_macos/pubspec.yaml +++ b/flutter_keyboard_visibility_macos/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/MisterJimson/flutter_keyboard_visibility repository: https://github.com/MisterJimson/flutter_keyboard_visibility environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.12.0 <4.0.0' flutter: ">=1.20.0" flutter: diff --git a/flutter_keyboard_visibility_platform_interface/pubspec.yaml b/flutter_keyboard_visibility_platform_interface/pubspec.yaml index 9b072b2..4d8a3e5 100644 --- a/flutter_keyboard_visibility_platform_interface/pubspec.yaml +++ b/flutter_keyboard_visibility_platform_interface/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/MisterJimson/flutter_keyboard_visibility repository: https://github.com/MisterJimson/flutter_keyboard_visibility environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.12.0 <4.0.0' flutter: ">=1.12.13+hotfix.6" dependencies: diff --git a/flutter_keyboard_visibility_web/pubspec.yaml b/flutter_keyboard_visibility_web/pubspec.yaml index 311199a..88ea30a 100644 --- a/flutter_keyboard_visibility_web/pubspec.yaml +++ b/flutter_keyboard_visibility_web/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/MisterJimson/flutter_keyboard_visibility repository: https://github.com/MisterJimson/flutter_keyboard_visibility environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.12.0 <4.0.0' flutter: ">=1.20.0" flutter: diff --git a/flutter_keyboard_visibility_windows/pubspec.yaml b/flutter_keyboard_visibility_windows/pubspec.yaml index cacf776..d157ef0 100644 --- a/flutter_keyboard_visibility_windows/pubspec.yaml +++ b/flutter_keyboard_visibility_windows/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/MisterJimson/flutter_keyboard_visibility repository: https://github.com/MisterJimson/flutter_keyboard_visibility environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=2.12.0 <4.0.0' flutter: '>=1.20.0' flutter: From b5e7b0de4fa9eb6a6c076f1120e5f92a77b7679d Mon Sep 17 00:00:00 2001 From: Jason Rai Date: Sat, 20 May 2023 09:45:48 -0400 Subject: [PATCH 16/19] chore: update changelog --- flutter_keyboard_visibility/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flutter_keyboard_visibility/CHANGELOG.md b/flutter_keyboard_visibility/CHANGELOG.md index a9d35b7..bf7524e 100644 --- a/flutter_keyboard_visibility/CHANGELOG.md +++ b/flutter_keyboard_visibility/CHANGELOG.md @@ -1,4 +1,4 @@ -## [5.4.3] - May 12, 2023 +## [5.4.3] - May 20, 2023 Thanks to fabricio-godoi for reporting this issue. * Fixed compatibility with Gradle 7 Android projects (support for Gradle 8 remains in place) From 8c28373a5838a5376b7db471c9b298cd1d79ca04 Mon Sep 17 00:00:00 2001 From: Jason Rai Date: Mon, 21 Aug 2023 08:54:27 -0400 Subject: [PATCH 17/19] chore: flutter updates (#144) generated code changes, remove unneeded and removed command option --- .../example/linux/flutter/generated_plugin_registrant.cc | 4 ---- .../example/linux/flutter/generated_plugins.cmake | 1 - .../example/windows/flutter/generated_plugin_registrant.cc | 3 --- .../example/windows/flutter/generated_plugins.cmake | 1 - test_lint.sh | 3 +-- 5 files changed, 1 insertion(+), 11 deletions(-) diff --git a/flutter_keyboard_visibility/example/linux/flutter/generated_plugin_registrant.cc b/flutter_keyboard_visibility/example/linux/flutter/generated_plugin_registrant.cc index b669ea9..e71a16d 100644 --- a/flutter_keyboard_visibility/example/linux/flutter/generated_plugin_registrant.cc +++ b/flutter_keyboard_visibility/example/linux/flutter/generated_plugin_registrant.cc @@ -6,10 +6,6 @@ #include "generated_plugin_registrant.h" -#include void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) flutter_keyboard_visibility_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterKeyboardVisibilityPlugin"); - flutter_keyboard_visibility_plugin_register_with_registrar(flutter_keyboard_visibility_linux_registrar); } diff --git a/flutter_keyboard_visibility/example/linux/flutter/generated_plugins.cmake b/flutter_keyboard_visibility/example/linux/flutter/generated_plugins.cmake index acd0756..2e1de87 100644 --- a/flutter_keyboard_visibility/example/linux/flutter/generated_plugins.cmake +++ b/flutter_keyboard_visibility/example/linux/flutter/generated_plugins.cmake @@ -3,7 +3,6 @@ # list(APPEND FLUTTER_PLUGIN_LIST - flutter_keyboard_visibility_linux ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/flutter_keyboard_visibility/example/windows/flutter/generated_plugin_registrant.cc b/flutter_keyboard_visibility/example/windows/flutter/generated_plugin_registrant.cc index cf70736..8b6d468 100644 --- a/flutter_keyboard_visibility/example/windows/flutter/generated_plugin_registrant.cc +++ b/flutter_keyboard_visibility/example/windows/flutter/generated_plugin_registrant.cc @@ -6,9 +6,6 @@ #include "generated_plugin_registrant.h" -#include void RegisterPlugins(flutter::PluginRegistry* registry) { - FlutterKeyboardVisibilityPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FlutterKeyboardVisibilityPlugin")); } diff --git a/flutter_keyboard_visibility/example/windows/flutter/generated_plugins.cmake b/flutter_keyboard_visibility/example/windows/flutter/generated_plugins.cmake index a8c2fe0..b93c4c3 100644 --- a/flutter_keyboard_visibility/example/windows/flutter/generated_plugins.cmake +++ b/flutter_keyboard_visibility/example/windows/flutter/generated_plugins.cmake @@ -3,7 +3,6 @@ # list(APPEND FLUTTER_PLUGIN_LIST - flutter_keyboard_visibility_windows ) list(APPEND FLUTTER_FFI_PLUGIN_LIST diff --git a/test_lint.sh b/test_lint.sh index 9d0c7df..2bf0aa4 100755 --- a/test_lint.sh +++ b/test_lint.sh @@ -6,5 +6,4 @@ (cd flutter_keyboard_visibility_windows && flutter analyze) (cd flutter_keyboard_visibility && flutter analyze) (cd flutter_keyboard_visibility/example && flutter analyze) -(cd flutter_keyboard_visibility/example_old && flutter analyze) -(cd flutter_keyboard_visibility && flutter test --no-sound-null-safety --coverage) +(cd flutter_keyboard_visibility && flutter test --coverage) From 0c7cd61e57e43bca478ce95819f930daa8831cb2 Mon Sep 17 00:00:00 2001 From: Jason Rai Date: Tue, 19 Dec 2023 13:16:04 -0500 Subject: [PATCH 18/19] chore: v6 --- flutter_keyboard_visibility/CHANGELOG.md | 3 +++ flutter_keyboard_visibility/pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/flutter_keyboard_visibility/CHANGELOG.md b/flutter_keyboard_visibility/CHANGELOG.md index bf7524e..9ec9c36 100644 --- a/flutter_keyboard_visibility/CHANGELOG.md +++ b/flutter_keyboard_visibility/CHANGELOG.md @@ -1,3 +1,6 @@ +## [6.0.0-beta] - December 19, 2023 +* 5.4.3 republished as a new major version. The Android Gradle changes were breaking for some users so 5.4.3 was unpublished. Using this version may require you to update your Android Gradle version. + ## [5.4.3] - May 20, 2023 Thanks to fabricio-godoi for reporting this issue. diff --git a/flutter_keyboard_visibility/pubspec.yaml b/flutter_keyboard_visibility/pubspec.yaml index 1a5d48b..99b7b9a 100644 --- a/flutter_keyboard_visibility/pubspec.yaml +++ b/flutter_keyboard_visibility/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_keyboard_visibility description: Flutter plugin for discovering the state of the soft-keyboard visibility on Android and iOS. -version: 5.4.3 +version: 6.0.0-beta homepage: https://github.com/MisterJimson/flutter_keyboard_visibility repository: https://github.com/MisterJimson/flutter_keyboard_visibility From 71a3229801eb2f795a64f84f8f28fae29fc866db Mon Sep 17 00:00:00 2001 From: Jason Rai Date: Thu, 21 Dec 2023 09:32:40 -0500 Subject: [PATCH 19/19] v6 stable --- flutter_keyboard_visibility/CHANGELOG.md | 2 +- flutter_keyboard_visibility/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/flutter_keyboard_visibility/CHANGELOG.md b/flutter_keyboard_visibility/CHANGELOG.md index 9ec9c36..212a285 100644 --- a/flutter_keyboard_visibility/CHANGELOG.md +++ b/flutter_keyboard_visibility/CHANGELOG.md @@ -1,4 +1,4 @@ -## [6.0.0-beta] - December 19, 2023 +## [6.0.0] - December 19, 2023 * 5.4.3 republished as a new major version. The Android Gradle changes were breaking for some users so 5.4.3 was unpublished. Using this version may require you to update your Android Gradle version. ## [5.4.3] - May 20, 2023 diff --git a/flutter_keyboard_visibility/pubspec.yaml b/flutter_keyboard_visibility/pubspec.yaml index 99b7b9a..314c2b4 100644 --- a/flutter_keyboard_visibility/pubspec.yaml +++ b/flutter_keyboard_visibility/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_keyboard_visibility description: Flutter plugin for discovering the state of the soft-keyboard visibility on Android and iOS. -version: 6.0.0-beta +version: 6.0.0 homepage: https://github.com/MisterJimson/flutter_keyboard_visibility repository: https://github.com/MisterJimson/flutter_keyboard_visibility