diff --git a/.github/workflows/build_test.yaml b/.github/workflows/build_test.yaml new file mode 100644 index 0000000..4a8e7d2 --- /dev/null +++ b/.github/workflows/build_test.yaml @@ -0,0 +1,97 @@ +name: build-test + +on: + push: + branches: + - master + paths-ignore: + - ".vscode/**" + - "CHANGELOG.md" + - "LICENSE" + - "README.md" + - "resources/**" + - "**/CHANGELOG.md" + - "**/LICENSE" + - "**/README.md" + pull_request: + paths-ignore: + - ".vscode/**" + - "CHANGELOG.md" + - "LICENSE" + - "README.md" + - "resources/**" + - "**/CHANGELOG.md" + - "**/LICENSE" + - "**/README.md" + workflow_dispatch: + +concurrency: + group: > + ${{ github.workflow }} + ${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + build: + name: ${{ matrix.runner }} + runs-on: ${{ matrix.runner }}-latest + timeout-minutes: 30 + strategy: + fail-fast: false # Important + matrix: + runner: [ubuntu, windows, macos] + include: + - runner: ubuntu + target: linux + - runner: windows + target: windows + - runner: macos + target: macos + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 1 + submodules: true + + - name: Setup Flutter SDK + uses: subosito/flutter-action@v2 + with: + channel: "stable" + cache: true + + - name: Setup Ninja and GTK3 toolchain (Only Linux) + if: matrix.runner == 'ubuntu' + run: | + sudo apt-get update -y + sudo apt-get install -y ninja-build libgtk-3-dev + + - name: Fetch dependencies + working-directory: bitsdojo_window/example + run: flutter pub get + + - name: Run flutter build ${{ matrix.target }} + working-directory: bitsdojo_window/example + run: flutter build ${{ matrix.target }} --release -v + + - name: Archive artifacts (Linux) + if: matrix.runner == 'ubuntu' + uses: actions/upload-artifact@v3 + with: + name: bitsdojo_window_example_${{ matrix.runner }} + path: bitsdojo_window/example/build/linux/x64/release/bundle/ + + - name: Archive artifacts (Windows) + if: matrix.runner == 'windows' + uses: actions/upload-artifact@v3 + with: + name: bitsdojo_window_example_${{ matrix.runner }} + path: bitsdojo_window/example/build/windows/runner/Release/bitsdojo_window_example.exe + + - name: Archive artifacts (macOS) + if: matrix.runner == 'macos' + uses: actions/upload-artifact@v3 + with: + name: bitsdojo_window_example_${{ matrix.runner }} + path: bitsdojo_window/example/build/macos/Build/Products/Release/bitsdojo_window_example.app diff --git a/README.md b/README.md index 236597c..9468807 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,16 @@ +[![Pub Version](https://img.shields.io/pub/v/bitsdojo_window)](https://pub.dev/packages/bitsdojo_window) +[![Pub Popularity](https://img.shields.io/pub/popularity/bitsdojo_window)](https://pub.dev/packages/bitsdojo_window) +[![Pub Points](https://img.shields.io/pub/points/bitsdojo_window)](https://pub.dev/packages/bitsdojo_window) + +[![GitHub Stars](https://img.shields.io/github/stars/bitsdojo/bitsdojo_window)](https://github.com/bitsdojo/bitsdojo_window/stargazers) +[![Build Test](https://github.com/bitsdojo/bitsdojo_window/actions/workflows/build_test.yaml/badge.svg)](https://github.com/bitsdojo/bitsdojo_window/actions/workflows/build_test.yaml) +[![GitHub License](https://img.shields.io/github/license/bitsdojo/bitsdojo_window)](https://github.com/bitsdojo/bitsdojo_window/blob/main/LICENSE) + # bitsdojo_window -A [Flutter package](https://pub.dev/packages/bitsdojo_window) that makes it easy to customize and work with your Flutter desktop app window **on Windows, macOS and Linux**. +A [Flutter package](https://pub.dev/packages/bitsdojo_window) that makes it easy to customize and work with your Flutter desktop app window on **Windows**, **macOS** and **Linux**. -Watch the tutorial to get started. Click the image below to watch the video: +Watch the tutorial to get started. Click the image below to watch the video: [![IMAGE ALT TEXT](https://img.youtube.com/vi/bee2AHQpGK4/0.jpg)](https://www.youtube.com/watch?v=bee2AHQpGK4 "Click to open") @@ -10,70 +18,85 @@ Watch the tutorial to get started. Click the image below to watch the video: **Features**: - - Custom window frame - remove standard Windows/macOS/Linux titlebar and buttons - - Hide window on startup - - Show/hide window - - Move window using Flutter widget - - Minimize/Maximize/Restore/Close window - - Set window size, minimum size and maximum size - - Set window position - - Set window alignment on screen (center/topLeft/topRight/bottomLeft/bottomRight) - - Set window title +- Custom window frame - remove standard Windows/macOS/Linux titlebar and buttons +- Hide window on startup +- Show/hide window +- Move window using Flutter widget +- Minimize/Maximize/Restore/Close window +- Set window size, minimum size and maximum size +- Set window position +- Set window alignment on screen (center/topLeft/topRight/bottomLeft/bottomRight) +- Set window title # Getting Started -Install the package using `pubspec.yaml` +Add the package to your project's `pubspec.yaml` file manually or using the command below: -# For Windows apps +```shell +pub add bitsdojo_window +``` -Inside your application folder, go to `windows\runner\main.cpp` and add these two lines at the beginning of the file: +The `pubspec.yaml` file should look like this: -```cpp -#include -auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP); -``` +```diff +// pubspec.yaml -# For macOS apps + ... -Inside your application folder, go to `macos\runner\MainFlutterWindow.swift` and add this line after the one saying `import FlutterMacOS` : + dependencies: + flutter: + sdk: flutter ++ bitsdojo_window: ^0.1.6 -```swift -import FlutterMacOS -import bitsdojo_window_macos // Add this line + dev_dependencies: + + ... ``` -Then change this line from: +# For Windows apps -```swift -class MainFlutterWindow: NSWindow { -``` +Inside your application folder, go to `windows\runner\main.cpp` and change the code look like this: -to this: +```diff +// windows/runner/main.cpp -```swift -class MainFlutterWindow: BitsdojoWindow { -``` + ... -After changing `NSWindow` to `BitsdojoWindow` add these lines below the line you changed: + #include "flutter_window.h" + #include "utils.h" -```swift -override func bitsdojo_window_configure() -> UInt { - return BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP -} ++ #include ++ auto bdw = bitsdojo_window_configure(BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP); + + int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + + ... ``` -Your code should now look like this: +# For macOS apps + +Inside your application folder, go to `macos\runner\MainFlutterWindow.swift` and change the code look like this: + +```diff +// macos/runner/MainFlutterWindow.swift -```swift -class MainFlutterWindow: BitsdojoWindow { - - override func bitsdojo_window_configure() -> UInt { - return BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP + import Cocoa + import FlutterMacOS ++ import bitsdojo_window_macos + +- class MainFlutterWindow: NSWindow { ++ class MainFlutterWindow: BitsdojoWindow { ++ override func bitsdojo_window_configure() -> UInt { ++ return BDW_CUSTOM_FRAME | BDW_HIDE_ON_STARTUP ++ } + override func awakeFromNib() { + + ... + + } } - - override func awakeFromNib() { - ... //rest of your code ``` + # If you don't want to use a custom frame and prefer the standard window titlebar and buttons, you can remove the `BDW_CUSTOM_FRAME` flag from the code above. @@ -82,57 +105,63 @@ If you don't want to hide the window on startup, you can remove the `BDW_HIDE_ON # For Linux apps -Inside your application folder, go to `linux\my_application.cc` and add this line at the beginning of the file: +Inside your application folder, go to `linux\my_application.cc` and change the code look like this: -```cpp -#include -``` -Then look for these two lines: +```diff +// linux/my_application.cc -```cpp -gtk_window_set_default_size(window, 1280, 720); -gtk_widget_show(GTK_WIDGET(window)); -``` -and change them to this: + ... + #include "flutter/generated_plugin_registrant.h" ++ #include -```cpp -auto bdw = bitsdojo_window_from(window); // <--- add this line -bdw->setCustomFrame(true); // <-- add this line -//gtk_window_set_default_size(window, 1280, 720); // <-- comment this line -gtk_widget_show(GTK_WIDGET(window)); -``` + struct _MyApplication { + + ... + + } -As you can see, we commented the line calling `gtk_window_set_default_size` and added these two lines before `gtk_widget_show(GTK_WIDGET(window));` ++ auto bdw = bitsdojo_window_from(window); ++ bdw->setCustomFrame(true); +- gtk_window_set_default_size(window, 1280, 720); + gtk_widget_show(GTK_WIDGET(window)); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + + ... + + } -```cpp -auto bdw = bitsdojo_window_from(window); -bdw->setCustomFrame(true); ``` # Flutter app integration -Now go to `lib\main.dart` and add this code in the `main` function right after `runApp(MyApp());` : +Now go to `lib\main.dart` and change the code look like this: -```dart -void main() { - runApp(MyApp()); +```diff +// lib/main.dart - // Add this code below + import 'package:flutter/material.dart'; ++ import 'package:bitsdojo_window/bitsdojo_window.dart'; - doWhenWindowReady(() { - const initialSize = Size(600, 450); - appWindow.minSize = initialSize; - appWindow.size = initialSize; - appWindow.alignment = Alignment.center; - appWindow.show(); - }); -} + void main() { + runApp(MyApp()); + ++ doWhenWindowReady(() { ++ const initialSize = Size(600, 450); ++ appWindow.minSize = initialSize; ++ appWindow.size = initialSize; ++ appWindow.alignment = Alignment.center; ++ appWindow.show(); ++ }); + } ``` + This will set an initial size and a minimum size for your application window, center it on the screen and show it on the screen. -You can find examples in the `example` folder. +You can find examples in the [example](./bitsdojo_window/example) folder. Here is an example that displays this window: +
Click to expand @@ -249,9 +278,11 @@ class WindowButtons extends StatelessWidget { } } ``` +
# + # **Want to help? Become a sponsor** I am developing this package in my spare time and any help is appreciated. @@ -262,4 +293,4 @@ If you want to help you can [become a sponsor](https://github.com/sponsors/bitsd ## ☕️ Current sponsors: - No sponsors +No sponsors diff --git a/bitsdojo_window/CHANGELOG.md b/bitsdojo_window/CHANGELOG.md index c022588..4af9672 100644 --- a/bitsdojo_window/CHANGELOG.md +++ b/bitsdojo_window/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.1.6 + - Various fixes to work with latest Flutter version ## 0.1.5 - Runs on Windows 7 ## 0.1.4 diff --git a/bitsdojo_window/example/lib/main.dart b/bitsdojo_window/example/lib/main.dart index 68d9c6d..7bd94d0 100644 --- a/bitsdojo_window/example/lib/main.dart +++ b/bitsdojo_window/example/lib/main.dart @@ -5,7 +5,9 @@ import 'package:flutter/material.dart'; import 'package:bitsdojo_window/bitsdojo_window.dart'; void main() { + appWindow.size = const Size(600, 450); runApp(const MyApp()); + appWindow.show(); doWhenWindowReady(() { final win = appWindow; const initialSize = Size(600, 450); @@ -20,7 +22,7 @@ void main() { const borderColor = Color(0xFF805306); class MyApp extends StatelessWidget { - const MyApp({Key? key}) : super(key: key); + const MyApp({super.key}); @override Widget build(BuildContext context) { @@ -30,8 +32,8 @@ class MyApp extends StatelessWidget { body: WindowBorder( color: borderColor, width: 1, - child: Row( - children: const [LeftSide(), RightSide()], + child: const Row( + children: [LeftSide(), RightSide()], ), ), ), @@ -42,7 +44,7 @@ class MyApp extends StatelessWidget { const sidebarColor = Color(0xFFF6A00C); class LeftSide extends StatelessWidget { - const LeftSide({Key? key}) : super(key: key); + const LeftSide({super.key}); @override Widget build(BuildContext context) { return SizedBox( @@ -62,7 +64,7 @@ const backgroundStartColor = Color(0xFFFFD500); const backgroundEndColor = Color(0xFFF6A00C); class RightSide extends StatelessWidget { - const RightSide({Key? key}) : super(key: key); + const RightSide({super.key}); @override Widget build(BuildContext context) { return Expanded( @@ -100,10 +102,10 @@ final closeButtonColors = WindowButtonColors( iconMouseOver: Colors.white); class WindowButtons extends StatefulWidget { - const WindowButtons({Key? key}) : super(key: key); + const WindowButtons({super.key}); @override - _WindowButtonsState createState() => _WindowButtonsState(); + State createState() => _WindowButtonsState(); } class _WindowButtonsState extends State { diff --git a/bitsdojo_window/example/lib/switch.dart b/bitsdojo_window/example/lib/switch.dart index 2e65657..fbe6801 100644 --- a/bitsdojo_window/example/lib/switch.dart +++ b/bitsdojo_window/example/lib/switch.dart @@ -94,10 +94,10 @@ class AppColors extends InheritedWidget { final AppSkin colors; //final Widget child; const AppColors({ - Key? key, + super.key, required this.colors, - required Widget child, - }) : super(key: key, child: child); + required super.child, + }); static AppColors? of(BuildContext context) { return context.dependOnInheritedWidgetOfExactType(); @@ -121,7 +121,7 @@ void main() { } class MyApp extends StatelessWidget { - const MyApp({Key? key}) : super(key: key); + const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( @@ -130,10 +130,10 @@ class MyApp extends StatelessWidget { } class AppBody extends StatefulWidget { - const AppBody({Key? key}) : super(key: key); + const AppBody({super.key}); @override - _AppBodyState createState() => _AppBodyState(); + State createState() => _AppBodyState(); } class _AppBodyState extends State { @@ -165,7 +165,7 @@ class _AppBodyState extends State { } class LeftSide extends StatelessWidget { - const LeftSide({Key? key}) : super(key: key); + const LeftSide({super.key}); @override Widget build(BuildContext context) { @@ -182,7 +182,7 @@ class LeftSide extends StatelessWidget { class RightSide extends StatelessWidget { final VoidCallback? onButtonPressed; - const RightSide({Key? key, this.onButtonPressed}) : super(key: key); + const RightSide({super.key, this.onButtonPressed}); @override Widget build(BuildContext context) { final colors = AppColors.of(context)!.colors; @@ -210,7 +210,7 @@ class RightSide extends StatelessWidget { } class RightSideTopArea extends StatelessWidget { - const RightSideTopArea({Key? key}) : super(key: key); + const RightSideTopArea({super.key}); @override Widget build(BuildContext context) { @@ -221,7 +221,7 @@ class RightSideTopArea extends StatelessWidget { } class WindowButtons extends StatelessWidget { - const WindowButtons({Key? key}) : super(key: key); + const WindowButtons({super.key}); @override Widget build(BuildContext context) { @@ -256,29 +256,27 @@ class RoundedFlatButton extends StatelessWidget { final String? text; const RoundedFlatButton( - {Key? key, + {super.key, this.onPressed, this.color, this.mouseOverColor, this.textColor, - this.text}) - : super(key: key); + this.text}); @override Widget build(BuildContext context) { return ElevatedButton( - child: Text(text ?? 'Button'), style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12.0), - side: const BorderSide(color: Colors.white)), - primary: color ?? Colors.grey[900], + side: const BorderSide(color: Colors.white)), backgroundColor: color ?? Colors.grey[900], padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 20), textStyle: TextStyle( color: textColor ?? Colors.white, fontSize: 12.0, fontWeight: FontWeight.w600)), onPressed: onPressed, + child: Text(text ?? 'Button'), ); } } diff --git a/bitsdojo_window/example/linux/CMakeLists.txt b/bitsdojo_window/example/linux/CMakeLists.txt index a558bc4..0948fef 100644 --- a/bitsdojo_window/example/linux/CMakeLists.txt +++ b/bitsdojo_window/example/linux/CMakeLists.txt @@ -1,8 +1,8 @@ cmake_minimum_required(VERSION 3.10) project(runner LANGUAGES CXX) -set(BINARY_NAME "example") -set(APPLICATION_ID "com.example.example") +set(BINARY_NAME "bitsdojo_window_example") +set(APPLICATION_ID "com.example.bitsdojo_window_example") cmake_policy(SET CMP0063 NEW) diff --git a/bitsdojo_window/example/linux/my_application.cc b/bitsdojo_window/example/linux/my_application.cc index 4e43d4e..b9b8da8 100644 --- a/bitsdojo_window/example/linux/my_application.cc +++ b/bitsdojo_window/example/linux/my_application.cc @@ -41,11 +41,11 @@ static void my_application_activate(GApplication* application) { if (use_header_bar) { GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); gtk_widget_show(GTK_WIDGET(header_bar)); - gtk_header_bar_set_title(header_bar, "example"); + gtk_header_bar_set_title(header_bar, "bitsdojo_window_example"); gtk_header_bar_set_show_close_button(header_bar, TRUE); gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); } else { - gtk_window_set_title(window, "example"); + gtk_window_set_title(window, "bitsdojo_window_example"); } auto bdw = bitsdojo_window_from(window); diff --git a/bitsdojo_window/example/macos/Podfile b/bitsdojo_window/example/macos/Podfile index dade8df..049abe2 100644 --- a/bitsdojo_window/example/macos/Podfile +++ b/bitsdojo_window/example/macos/Podfile @@ -1,4 +1,4 @@ -platform :osx, '10.11' +platform :osx, '10.14' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. ENV['COCOAPODS_DISABLE_STATS'] = 'true' diff --git a/bitsdojo_window/example/macos/Podfile.lock b/bitsdojo_window/example/macos/Podfile.lock index f64db9c..76e5c55 100644 --- a/bitsdojo_window/example/macos/Podfile.lock +++ b/bitsdojo_window/example/macos/Podfile.lock @@ -15,8 +15,8 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: bitsdojo_window_macos: 44e3b8fe3dd463820e0321f6256c5b1c16bb6a00 - FlutterMacOS: 57701585bf7de1b3fc2bb61f6378d73bbdea8424 + FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 -PODFILE CHECKSUM: 6eac6b3292e5142cfc23bdeb71848a40ec51c14c +PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7 -COCOAPODS: 1.11.3 +COCOAPODS: 1.14.3 diff --git a/bitsdojo_window/example/macos/Runner.xcodeproj/project.pbxproj b/bitsdojo_window/example/macos/Runner.xcodeproj/project.pbxproj index c6f13b6..fc376d5 100644 --- a/bitsdojo_window/example/macos/Runner.xcodeproj/project.pbxproj +++ b/bitsdojo_window/example/macos/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ @@ -55,7 +55,7 @@ /* Begin PBXFileReference section */ 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; - 33CC10ED2044A3C60003C045 /* example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 33CC10ED2044A3C60003C045 /* bitsdojo_window_example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = bitsdojo_window_example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = ""; }; 33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = ""; }; @@ -112,7 +112,7 @@ 33CC10EE2044A3C60003C045 /* Products */ = { isa = PBXGroup; children = ( - 33CC10ED2044A3C60003C045 /* example.app */, + 33CC10ED2044A3C60003C045 /* bitsdojo_window_example.app */, ); name = Products; sourceTree = ""; @@ -193,7 +193,7 @@ ); name = Runner; productName = Runner; - productReference = 33CC10ED2044A3C60003C045 /* example.app */; + productReference = 33CC10ED2044A3C60003C045 /* bitsdojo_window_example.app */; productType = "com.apple.product-type.application"; }; /* End PBXNativeTarget section */ @@ -203,7 +203,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 0930; + LastUpgradeCheck = 1430; ORGANIZATIONNAME = ""; TargetAttributes = { 33CC10EC2044A3C60003C045 = { @@ -256,6 +256,7 @@ /* Begin PBXShellScriptBuildPhase section */ 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -404,7 +405,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -483,7 +484,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -530,7 +531,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; diff --git a/bitsdojo_window/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/bitsdojo_window/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index ae8ff59..fb993bd 100644 --- a/bitsdojo_window/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/bitsdojo_window/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ @@ -31,13 +31,13 @@ - - + + - - diff --git a/bitsdojo_window/example/macos/Runner/Base.lproj/MainMenu.xib b/bitsdojo_window/example/macos/Runner/Base.lproj/MainMenu.xib index 537341a..2cb4240 100644 --- a/bitsdojo_window/example/macos/Runner/Base.lproj/MainMenu.xib +++ b/bitsdojo_window/example/macos/Runner/Base.lproj/MainMenu.xib @@ -1,8 +1,8 @@ - + - + @@ -13,7 +13,7 @@ - + @@ -326,14 +326,15 @@ - + - + + diff --git a/bitsdojo_window/example/macos/Runner/Configs/AppInfo.xcconfig b/bitsdojo_window/example/macos/Runner/Configs/AppInfo.xcconfig index cf9be60..31ba669 100644 --- a/bitsdojo_window/example/macos/Runner/Configs/AppInfo.xcconfig +++ b/bitsdojo_window/example/macos/Runner/Configs/AppInfo.xcconfig @@ -5,10 +5,10 @@ // 'flutter create' template. // The application's name. By default this is also the title of the Flutter window. -PRODUCT_NAME = example +PRODUCT_NAME = bitsdojo_window_example // The application's bundle identifier -PRODUCT_BUNDLE_IDENTIFIER = com.example.example +PRODUCT_BUNDLE_IDENTIFIER = com.example.bitsdojo-window-example // The copyright displayed in application information PRODUCT_COPYRIGHT = Copyright © 2021 com.example. All rights reserved. diff --git a/bitsdojo_window/example/pubspec.yaml b/bitsdojo_window/example/pubspec.yaml index fcc3df2..38d563d 100644 --- a/bitsdojo_window/example/pubspec.yaml +++ b/bitsdojo_window/example/pubspec.yaml @@ -3,10 +3,15 @@ description: Demonstrates how to use the bitsdojo_window plugin. # The following line prevents the package from being accidentally published to # pub.dev using `pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev +publish_to: "none" # Remove this line if you wish to publish to pub.dev + +platforms: + linux: + macos: + windows: environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=2.17.0 <4.0.0" dependencies: flutter: @@ -34,14 +39,13 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^1.0.0 + flutter_lints: ^3.0.1 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec # The following section is specific to Flutter. flutter: - # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. diff --git a/bitsdojo_window/example/web/favicon.png b/bitsdojo_window/example/web/favicon.png deleted file mode 100644 index 8aaa46a..0000000 Binary files a/bitsdojo_window/example/web/favicon.png and /dev/null differ diff --git a/bitsdojo_window/example/web/icons/Icon-192.png b/bitsdojo_window/example/web/icons/Icon-192.png deleted file mode 100644 index b749bfe..0000000 Binary files a/bitsdojo_window/example/web/icons/Icon-192.png and /dev/null differ diff --git a/bitsdojo_window/example/web/icons/Icon-512.png b/bitsdojo_window/example/web/icons/Icon-512.png deleted file mode 100644 index 88cfd48..0000000 Binary files a/bitsdojo_window/example/web/icons/Icon-512.png and /dev/null differ diff --git a/bitsdojo_window/example/web/index.html b/bitsdojo_window/example/web/index.html deleted file mode 100644 index 1460b5e..0000000 --- a/bitsdojo_window/example/web/index.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - example - - - - - - - - diff --git a/bitsdojo_window/example/web/manifest.json b/bitsdojo_window/example/web/manifest.json deleted file mode 100644 index 8c01291..0000000 --- a/bitsdojo_window/example/web/manifest.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "example", - "short_name": "example", - "start_url": ".", - "display": "standalone", - "background_color": "#0175C2", - "theme_color": "#0175C2", - "description": "A new Flutter project.", - "orientation": "portrait-primary", - "prefer_related_applications": false, - "icons": [ - { - "src": "icons/Icon-192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "icons/Icon-512.png", - "sizes": "512x512", - "type": "image/png" - } - ] -} diff --git a/bitsdojo_window/example/windows/CMakeLists.txt b/bitsdojo_window/example/windows/CMakeLists.txt index abf9040..9f3b61e 100644 --- a/bitsdojo_window/example/windows/CMakeLists.txt +++ b/bitsdojo_window/example/windows/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.15) -project(example LANGUAGES CXX) +project(bitsdojo_window_example LANGUAGES CXX) -set(BINARY_NAME "example") +set(BINARY_NAME "bitsdojo_window_example") cmake_policy(SET CMP0063 NEW) diff --git a/bitsdojo_window/example/windows/runner/Runner.rc b/bitsdojo_window/example/windows/runner/Runner.rc index 51812dc..000b24c 100644 --- a/bitsdojo_window/example/windows/runner/Runner.rc +++ b/bitsdojo_window/example/windows/runner/Runner.rc @@ -92,10 +92,10 @@ BEGIN VALUE "CompanyName", "com.example" "\0" VALUE "FileDescription", "A new Flutter project." "\0" VALUE "FileVersion", VERSION_AS_STRING "\0" - VALUE "InternalName", "example" "\0" + VALUE "InternalName", "bitsdojo_window_example" "\0" VALUE "LegalCopyright", "Copyright (C) 2021 com.example. All rights reserved." "\0" - VALUE "OriginalFilename", "example.exe" "\0" - VALUE "ProductName", "example" "\0" + VALUE "OriginalFilename", "bitsdojo_window_example.exe" "\0" + VALUE "ProductName", "bitsdojo_window_example" "\0" VALUE "ProductVersion", VERSION_AS_STRING "\0" END END diff --git a/bitsdojo_window/example/windows/runner/main.cpp b/bitsdojo_window/example/windows/runner/main.cpp index 3922217..89f4fb3 100644 --- a/bitsdojo_window/example/windows/runner/main.cpp +++ b/bitsdojo_window/example/windows/runner/main.cpp @@ -33,7 +33,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, FlutterWindow window(&run_loop, project); Win32Window::Point origin(10, 10); Win32Window::Size size(1280, 720); - if (!window.CreateAndShow(L"example", origin, size)) { + if (!window.CreateAndShow(L"bitsdojo_window_example", origin, size)) { return EXIT_FAILURE; } window.SetQuitOnClose(true); diff --git a/bitsdojo_window/pubspec.yaml b/bitsdojo_window/pubspec.yaml index 47ef658..656675f 100644 --- a/bitsdojo_window/pubspec.yaml +++ b/bitsdojo_window/pubspec.yaml @@ -1,11 +1,11 @@ name: bitsdojo_window description: A package to help with creating custom windows with Flutter desktop (custom border, titlebar and minimize/maximize/close buttons) and common desktop window operations (show/hide/position on screen) for Windows and macOS -version: 0.1.5 +version: 0.1.6 homepage: https://www.bitsdojo.com repository: https://github.com/bitsdojo/bitsdojo_window environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=2.17.0 <4.0.0" flutter: ">=1.20.0" flutter: @@ -21,11 +21,15 @@ flutter: dependencies: flutter: sdk: flutter - bitsdojo_window_platform_interface: ^0.1.2 + bitsdojo_window_platform_interface: + ^0.1.2 #path: ../bitsdojo_window_platform_interface - bitsdojo_window_windows: ^0.1.5 + bitsdojo_window_windows: + ^0.1.6 #path: ../bitsdojo_window_windows - bitsdojo_window_macos: ^0.1.3 + bitsdojo_window_macos: + ^0.1.4 #path: ../bitsdojo_window_macos - bitsdojo_window_linux: ^0.1.3 + bitsdojo_window_linux: + ^0.1.4 #path: ../bitsdojo_window_linux diff --git a/bitsdojo_window_linux/CHANGELOG.md b/bitsdojo_window_linux/CHANGELOG.md index 266798f..b5f361f 100644 --- a/bitsdojo_window_linux/CHANGELOG.md +++ b/bitsdojo_window_linux/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.1.4 + - Various fixes to work with latest Flutter version ## 0.1.3 - Updated ffi to 2.0.0 ## 0.1.2 diff --git a/bitsdojo_window_linux/pubspec.yaml b/bitsdojo_window_linux/pubspec.yaml index 3946131..d9bcf55 100644 --- a/bitsdojo_window_linux/pubspec.yaml +++ b/bitsdojo_window_linux/pubspec.yaml @@ -1,21 +1,21 @@ name: bitsdojo_window_linux description: Linux implementation of the bitsdojo_window plugin. -version: 0.1.3 +version: 0.1.4 homepage: https://www.bitsdojo.com repository: https://github.com/bitsdojo/bitsdojo_window environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=2.17.0 <4.0.0" flutter: ">=1.20.0" dependencies: flutter: sdk: flutter - bitsdojo_window_platform_interface: ^0.1.2 + bitsdojo_window_platform_interface: + ^0.1.2 #path: ../bitsdojo_window_platform_interface ffi: ^2.0.0 - dev_dependencies: flutter_test: sdk: flutter diff --git a/bitsdojo_window_linux/test/bitsdojo_window_test.dart b/bitsdojo_window_linux/test/bitsdojo_window_test.dart deleted file mode 100644 index 60d1a37..0000000 --- a/bitsdojo_window_linux/test/bitsdojo_window_test.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - const MethodChannel channel = MethodChannel('bitsdojo/window'); - - TestWidgetsFlutterBinding.ensureInitialized(); - - setUp(() { - channel.setMockMethodCallHandler((MethodCall methodCall) async { - return '42'; - }); - }); - - tearDown(() { - channel.setMockMethodCallHandler(null); - }); -} diff --git a/bitsdojo_window_macos/CHANGELOG.md b/bitsdojo_window_macos/CHANGELOG.md index 8651047..c88b4d5 100644 --- a/bitsdojo_window_macos/CHANGELOG.md +++ b/bitsdojo_window_macos/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.1.4 + - Various fixes to work with latest Flutter version ## 0.1.3 - Updated ffi to 2.0.0 ## 0.1.2 diff --git a/bitsdojo_window_macos/macos/Classes/BitsdojoWindow.swift b/bitsdojo_window_macos/macos/Classes/BitsdojoWindow.swift index 7c78965..777e2e3 100644 --- a/bitsdojo_window_macos/macos/Classes/BitsdojoWindow.swift +++ b/bitsdojo_window_macos/macos/Classes/BitsdojoWindow.swift @@ -25,6 +25,10 @@ open class BitsdojoWindow: NSWindow { } override public func order(_ place: NSWindow.OrderingMode, relativeTo otherWin: Int) { + if (!bdwPrivateAPI.appWindowIsSet()) + { + bdwPrivateAPI.setAppWindow(self); + } let flags = self.bitsdojo_window_configure() let hideOnStartup:Bool = ((flags & BDW_HIDE_ON_STARTUP) != 0); @@ -41,9 +45,8 @@ open class BitsdojoWindow: NSWindow { } super.order(place, relativeTo: otherWin) let windowCanBeShown: Bool = bdwPrivateAPI.windowCanBeShown(); - bdwPrivateAPI.setAppWindow(self) - if (!(windowCanBeShown) && hideOnStartup) { - self.setIsVisible(false) + if (!(windowCanBeShown) && hideOnStartup && self.isVisible) { + self.setIsVisible(false) } } } diff --git a/bitsdojo_window_macos/macos/Classes/bitsdojo_window.h b/bitsdojo_window_macos/macos/Classes/bitsdojo_window.h index 9406c23..82b3271 100644 --- a/bitsdojo_window_macos/macos/Classes/bitsdojo_window.h +++ b/bitsdojo_window_macos/macos/Classes/bitsdojo_window.h @@ -8,6 +8,9 @@ typedef bool (*TWindowCanBeShown)(); bool windowCanBeShown(); +typedef bool (*TAppWindowIsSet)(); +bool appWindowIsSet(); + typedef void (*TSetAppWindow)(NSWindow*); void setAppWindow(NSWindow* window); diff --git a/bitsdojo_window_macos/macos/Classes/bitsdojo_window.mm b/bitsdojo_window_macos/macos/Classes/bitsdojo_window.mm index a955842..6eae8d5 100644 --- a/bitsdojo_window_macos/macos/Classes/bitsdojo_window.mm +++ b/bitsdojo_window_macos/macos/Classes/bitsdojo_window.mm @@ -1,94 +1,105 @@ #import "bitsdojo_window.h" +#import "bitsdojo_window_controller.h" NSWindow* _appWindow = NULL; bool _windowCanBeShown = false; bool _insideDoWhenWindowReady = false; +BitsdojoWindowController *controller = NULL; -void setInsideDoWhenWindowReady(bool value){ +void setInsideDoWhenWindowReady(bool value) { _insideDoWhenWindowReady = value; } -void setAppWindow(NSWindow* value){ +bool appWindowIsSet() { + return _appWindow != NULL; +} + +void setAppWindow(NSWindow* value) { _appWindow = value; + controller = [[BitsdojoWindowController alloc] initWithWindow:value]; } -NSWindow* getAppWindow(){ - if (NULL == _appWindow) { +NSWindow* getAppWindow() { + if (_appWindow == NULL) { _appWindow = [NSApp windows][0]; } return _appWindow; } -bool windowCanBeShown(){ +bool windowCanBeShown() { return _windowCanBeShown; } -void setWindowCanBeShown(bool value){ +void setWindowCanBeShown(bool value) { _windowCanBeShown = value; } +void runOnMainThread(dispatch_block_t block) { + if ([NSThread isMainThread]) { + block(); + } else { + dispatch_async(dispatch_get_main_queue(), block); + } +} void showWindow(NSWindow* window) { - dispatch_async(dispatch_get_main_queue(), ^{ - // [window setIsVisible:TRUE] + setWindowCanBeShown(true); + runOnMainThread(^{ + if (![[NSApplication sharedApplication] isActive]) { + [[NSApplication sharedApplication] activateIgnoringOtherApps:YES]; + } [window makeKeyAndOrderFront:nil]; }); } void hideWindow(NSWindow* window) { - - dispatch_async(dispatch_get_main_queue(), ^{ + runOnMainThread(^{ [window setIsVisible:FALSE]; }); } void moveWindow(NSWindow* window) { - dispatch_async(dispatch_get_main_queue(), ^{ + runOnMainThread(^{ [window performWindowDragWithEvent:[window currentEvent]]; - }); + }); } -void setSize(NSWindow* window, int width, int height){ +void setSize(NSWindow* window, int width, int height) { NSRect frame = [window frame]; frame.size.width = width; frame.size.height = height; - - dispatch_async(dispatch_get_main_queue(), ^{ + runOnMainThread(^{ [window setFrame:frame display:true]; }); } -void setMinSize(NSWindow* window, int width, int height){ +void setMinSize(NSWindow* window, int width, int height) { NSSize minSize; minSize.width = width; minSize.height = height; - - dispatch_async(dispatch_get_main_queue(), ^{ + runOnMainThread(^{ [window setMinSize:minSize]; }); } -void setMaxSize(NSWindow* window, int width, int height){ +void setMaxSize(NSWindow* window, int width, int height) { NSSize maxSize; maxSize.width = width; maxSize.height = height; - dispatch_async(dispatch_get_main_queue(), ^{ + runOnMainThread(^{ [window setMaxSize:maxSize]; }); } -BDWStatus getScreenInfoForWindow(NSWindow* window, BDWScreenInfo *screenInfo){ - auto screen = [window screen]; - auto workingScreenRect = [screen visibleFrame]; - auto fullScreenRect = [screen frame]; +BDWStatus getScreenInfoForWindow(NSWindow* window, BDWScreenInfo *screenInfo) { + auto workingScreenRect = controller.workingScreenRect; + auto fullScreenRect = controller.fullScreenRect; auto menuBarHeight = fullScreenRect.size.height - workingScreenRect.size.height - workingScreenRect.origin.y; - BDWRect* workingRect = screenInfo->workingRect; BDWRect* fullRect = screenInfo->fullRect; workingRect->top = menuBarHeight; workingRect->left = workingScreenRect.origin.x; workingRect->bottom = workingRect->top + workingScreenRect.size.height; workingRect->right = workingRect->left + workingScreenRect.size.width; - fullRect->left = fullScreenRect.origin.x; fullRect->right = fullRect->left + fullScreenRect.size.width; fullRect->top = fullScreenRect.origin.y; @@ -96,48 +107,36 @@ BDWStatus getScreenInfoForWindow(NSWindow* window, BDWScreenInfo *screenInfo){ return BDW_SUCCESS; } -BDWStatus setPositionForWindow(NSWindow* window, BDWOffset* offset){ - auto block = ^{ +BDWStatus setPositionForWindow(NSWindow* window, BDWOffset* offset) { + runOnMainThread(^{ NSPoint position; auto screen = [window screen]; auto fullScreenRect = [screen visibleFrame]; position.x = offset->x; position.y = fullScreenRect.origin.y + fullScreenRect.size.height - offset->y; [window setFrameTopLeftPoint:position]; - }; - - if ([NSThread isMainThread]) { - block(); - } else { - dispatch_async(dispatch_get_main_queue(), block); - } + }); return BDW_SUCCESS; } -BDWStatus setRectForWindow(NSWindow* window, BDWRect* rect){ - - auto block = ^ { - NSScreen* screen = [window screen]; - NSRect fullScreenRect = [screen frame]; - NSRect frame; - frame.size.width = rect->right - rect->left; - frame.size.height = rect->bottom - rect->top; - frame.origin.x = fullScreenRect.origin.x + rect->left; - frame.origin.y = fullScreenRect.origin.y + fullScreenRect.size.height - rect->bottom; - [window setFrame:frame display:TRUE]; - }; - if ([NSThread isMainThread]) { - block(); - } else { - dispatch_async(dispatch_get_main_queue(), block); - } +BDWStatus setRectForWindow(NSWindow* window, BDWRect* rect) { + setWindowCanBeShown(true); + NSRect fullScreenRect = controller.fullScreenRect; + NSRect frame; + frame.size.width = rect->right - rect->left; + frame.size.height = rect->bottom - rect->top; + frame.origin.x = fullScreenRect.origin.x + rect->left; + frame.origin.y = fullScreenRect.origin.y + fullScreenRect.size.height - rect->bottom; + controller.windowFrame = frame; + runOnMainThread(^{ + [window setFrame:frame display:YES]; + }); return BDW_SUCCESS; } -BDWStatus getRectForWindow(NSWindow* window, BDWRect *rect){ - NSScreen* screen = [window screen]; - auto workingScreenRect = [screen visibleFrame]; - NSRect frame = [window frame]; +BDWStatus getRectForWindow(NSWindow* window, BDWRect *rect) { + auto workingScreenRect = controller.workingScreenRect; + NSRect frame = controller.windowFrame; rect->left = frame.origin.x; auto frameTop = frame.origin.y + frame.size.height; auto workingScreenTop = workingScreenRect.origin.y + workingScreenRect.size.height; @@ -147,48 +146,46 @@ BDWStatus getRectForWindow(NSWindow* window, BDWRect *rect){ return BDW_SUCCESS; } -bool isWindowMaximized(NSWindow* window){ - return [window isZoomed]; +bool isWindowMaximized(NSWindow* window) { + return controller.isZoomed; } -bool isWindowVisible(NSWindow* window){ - return [window isVisible]; +bool isWindowVisible(NSWindow* window) { + return controller.isVisible; } -void maximizeOrRestoreWindow(NSWindow* window){ - dispatch_async(dispatch_get_main_queue(), ^{ +void maximizeOrRestoreWindow(NSWindow* window) { + runOnMainThread(^{ [window zoom:nil]; }); } -void maximizeWindow(NSWindow* window){ - dispatch_async(dispatch_get_main_queue(), ^{ +void maximizeWindow(NSWindow* window) { + runOnMainThread(^{ auto screen = [window screen]; [window setFrame:[screen visibleFrame] display:true animate:true]; }); } -void minimizeWindow(NSWindow* window){ - dispatch_async(dispatch_get_main_queue(), ^{ - [window miniaturize:nil]; +void minimizeWindow(NSWindow* window) { + runOnMainThread(^{ + [window miniaturize:nil]; }); } -void closeWindow(NSWindow* window){ - dispatch_async(dispatch_get_main_queue(), ^{ +void closeWindow(NSWindow* window) { + runOnMainThread(^{ [window close]; }); } -void setWindowTitle(NSWindow* window, const char* title){ +void setWindowTitle(NSWindow* window, const char* title) { NSString *_title = [NSString stringWithUTF8String:title]; - dispatch_async(dispatch_get_main_queue(), ^{ + runOnMainThread(^{ [window setTitle:_title]; }); } -double getTitleBarHeight(NSWindow* window){ - double windowFrameHeight = window.contentView.frame.size.height; - double contentLayoutHeight = window.contentLayoutRect.size.height; - return windowFrameHeight - contentLayoutHeight; +double getTitleBarHeight(NSWindow* window) { + return controller.titleBarHeight; } diff --git a/bitsdojo_window_macos/macos/Classes/bitsdojo_window_api.h b/bitsdojo_window_macos/macos/Classes/bitsdojo_window_api.h index be136ac..16ced52 100644 --- a/bitsdojo_window_macos/macos/Classes/bitsdojo_window_api.h +++ b/bitsdojo_window_macos/macos/Classes/bitsdojo_window_api.h @@ -32,6 +32,7 @@ typedef struct _BDWPublicAPI typedef struct _BDWPrivateAPI{ TWindowCanBeShown windowCanBeShown; TSetAppWindow setAppWindow; + TAppWindowIsSet appWindowIsSet; } BDWPrivateAPI; typedef struct _BDWAPI{ diff --git a/bitsdojo_window_macos/macos/Classes/bitsdojo_window_api.mm b/bitsdojo_window_macos/macos/Classes/bitsdojo_window_api.mm index 1413a0c..7f3e33f 100644 --- a/bitsdojo_window_macos/macos/Classes/bitsdojo_window_api.mm +++ b/bitsdojo_window_macos/macos/Classes/bitsdojo_window_api.mm @@ -3,7 +3,8 @@ BDWPrivateAPI privateAPI = { windowCanBeShown, - setAppWindow + setAppWindow, + appWindowIsSet, }; BDWPublicAPI publicAPI = { diff --git a/bitsdojo_window_macos/macos/Classes/bitsdojo_window_controller.h b/bitsdojo_window_macos/macos/Classes/bitsdojo_window_controller.h new file mode 100644 index 0000000..a116d53 --- /dev/null +++ b/bitsdojo_window_macos/macos/Classes/bitsdojo_window_controller.h @@ -0,0 +1,16 @@ +#import + +@interface BitsdojoWindowController : NSObject + +@property (assign) CGSize windowSize; +@property (assign) bool isVisible; +@property (assign) bool isZoomed; +@property (assign) double titleBarHeight; +@property (nonatomic, weak) NSWindow *window; +@property (assign) NSRect workingScreenRect; +@property (assign) NSRect fullScreenRect; +@property (assign) NSRect windowFrame; + +- (instancetype)initWithWindow:(NSWindow *)window; + +@end diff --git a/bitsdojo_window_macos/macos/Classes/bitsdojo_window_controller.mm b/bitsdojo_window_macos/macos/Classes/bitsdojo_window_controller.mm new file mode 100644 index 0000000..4dcb4bd --- /dev/null +++ b/bitsdojo_window_macos/macos/Classes/bitsdojo_window_controller.mm @@ -0,0 +1,66 @@ +#import "bitsdojo_window_controller.h" + +@implementation BitsdojoWindowController + +- (instancetype)initWithWindow:(NSWindow *)window { + self = [super init]; + if (self && window) { + self.window = window; + self.window.delegate = self; + [self onScreenChange]; + } + return self; +} + +- (void)onScreenChange { + self.isVisible = self.window.isVisible; + self.isZoomed = self.window.isZoomed; + [self setupScreenRects]; + [self setupWindowRects]; +} + +- (void)setupWindowRects { + self.windowFrame = self.window.frame; + double windowFrameHeight = self.window.contentView.frame.size.height; + double contentLayoutHeight = self.window.contentLayoutRect.size.height; + self.titleBarHeight = windowFrameHeight - contentLayoutHeight; +} + +- (void)setupScreenRects { + NSScreen *screen = self.window.screen; + self.workingScreenRect = screen.visibleFrame; + self.fullScreenRect = screen.frame; +} + +- (void)windowDidResize:(NSNotification *)notification { + NSWindow *resizedWindow = notification.object; + if ([resizedWindow isKindOfClass:[NSWindow class]]) { + [self setupWindowRects]; + self.windowSize = self.window.frame.size; + } +} + +-(void)handleWindowChanges { + self.isZoomed = self.window.isZoomed; +} + +- (void)windowDidBecomeVisible:(NSNotification *)notification { + self.isVisible = YES; +} + +- (void)windowDidBecomeHidden:(NSNotification *)notification { + self.isVisible = NO; +} + +- (void)windowDidChangeScreen:(NSNotification *)notification { + [self onScreenChange]; +} + +- (void)windowDidChangeBackingProperties:(NSNotification *)notification { + [self onScreenChange]; +} + +- (void)windowDidMiniaturize:(NSNotification *)notification { [self handleWindowChanges]; } +- (void)windowDidDeminiaturize:(NSNotification *)notification { [self handleWindowChanges]; } +- (void)windowDidEndLiveResize:(NSNotification *)notification { [self handleWindowChanges]; } +@end diff --git a/bitsdojo_window_macos/pubspec.yaml b/bitsdojo_window_macos/pubspec.yaml index 7873bc5..183b6b4 100644 --- a/bitsdojo_window_macos/pubspec.yaml +++ b/bitsdojo_window_macos/pubspec.yaml @@ -1,21 +1,21 @@ name: bitsdojo_window_macos description: macOS implementation of the bitsdojo_window plugin. -version: 0.1.3 +version: 0.1.4 homepage: https://www.bitsdojo.com repository: https://github.com/bitsdojo/bitsdojo_window environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=2.17.0 <4.0.0" flutter: ">=1.20.0" dependencies: flutter: sdk: flutter - bitsdojo_window_platform_interface: ^0.1.2 + bitsdojo_window_platform_interface: + ^0.1.2 #path: ../bitsdojo_window_platform_interface ffi: ^2.0.0 - dev_dependencies: flutter_test: sdk: flutter diff --git a/bitsdojo_window_platform_interface/pubspec.yaml b/bitsdojo_window_platform_interface/pubspec.yaml index 9f284a1..28fa4d4 100644 --- a/bitsdojo_window_platform_interface/pubspec.yaml +++ b/bitsdojo_window_platform_interface/pubspec.yaml @@ -18,5 +18,5 @@ dev_dependencies: pedantic: ^1.11.0 environment: - sdk: '>=2.17.0 <3.0.0' + sdk: ">=2.17.0 <4.0.0" flutter: ">=1.22.0" diff --git a/bitsdojo_window_windows/CHANGELOG.md b/bitsdojo_window_windows/CHANGELOG.md index b8b575f..bdf8313 100644 --- a/bitsdojo_window_windows/CHANGELOG.md +++ b/bitsdojo_window_windows/CHANGELOG.md @@ -1,3 +1,5 @@ +## 0.1.6 + - Various fixes to work with latest Flutter version ## 0.1.5 - Runs on Windows 7 ## 0.1.4 diff --git a/bitsdojo_window_windows/pubspec.yaml b/bitsdojo_window_windows/pubspec.yaml index 0d6c3b2..e1e525d 100644 --- a/bitsdojo_window_windows/pubspec.yaml +++ b/bitsdojo_window_windows/pubspec.yaml @@ -1,22 +1,22 @@ name: bitsdojo_window_windows description: Windows implementation of the bitsdojo_window plugin. -version: 0.1.5 +version: 0.1.6 homepage: https://www.bitsdojo.com repository: https://github.com/bitsdojo/bitsdojo_window environment: - sdk: ">=2.17.0 <3.0.0" + sdk: ">=2.17.0 <4.0.0" flutter: ">=1.20.0" dependencies: flutter: sdk: flutter - bitsdojo_window_platform_interface: ^0.1.2 + bitsdojo_window_platform_interface: + ^0.1.2 #path: ../bitsdojo_window_platform_interface - win32: ">=3.0.0 <5.0.0" + win32: ^5.1.1 ffi: ^2.0.0 - dev_dependencies: flutter_test: sdk: flutter @@ -25,4 +25,4 @@ flutter: plugin: platforms: windows: - pluginClass: BitsdojoWindowPlugin \ No newline at end of file + pluginClass: BitsdojoWindowPlugin diff --git a/bitsdojo_window_windows/test/bitsdojo_window_test.dart b/bitsdojo_window_windows/test/bitsdojo_window_test.dart deleted file mode 100644 index 60d1a37..0000000 --- a/bitsdojo_window_windows/test/bitsdojo_window_test.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - const MethodChannel channel = MethodChannel('bitsdojo/window'); - - TestWidgetsFlutterBinding.ensureInitialized(); - - setUp(() { - channel.setMockMethodCallHandler((MethodCall methodCall) async { - return '42'; - }); - }); - - tearDown(() { - channel.setMockMethodCallHandler(null); - }); -}