diff --git a/.gitignore b/.gitignore index f890f640..fa08f054 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,6 @@ -.DS_Store .dart_tool/ .idea/ -.packages -.pub/ -.vscode/ -build/ -Generated* -generated* + +*.iml +pubspec_overrides.yaml +pubspec.lock diff --git a/LICENSE b/LICENSE index 03d8b0a2..46e9d56a 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 LiJianying +Copyright (c) 2022-present LiJianying Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/example/pubspec.lock b/example/pubspec.lock deleted file mode 100644 index 46218dd2..00000000 --- a/example/pubspec.lock +++ /dev/null @@ -1,323 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" - source: hosted - version: "2.11.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - bot_toast: - dependency: "direct main" - description: - name: bot_toast - sha256: "6b93030a99a98335b8827ecd83021e92e885ffc61d261d3825ffdecdd17f3bdf" - url: "https://pub.dev" - source: hosted - version: "4.1.3" - characters: - dependency: transitive - description: - name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" - source: hosted - version: "1.3.0" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - collection: - dependency: transitive - description: - name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a - url: "https://pub.dev" - source: hosted - version: "1.18.0" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 - url: "https://pub.dev" - source: hosted - version: "1.0.8" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - file: - dependency: transitive - description: - name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" - url: "https://pub.dev" - source: hosted - version: "7.0.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_driver: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - fuchsia_remote_debug_protocol: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - integration_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - leak_tracker: - dependency: transitive - description: - name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" - url: "https://pub.dev" - source: hosted - version: "10.0.5" - leak_tracker_flutter_testing: - dependency: transitive - description: - name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" - url: "https://pub.dev" - source: hosted - version: "3.0.5" - leak_tracker_testing: - dependency: transitive - description: - name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" - url: "https://pub.dev" - source: hosted - version: "3.0.1" - lints: - dependency: transitive - description: - name: lints - sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" - url: "https://pub.dev" - source: hosted - version: "4.0.0" - matcher: - dependency: transitive - description: - name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb - url: "https://pub.dev" - source: hosted - version: "0.12.16+1" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec - url: "https://pub.dev" - source: hosted - version: "0.11.1" - menu_base: - dependency: transitive - description: - name: menu_base - sha256: "820368014a171bd1241030278e6c2617354f492f5c703d7b7d4570a6b8b84405" - url: "https://pub.dev" - source: hosted - version: "0.1.1" - meta: - dependency: transitive - description: - name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 - url: "https://pub.dev" - source: hosted - version: "1.15.0" - mostly_reasonable_lints: - dependency: "direct dev" - description: - name: mostly_reasonable_lints - sha256: e19fec63536866ba307b3dfbc258b4bce9b3745129f038006b56b4067c6293d8 - url: "https://pub.dev" - source: hosted - version: "0.1.2" - path: - dependency: transitive - description: - name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - url: "https://pub.dev" - source: hosted - version: "1.9.0" - platform: - dependency: transitive - description: - name: platform - sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" - url: "https://pub.dev" - source: hosted - version: "3.1.5" - preference_list: - dependency: "direct main" - description: - name: preference_list - sha256: "1429f8fe03605d5eaf6dc333208d7bbf028bae707c3c1c32386939e4d7f58154" - url: "https://pub.dev" - source: hosted - version: "0.0.2" - process: - dependency: transitive - description: - name: process - sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" - url: "https://pub.dev" - source: hosted - version: "5.0.2" - screen_retriever: - dependency: transitive - description: - name: screen_retriever - sha256: "6ee02c8a1158e6dae7ca430da79436e3b1c9563c8cf02f524af997c201ac2b90" - url: "https://pub.dev" - source: hosted - version: "0.1.9" - shortid: - dependency: transitive - description: - name: shortid - sha256: d0b40e3dbb50497dad107e19c54ca7de0d1a274eb9b4404991e443dadb9ebedb - url: "https://pub.dev" - source: hosted - version: "0.1.2" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" - url: "https://pub.dev" - source: hosted - version: "1.10.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" - url: "https://pub.dev" - source: hosted - version: "1.11.1" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 - url: "https://pub.dev" - source: hosted - version: "2.1.2" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - sync_http: - dependency: transitive - description: - name: sync_http - sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" - url: "https://pub.dev" - source: hosted - version: "0.3.1" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" - url: "https://pub.dev" - source: hosted - version: "0.7.2" - tray_manager: - dependency: "direct main" - description: - name: tray_manager - sha256: c9a63fd88bd3546287a7eb8ccc978d707eef82c775397af17dda3a4f4c039e64 - url: "https://pub.dev" - source: hosted - version: "0.2.3" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" - url: "https://pub.dev" - source: hosted - version: "14.2.5" - webdriver: - dependency: transitive - description: - name: webdriver - sha256: "003d7da9519e1e5f329422b36c4dcdf18d7d2978d1ba099ea4e45ba490ed845e" - url: "https://pub.dev" - source: hosted - version: "3.0.3" - window_manager: - dependency: "direct main" - description: - path: ".." - relative: true - source: path - version: "0.4.2" -sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" diff --git a/melos.yaml b/melos.yaml new file mode 100644 index 00000000..0c8036c9 --- /dev/null +++ b/melos.yaml @@ -0,0 +1,35 @@ +name: window_manager_workspace +repository: https://github.com/leanflutter/window_manager + +packages: + - examples/** + - packages/** + +command: + bootstrap: + # Uses the pubspec_overrides.yaml instead of having Melos modifying the lock file. + usePubspecOverrides: true + +scripts: + analyze: + exec: flutter analyze --fatal-infos + description: Run `flutter analyze` for all packages. + + test: + exec: flutter test + description: Run `flutter test` for a specific package. + packageFilters: + dirExists: + - test + + format: + exec: dart format . --fix + description: Run `dart format` for all packages. + + format-check: + exec: dart format . --fix --set-exit-if-changed + description: Run `dart format` checks for all packages. + + fix: + exec: dart fix . --apply + description: Run `dart fix` for all packages. diff --git a/packages/window_manager/.gitignore b/packages/window_manager/.gitignore new file mode 100644 index 00000000..96486fd9 --- /dev/null +++ b/packages/window_manager/.gitignore @@ -0,0 +1,30 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. +/pubspec.lock +**/doc/api/ +.dart_tool/ +.packages +build/ diff --git a/.metadata b/packages/window_manager/.metadata similarity index 100% rename from .metadata rename to packages/window_manager/.metadata diff --git a/CHANGELOG.md b/packages/window_manager/CHANGELOG.md similarity index 98% rename from CHANGELOG.md rename to packages/window_manager/CHANGELOG.md index de14d5b1..a101a0e8 100644 --- a/CHANGELOG.md +++ b/packages/window_manager/CHANGELOG.md @@ -1,3 +1,8 @@ +### 0.4.3 + +* [windows] fix: scale ratio on dpi change (#496) +* [windows] fix: get window monitor from minimized state (#495) + ### 0.4.2 * [windows] Update window_manager_plugin.cpp for fix #439 issue #486 diff --git a/packages/window_manager/LICENSE b/packages/window_manager/LICENSE new file mode 100644 index 00000000..46e9d56a --- /dev/null +++ b/packages/window_manager/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022-present LiJianying + +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. \ No newline at end of file diff --git a/packages/window_manager/README-ZH.md b/packages/window_manager/README-ZH.md new file mode 120000 index 00000000..7da944f1 --- /dev/null +++ b/packages/window_manager/README-ZH.md @@ -0,0 +1 @@ +../../README-ZH.md \ No newline at end of file diff --git a/packages/window_manager/README.md b/packages/window_manager/README.md new file mode 120000 index 00000000..fe840054 --- /dev/null +++ b/packages/window_manager/README.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/analysis_options.yaml b/packages/window_manager/analysis_options.yaml similarity index 100% rename from analysis_options.yaml rename to packages/window_manager/analysis_options.yaml diff --git a/dart_dependency_validator.yaml b/packages/window_manager/dart_dependency_validator.yaml similarity index 100% rename from dart_dependency_validator.yaml rename to packages/window_manager/dart_dependency_validator.yaml diff --git a/example/.gitignore b/packages/window_manager/example/.gitignore similarity index 100% rename from example/.gitignore rename to packages/window_manager/example/.gitignore diff --git a/example/.metadata b/packages/window_manager/example/.metadata similarity index 100% rename from example/.metadata rename to packages/window_manager/example/.metadata diff --git a/example/README.md b/packages/window_manager/example/README.md similarity index 100% rename from example/README.md rename to packages/window_manager/example/README.md diff --git a/example/analysis_options.yaml b/packages/window_manager/example/analysis_options.yaml similarity index 100% rename from example/analysis_options.yaml rename to packages/window_manager/example/analysis_options.yaml diff --git a/example/images/tray_icon.ico b/packages/window_manager/example/images/tray_icon.ico similarity index 100% rename from example/images/tray_icon.ico rename to packages/window_manager/example/images/tray_icon.ico diff --git a/example/images/tray_icon.png b/packages/window_manager/example/images/tray_icon.png similarity index 100% rename from example/images/tray_icon.png rename to packages/window_manager/example/images/tray_icon.png diff --git a/example/images/tray_icon_original.ico b/packages/window_manager/example/images/tray_icon_original.ico similarity index 100% rename from example/images/tray_icon_original.ico rename to packages/window_manager/example/images/tray_icon_original.ico diff --git a/example/images/tray_icon_original.png b/packages/window_manager/example/images/tray_icon_original.png similarity index 100% rename from example/images/tray_icon_original.png rename to packages/window_manager/example/images/tray_icon_original.png diff --git a/example/integration_test/window_manager_test.dart b/packages/window_manager/example/integration_test/window_manager_test.dart similarity index 100% rename from example/integration_test/window_manager_test.dart rename to packages/window_manager/example/integration_test/window_manager_test.dart diff --git a/example/lib/main.dart b/packages/window_manager/example/lib/main.dart similarity index 100% rename from example/lib/main.dart rename to packages/window_manager/example/lib/main.dart diff --git a/example/lib/pages/home.dart b/packages/window_manager/example/lib/pages/home.dart similarity index 100% rename from example/lib/pages/home.dart rename to packages/window_manager/example/lib/pages/home.dart diff --git a/example/lib/utils/config.dart b/packages/window_manager/example/lib/utils/config.dart similarity index 100% rename from example/lib/utils/config.dart rename to packages/window_manager/example/lib/utils/config.dart diff --git a/example/linux/.gitignore b/packages/window_manager/example/linux/.gitignore similarity index 100% rename from example/linux/.gitignore rename to packages/window_manager/example/linux/.gitignore diff --git a/example/linux/CMakeLists.txt b/packages/window_manager/example/linux/CMakeLists.txt similarity index 100% rename from example/linux/CMakeLists.txt rename to packages/window_manager/example/linux/CMakeLists.txt diff --git a/example/linux/flutter/CMakeLists.txt b/packages/window_manager/example/linux/flutter/CMakeLists.txt similarity index 100% rename from example/linux/flutter/CMakeLists.txt rename to packages/window_manager/example/linux/flutter/CMakeLists.txt diff --git a/example/linux/main.cc b/packages/window_manager/example/linux/main.cc similarity index 100% rename from example/linux/main.cc rename to packages/window_manager/example/linux/main.cc diff --git a/example/linux/my_application.cc b/packages/window_manager/example/linux/my_application.cc similarity index 100% rename from example/linux/my_application.cc rename to packages/window_manager/example/linux/my_application.cc diff --git a/example/linux/my_application.h b/packages/window_manager/example/linux/my_application.h similarity index 100% rename from example/linux/my_application.h rename to packages/window_manager/example/linux/my_application.h diff --git a/example/macos/.gitignore b/packages/window_manager/example/macos/.gitignore similarity index 100% rename from example/macos/.gitignore rename to packages/window_manager/example/macos/.gitignore diff --git a/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/window_manager/example/macos/Flutter/Flutter-Debug.xcconfig similarity index 100% rename from example/macos/Flutter/Flutter-Debug.xcconfig rename to packages/window_manager/example/macos/Flutter/Flutter-Debug.xcconfig diff --git a/example/macos/Flutter/Flutter-Release.xcconfig b/packages/window_manager/example/macos/Flutter/Flutter-Release.xcconfig similarity index 100% rename from example/macos/Flutter/Flutter-Release.xcconfig rename to packages/window_manager/example/macos/Flutter/Flutter-Release.xcconfig diff --git a/packages/window_manager/example/macos/Flutter/GeneratedPluginRegistrant.swift b/packages/window_manager/example/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 00000000..641dc94f --- /dev/null +++ b/packages/window_manager/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,16 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + +import screen_retriever_macos +import tray_manager +import window_manager + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin")) + TrayManagerPlugin.register(with: registry.registrar(forPlugin: "TrayManagerPlugin")) + WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) +} diff --git a/example/macos/Podfile b/packages/window_manager/example/macos/Podfile similarity index 100% rename from example/macos/Podfile rename to packages/window_manager/example/macos/Podfile diff --git a/example/macos/Podfile.lock b/packages/window_manager/example/macos/Podfile.lock similarity index 73% rename from example/macos/Podfile.lock rename to packages/window_manager/example/macos/Podfile.lock index 5326c40f..f7e4c3ee 100644 --- a/example/macos/Podfile.lock +++ b/packages/window_manager/example/macos/Podfile.lock @@ -1,6 +1,6 @@ PODS: - FlutterMacOS (1.0.0) - - screen_retriever (0.0.1): + - screen_retriever_macos (0.0.1): - FlutterMacOS - tray_manager (0.0.1): - FlutterMacOS @@ -9,15 +9,15 @@ PODS: DEPENDENCIES: - FlutterMacOS (from `Flutter/ephemeral`) - - screen_retriever (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos`) + - screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`) - tray_manager (from `Flutter/ephemeral/.symlinks/plugins/tray_manager/macos`) - window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`) EXTERNAL SOURCES: FlutterMacOS: :path: Flutter/ephemeral - screen_retriever: - :path: Flutter/ephemeral/.symlinks/plugins/screen_retriever/macos + screen_retriever_macos: + :path: Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos tray_manager: :path: Flutter/ephemeral/.symlinks/plugins/tray_manager/macos window_manager: @@ -25,7 +25,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 - screen_retriever: 59634572a57080243dd1bf715e55b6c54f241a38 + screen_retriever_macos: 776e0fa5d42c6163d2bf772d22478df4b302b161 tray_manager: 9064e219c56d75c476e46b9a21182087930baf90 window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8 diff --git a/example/macos/Runner.xcodeproj/project.pbxproj b/packages/window_manager/example/macos/Runner.xcodeproj/project.pbxproj similarity index 100% rename from example/macos/Runner.xcodeproj/project.pbxproj rename to packages/window_manager/example/macos/Runner.xcodeproj/project.pbxproj diff --git a/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/window_manager/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to packages/window_manager/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/window_manager/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to packages/window_manager/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/packages/window_manager/example/macos/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from example/macos/Runner.xcworkspace/contents.xcworkspacedata rename to packages/window_manager/example/macos/Runner.xcworkspace/contents.xcworkspacedata diff --git a/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/packages/window_manager/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to packages/window_manager/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/example/macos/Runner/AppDelegate.swift b/packages/window_manager/example/macos/Runner/AppDelegate.swift similarity index 100% rename from example/macos/Runner/AppDelegate.swift rename to packages/window_manager/example/macos/Runner/AppDelegate.swift diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png similarity index 100% rename from example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png rename to packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png similarity index 100% rename from example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png rename to packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png similarity index 100% rename from example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png rename to packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png similarity index 100% rename from example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png rename to packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png similarity index 100% rename from example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png rename to packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png similarity index 100% rename from example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png rename to packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png diff --git a/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png similarity index 100% rename from example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png rename to packages/window_manager/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png diff --git a/example/macos/Runner/Base.lproj/MainMenu.xib b/packages/window_manager/example/macos/Runner/Base.lproj/MainMenu.xib similarity index 100% rename from example/macos/Runner/Base.lproj/MainMenu.xib rename to packages/window_manager/example/macos/Runner/Base.lproj/MainMenu.xib diff --git a/example/macos/Runner/Configs/AppInfo.xcconfig b/packages/window_manager/example/macos/Runner/Configs/AppInfo.xcconfig similarity index 100% rename from example/macos/Runner/Configs/AppInfo.xcconfig rename to packages/window_manager/example/macos/Runner/Configs/AppInfo.xcconfig diff --git a/example/macos/Runner/Configs/Debug.xcconfig b/packages/window_manager/example/macos/Runner/Configs/Debug.xcconfig similarity index 100% rename from example/macos/Runner/Configs/Debug.xcconfig rename to packages/window_manager/example/macos/Runner/Configs/Debug.xcconfig diff --git a/example/macos/Runner/Configs/Release.xcconfig b/packages/window_manager/example/macos/Runner/Configs/Release.xcconfig similarity index 100% rename from example/macos/Runner/Configs/Release.xcconfig rename to packages/window_manager/example/macos/Runner/Configs/Release.xcconfig diff --git a/example/macos/Runner/Configs/Warnings.xcconfig b/packages/window_manager/example/macos/Runner/Configs/Warnings.xcconfig similarity index 100% rename from example/macos/Runner/Configs/Warnings.xcconfig rename to packages/window_manager/example/macos/Runner/Configs/Warnings.xcconfig diff --git a/example/macos/Runner/DebugProfile.entitlements b/packages/window_manager/example/macos/Runner/DebugProfile.entitlements similarity index 100% rename from example/macos/Runner/DebugProfile.entitlements rename to packages/window_manager/example/macos/Runner/DebugProfile.entitlements diff --git a/example/macos/Runner/Info.plist b/packages/window_manager/example/macos/Runner/Info.plist similarity index 100% rename from example/macos/Runner/Info.plist rename to packages/window_manager/example/macos/Runner/Info.plist diff --git a/example/macos/Runner/MainFlutterWindow.swift b/packages/window_manager/example/macos/Runner/MainFlutterWindow.swift similarity index 100% rename from example/macos/Runner/MainFlutterWindow.swift rename to packages/window_manager/example/macos/Runner/MainFlutterWindow.swift diff --git a/example/macos/Runner/Release.entitlements b/packages/window_manager/example/macos/Runner/Release.entitlements similarity index 100% rename from example/macos/Runner/Release.entitlements rename to packages/window_manager/example/macos/Runner/Release.entitlements diff --git a/example/pubspec.yaml b/packages/window_manager/example/pubspec.yaml similarity index 100% rename from example/pubspec.yaml rename to packages/window_manager/example/pubspec.yaml diff --git a/example/test/widget_test.dart b/packages/window_manager/example/test/widget_test.dart similarity index 100% rename from example/test/widget_test.dart rename to packages/window_manager/example/test/widget_test.dart diff --git a/example/windows/.gitignore b/packages/window_manager/example/windows/.gitignore similarity index 94% rename from example/windows/.gitignore rename to packages/window_manager/example/windows/.gitignore index ec4098aa..d492d0d9 100644 --- a/example/windows/.gitignore +++ b/packages/window_manager/example/windows/.gitignore @@ -1,17 +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/ +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/example/windows/CMakeLists.txt b/packages/window_manager/example/windows/CMakeLists.txt similarity index 97% rename from example/windows/CMakeLists.txt rename to packages/window_manager/example/windows/CMakeLists.txt index 65a82a22..471f7dde 100644 --- a/example/windows/CMakeLists.txt +++ b/packages/window_manager/example/windows/CMakeLists.txt @@ -1,95 +1,95 @@ -cmake_minimum_required(VERSION 3.14) -project(window_manager_example LANGUAGES CXX) - -set(BINARY_NAME "window_manager_example") - -cmake_policy(SET CMP0063 NEW) - -set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") - -# Configure build options. -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() - -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. -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() - -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") - -# Flutter library and tool build rules. -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# Application build -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) +cmake_minimum_required(VERSION 3.14) +project(window_manager_example LANGUAGES CXX) + +set(BINARY_NAME "window_manager_example") + +cmake_policy(SET CMP0063 NEW) + +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Configure build options. +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() + +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. +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() + +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") + +# Flutter library and tool build rules. +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build +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/example/windows/flutter/CMakeLists.txt b/packages/window_manager/example/windows/flutter/CMakeLists.txt similarity index 97% rename from example/windows/flutter/CMakeLists.txt rename to packages/window_manager/example/windows/flutter/CMakeLists.txt index e7107414..4f2af69b 100644 --- a/example/windows/flutter/CMakeLists.txt +++ b/packages/window_manager/example/windows/flutter/CMakeLists.txt @@ -1,108 +1,108 @@ -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") - -# Set fallback configurations for older versions of the flutter tool. -if (NOT DEFINED FLUTTER_TARGET_PLATFORM) - set(FLUTTER_TARGET_PLATFORM "windows-x64") -endif() - -# === 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" - ${FLUTTER_TARGET_PLATFORM} $ - VERBATIM -) -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} -) +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") + +# Set fallback configurations for older versions of the flutter tool. +if (NOT DEFINED FLUTTER_TARGET_PLATFORM) + set(FLUTTER_TARGET_PLATFORM "windows-x64") +endif() + +# === 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" + ${FLUTTER_TARGET_PLATFORM} $ + 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/example/windows/runner/CMakeLists.txt b/packages/window_manager/example/windows/runner/CMakeLists.txt similarity index 97% rename from example/windows/runner/CMakeLists.txt rename to packages/window_manager/example/windows/runner/CMakeLists.txt index 945bda7a..de2d8916 100644 --- a/example/windows/runner/CMakeLists.txt +++ b/packages/window_manager/example/windows/runner/CMakeLists.txt @@ -1,17 +1,17 @@ -cmake_minimum_required(VERSION 3.14) -project(runner LANGUAGES CXX) - -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_standard_settings(${BINARY_NAME}) -target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") -target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) -target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") -add_dependencies(${BINARY_NAME} flutter_assemble) +cmake_minimum_required(VERSION 3.14) +project(runner LANGUAGES CXX) + +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_standard_settings(${BINARY_NAME}) +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/example/windows/runner/Runner.rc b/packages/window_manager/example/windows/runner/Runner.rc similarity index 96% rename from example/windows/runner/Runner.rc rename to packages/window_manager/example/windows/runner/Runner.rc index 9b09cecb..90549426 100644 --- a/example/windows/runner/Runner.rc +++ b/packages/window_manager/example/windows/runner/Runner.rc @@ -1,121 +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", "org.leanflutter.plugins" "\0" - VALUE "FileDescription", "window_manager_example" "\0" - VALUE "FileVersion", VERSION_AS_STRING "\0" - VALUE "InternalName", "window_manager_example" "\0" - VALUE "LegalCopyright", "Copyright (C) 2022 org.leanflutter.plugins. All rights reserved." "\0" - VALUE "OriginalFilename", "window_manager_example.exe" "\0" - VALUE "ProductName", "window_manager_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 +// 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", "org.leanflutter.plugins" "\0" + VALUE "FileDescription", "window_manager_example" "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "window_manager_example" "\0" + VALUE "LegalCopyright", "Copyright (C) 2022 org.leanflutter.plugins. All rights reserved." "\0" + VALUE "OriginalFilename", "window_manager_example.exe" "\0" + VALUE "ProductName", "window_manager_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/example/windows/runner/flutter_window.cpp b/packages/window_manager/example/windows/runner/flutter_window.cpp similarity index 96% rename from example/windows/runner/flutter_window.cpp rename to packages/window_manager/example/windows/runner/flutter_window.cpp index 3a11b51d..b43b9095 100644 --- a/example/windows/runner/flutter_window.cpp +++ b/packages/window_manager/example/windows/runner/flutter_window.cpp @@ -1,61 +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); -} +#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/example/windows/runner/flutter_window.h b/packages/window_manager/example/windows/runner/flutter_window.h similarity index 96% rename from example/windows/runner/flutter_window.h rename to packages/window_manager/example/windows/runner/flutter_window.h index 28c23839..6da0652f 100644 --- a/example/windows/runner/flutter_window.h +++ b/packages/window_manager/example/windows/runner/flutter_window.h @@ -1,33 +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_ +#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/example/windows/runner/main.cpp b/packages/window_manager/example/windows/runner/main.cpp similarity index 96% rename from example/windows/runner/main.cpp rename to packages/window_manager/example/windows/runner/main.cpp index aa4e9ec5..f310af45 100644 --- a/example/windows/runner/main.cpp +++ b/packages/window_manager/example/windows/runner/main.cpp @@ -1,43 +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"window_manager_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; -} +#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"window_manager_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/example/windows/runner/resource.h b/packages/window_manager/example/windows/runner/resource.h similarity index 96% rename from example/windows/runner/resource.h rename to packages/window_manager/example/windows/runner/resource.h index ddc7f3ef..66a65d1e 100644 --- a/example/windows/runner/resource.h +++ b/packages/window_manager/example/windows/runner/resource.h @@ -1,16 +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 +//{{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/example/windows/runner/resources/app_icon.ico b/packages/window_manager/example/windows/runner/resources/app_icon.ico similarity index 100% rename from example/windows/runner/resources/app_icon.ico rename to packages/window_manager/example/windows/runner/resources/app_icon.ico diff --git a/example/windows/runner/runner.exe.manifest b/packages/window_manager/example/windows/runner/runner.exe.manifest similarity index 97% rename from example/windows/runner/runner.exe.manifest rename to packages/window_manager/example/windows/runner/runner.exe.manifest index 2c680b8b..c977c4a4 100644 --- a/example/windows/runner/runner.exe.manifest +++ b/packages/window_manager/example/windows/runner/runner.exe.manifest @@ -1,20 +1,20 @@ - - - - - PerMonitorV2 - - - - - - - - - - - - - - - + + + + + PerMonitorV2 + + + + + + + + + + + + + + + diff --git a/example/windows/runner/utils.cpp b/packages/window_manager/example/windows/runner/utils.cpp similarity index 96% rename from example/windows/runner/utils.cpp rename to packages/window_manager/example/windows/runner/utils.cpp index 05b53c01..d19bdbbc 100644 --- a/example/windows/runner/utils.cpp +++ b/packages/window_manager/example/windows/runner/utils.cpp @@ -1,64 +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); - if (target_length == 0) { - return std::string(); - } - std::string 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; -} +#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); + if (target_length == 0) { + return std::string(); + } + std::string 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/example/windows/runner/utils.h b/packages/window_manager/example/windows/runner/utils.h similarity index 97% rename from example/windows/runner/utils.h rename to packages/window_manager/example/windows/runner/utils.h index 3f0e05cb..3879d547 100644 --- a/example/windows/runner/utils.h +++ b/packages/window_manager/example/windows/runner/utils.h @@ -1,19 +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_ +#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/example/windows/runner/win32_window.cpp b/packages/window_manager/example/windows/runner/win32_window.cpp similarity index 96% rename from example/windows/runner/win32_window.cpp rename to packages/window_manager/example/windows/runner/win32_window.cpp index f18c269b..3273c2c0 100644 --- a/example/windows/runner/win32_window.cpp +++ b/packages/window_manager/example/windows/runner/win32_window.cpp @@ -1,245 +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, - 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. -} +#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, + 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/example/windows/runner/win32_window.h b/packages/window_manager/example/windows/runner/win32_window.h similarity index 97% rename from example/windows/runner/win32_window.h rename to packages/window_manager/example/windows/runner/win32_window.h index d9bcac1b..17ba4311 100644 --- a/example/windows/runner/win32_window.h +++ b/packages/window_manager/example/windows/runner/win32_window.h @@ -1,98 +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_ +#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/lib/src/resize_edge.dart b/packages/window_manager/lib/src/resize_edge.dart similarity index 100% rename from lib/src/resize_edge.dart rename to packages/window_manager/lib/src/resize_edge.dart diff --git a/lib/src/title_bar_style.dart b/packages/window_manager/lib/src/title_bar_style.dart similarity index 100% rename from lib/src/title_bar_style.dart rename to packages/window_manager/lib/src/title_bar_style.dart diff --git a/lib/src/utils/calc_window_position.dart b/packages/window_manager/lib/src/utils/calc_window_position.dart similarity index 100% rename from lib/src/utils/calc_window_position.dart rename to packages/window_manager/lib/src/utils/calc_window_position.dart diff --git a/lib/src/widgets/drag_to_move_area.dart b/packages/window_manager/lib/src/widgets/drag_to_move_area.dart similarity index 100% rename from lib/src/widgets/drag_to_move_area.dart rename to packages/window_manager/lib/src/widgets/drag_to_move_area.dart diff --git a/lib/src/widgets/drag_to_resize_area.dart b/packages/window_manager/lib/src/widgets/drag_to_resize_area.dart similarity index 100% rename from lib/src/widgets/drag_to_resize_area.dart rename to packages/window_manager/lib/src/widgets/drag_to_resize_area.dart diff --git a/lib/src/widgets/virtual_window_frame.dart b/packages/window_manager/lib/src/widgets/virtual_window_frame.dart similarity index 100% rename from lib/src/widgets/virtual_window_frame.dart rename to packages/window_manager/lib/src/widgets/virtual_window_frame.dart diff --git a/lib/src/widgets/window_caption.dart b/packages/window_manager/lib/src/widgets/window_caption.dart similarity index 100% rename from lib/src/widgets/window_caption.dart rename to packages/window_manager/lib/src/widgets/window_caption.dart diff --git a/lib/src/widgets/window_caption_button.dart b/packages/window_manager/lib/src/widgets/window_caption_button.dart similarity index 100% rename from lib/src/widgets/window_caption_button.dart rename to packages/window_manager/lib/src/widgets/window_caption_button.dart diff --git a/lib/src/window_listener.dart b/packages/window_manager/lib/src/window_listener.dart similarity index 100% rename from lib/src/window_listener.dart rename to packages/window_manager/lib/src/window_listener.dart diff --git a/lib/src/window_manager.dart b/packages/window_manager/lib/src/window_manager.dart similarity index 100% rename from lib/src/window_manager.dart rename to packages/window_manager/lib/src/window_manager.dart diff --git a/lib/src/window_options.dart b/packages/window_manager/lib/src/window_options.dart similarity index 100% rename from lib/src/window_options.dart rename to packages/window_manager/lib/src/window_options.dart diff --git a/lib/window_manager.dart b/packages/window_manager/lib/window_manager.dart similarity index 100% rename from lib/window_manager.dart rename to packages/window_manager/lib/window_manager.dart diff --git a/linux/CMakeLists.txt b/packages/window_manager/linux/CMakeLists.txt similarity index 100% rename from linux/CMakeLists.txt rename to packages/window_manager/linux/CMakeLists.txt diff --git a/linux/include/window_manager/window_manager_plugin.h b/packages/window_manager/linux/include/window_manager/window_manager_plugin.h similarity index 100% rename from linux/include/window_manager/window_manager_plugin.h rename to packages/window_manager/linux/include/window_manager/window_manager_plugin.h diff --git a/linux/window_manager_plugin.cc b/packages/window_manager/linux/window_manager_plugin.cc similarity index 100% rename from linux/window_manager_plugin.cc rename to packages/window_manager/linux/window_manager_plugin.cc diff --git a/macos/Classes/WindowManager.swift b/packages/window_manager/macos/Classes/WindowManager.swift similarity index 100% rename from macos/Classes/WindowManager.swift rename to packages/window_manager/macos/Classes/WindowManager.swift diff --git a/macos/Classes/WindowManagerPlugin.swift b/packages/window_manager/macos/Classes/WindowManagerPlugin.swift similarity index 100% rename from macos/Classes/WindowManagerPlugin.swift rename to packages/window_manager/macos/Classes/WindowManagerPlugin.swift diff --git a/macos/window_manager.podspec b/packages/window_manager/macos/window_manager.podspec similarity index 100% rename from macos/window_manager.podspec rename to packages/window_manager/macos/window_manager.podspec diff --git a/packages/window_manager/pubspec.yaml b/packages/window_manager/pubspec.yaml new file mode 100644 index 00000000..a881ece3 --- /dev/null +++ b/packages/window_manager/pubspec.yaml @@ -0,0 +1,42 @@ +name: window_manager +description: This plugin allows Flutter desktop apps to resizing and repositioning the window. +version: 0.4.3 +homepage: https://github.com/leanflutter/window_manager + +platforms: + linux: + macos: + windows: + +topics: + - window + - window-resize + - window-manager + - desktop + - desktop-window + +environment: + sdk: ">=3.0.0 <4.0.0" + flutter: ">=3.3.0" + +dependencies: + flutter: + sdk: flutter + path: ^1.8.2 + screen_retriever: ^0.2.0 + +dev_dependencies: + dependency_validator: ^3.0.0 + flutter_test: + sdk: flutter + mostly_reasonable_lints: ^0.1.2 + +flutter: + plugin: + platforms: + linux: + pluginClass: WindowManagerPlugin + macos: + pluginClass: WindowManagerPlugin + windows: + pluginClass: WindowManagerPlugin diff --git a/test/window_manager_test.dart b/packages/window_manager/test/window_manager_test.dart similarity index 100% rename from test/window_manager_test.dart rename to packages/window_manager/test/window_manager_test.dart diff --git a/windows/.gitignore b/packages/window_manager/windows/.gitignore similarity index 94% rename from windows/.gitignore rename to packages/window_manager/windows/.gitignore index 808064a0..b3eb2be1 100644 --- a/windows/.gitignore +++ b/packages/window_manager/windows/.gitignore @@ -1,17 +1,17 @@ -flutter/ - -# 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/ +flutter/ + +# 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/windows/CMakeLists.txt b/packages/window_manager/windows/CMakeLists.txt similarity index 97% rename from windows/CMakeLists.txt rename to packages/window_manager/windows/CMakeLists.txt index a5375226..cb09c10a 100644 --- a/windows/CMakeLists.txt +++ b/packages/window_manager/windows/CMakeLists.txt @@ -1,26 +1,26 @@ -cmake_minimum_required(VERSION 3.15) -set(PROJECT_NAME "window_manager") -project(${PROJECT_NAME} LANGUAGES CXX) - -# This value is used when generating builds using this plugin, so it must -# not be changed -set(PLUGIN_NAME "window_manager_plugin") - -add_library(${PLUGIN_NAME} SHARED - "window_manager.cpp" - "window_manager_plugin.cpp" -) -apply_standard_settings(${PLUGIN_NAME}) -set_target_properties(${PLUGIN_NAME} PROPERTIES - CXX_VISIBILITY_PRESET hidden) -target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) -target_compile_definitions(${PLUGIN_NAME} PRIVATE _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING) -target_include_directories(${PLUGIN_NAME} INTERFACE - "${CMAKE_CURRENT_SOURCE_DIR}/include") -target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin) - -# List of absolute paths to libraries that should be bundled with the plugin -set(window_manager_bundled_libraries - "" - PARENT_SCOPE -) +cmake_minimum_required(VERSION 3.15) +set(PROJECT_NAME "window_manager") +project(${PROJECT_NAME} LANGUAGES CXX) + +# This value is used when generating builds using this plugin, so it must +# not be changed +set(PLUGIN_NAME "window_manager_plugin") + +add_library(${PLUGIN_NAME} SHARED + "window_manager.cpp" + "window_manager_plugin.cpp" +) +apply_standard_settings(${PLUGIN_NAME}) +set_target_properties(${PLUGIN_NAME} PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) +target_compile_definitions(${PLUGIN_NAME} PRIVATE _SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING) +target_include_directories(${PLUGIN_NAME} INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}/include") +target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin) + +# List of absolute paths to libraries that should be bundled with the plugin +set(window_manager_bundled_libraries + "" + PARENT_SCOPE +) diff --git a/windows/include/window_manager/window_manager_plugin.h b/packages/window_manager/windows/include/window_manager/window_manager_plugin.h similarity index 95% rename from windows/include/window_manager/window_manager_plugin.h rename to packages/window_manager/windows/include/window_manager/window_manager_plugin.h index c4c9e839..8de48046 100644 --- a/windows/include/window_manager/window_manager_plugin.h +++ b/packages/window_manager/windows/include/window_manager/window_manager_plugin.h @@ -1,25 +1,25 @@ -#ifndef FLUTTER_PLUGIN_WINDOW_MANAGER_PLUGIN_H_ -#define FLUTTER_PLUGIN_WINDOW_MANAGER_PLUGIN_H_ - -#include - -#include - -#ifdef FLUTTER_PLUGIN_IMPL -#define FLUTTER_PLUGIN_EXPORT __declspec(dllexport) -#else -#define FLUTTER_PLUGIN_EXPORT __declspec(dllimport) -#endif - -#if defined(__cplusplus) -extern "C" { -#endif - -FLUTTER_PLUGIN_EXPORT void WindowManagerPluginRegisterWithRegistrar( - FlutterDesktopPluginRegistrarRef registrar); - -#if defined(__cplusplus) -} // extern "C" -#endif - -#endif // FLUTTER_PLUGIN_WINDOW_MANAGER_PLUGIN_H_ +#ifndef FLUTTER_PLUGIN_WINDOW_MANAGER_PLUGIN_H_ +#define FLUTTER_PLUGIN_WINDOW_MANAGER_PLUGIN_H_ + +#include + +#include + +#ifdef FLUTTER_PLUGIN_IMPL +#define FLUTTER_PLUGIN_EXPORT __declspec(dllexport) +#else +#define FLUTTER_PLUGIN_EXPORT __declspec(dllimport) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +FLUTTER_PLUGIN_EXPORT void WindowManagerPluginRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar); + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // FLUTTER_PLUGIN_WINDOW_MANAGER_PLUGIN_H_ diff --git a/windows/window_manager.cpp b/packages/window_manager/windows/window_manager.cpp similarity index 100% rename from windows/window_manager.cpp rename to packages/window_manager/windows/window_manager.cpp diff --git a/windows/window_manager_plugin.cpp b/packages/window_manager/windows/window_manager_plugin.cpp similarity index 97% rename from windows/window_manager_plugin.cpp rename to packages/window_manager/windows/window_manager_plugin.cpp index 7d4a55eb..36e767ab 100644 --- a/windows/window_manager_plugin.cpp +++ b/packages/window_manager/windows/window_manager_plugin.cpp @@ -1,596 +1,596 @@ -#include "include/window_manager/window_manager_plugin.h" - -// This must be included before many other Windows headers. -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include "window_manager.cpp" - -namespace { - -bool IsWindows11OrGreater() { - DWORD dwVersion = 0; - DWORD dwBuild = 0; - -#pragma warning(push) -#pragma warning(disable : 4996) - dwVersion = GetVersion(); - // Get the build number. - if (dwVersion < 0x80000000) - dwBuild = (DWORD)(HIWORD(dwVersion)); -#pragma warning(pop) - - return dwBuild < 22000; -} - -std::unique_ptr< - flutter::MethodChannel, - std::default_delete>> - channel = nullptr; - -class WindowManagerPlugin : public flutter::Plugin { - public: - static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar); - - WindowManagerPlugin(flutter::PluginRegistrarWindows* registrar); - - virtual ~WindowManagerPlugin(); - - private: - WindowManager* window_manager; - flutter::PluginRegistrarWindows* registrar; - - // The ID of the WindowProc delegate registration. - int window_proc_id = -1; - - void WindowManagerPlugin::_EmitEvent(std::string eventName); - // Called for top-level WindowProc delegation. - std::optional WindowManagerPlugin::HandleWindowProc(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam); - // Called when a method is called on this plugin's channel from Dart. - void HandleMethodCall( - const flutter::MethodCall& method_call, - std::unique_ptr> result); - - void adjustNCCALCSIZE(HWND hwnd, NCCALCSIZE_PARAMS* sz) { - LONG l = 8; - LONG t = 8; - - // HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); - // Don't use `MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST)` above. - // Because if the window is restored from minimized state, the window is not in the correct monitor. - // The monitor is always the left-most monitor. - // https://github.com/leanflutter/window_manager/issues/489 - HMONITOR monitor = MonitorFromRect(&sz->rgrc[0], MONITOR_DEFAULTTONEAREST); - if (monitor != NULL) { - MONITORINFO monitorInfo; - monitorInfo.cbSize = sizeof(MONITORINFO); - if (TRUE == GetMonitorInfo(monitor, &monitorInfo)) { - l = sz->rgrc[0].left - monitorInfo.rcWork.left; - t = sz->rgrc[0].top - monitorInfo.rcWork.top; - } else { - // GetMonitorInfo failed, use (8, 8) as default value - } - } else { - // unreachable code - } - - sz->rgrc[0].left -= l; - sz->rgrc[0].top -= t; - sz->rgrc[0].right += l; - sz->rgrc[0].bottom += t; - } -}; - -// static -void WindowManagerPlugin::RegisterWithRegistrar( - flutter::PluginRegistrarWindows* registrar) { - channel = std::make_unique>( - registrar->messenger(), "window_manager", - &flutter::StandardMethodCodec::GetInstance()); - - auto plugin = std::make_unique(registrar); - - channel->SetMethodCallHandler( - [plugin_pointer = plugin.get()](const auto& call, auto result) { - plugin_pointer->HandleMethodCall(call, std::move(result)); - }); - - registrar->AddPlugin(std::move(plugin)); -} - -WindowManagerPlugin::WindowManagerPlugin( - flutter::PluginRegistrarWindows* registrar) - : registrar(registrar) { - window_manager = new WindowManager(); - window_proc_id = registrar->RegisterTopLevelWindowProcDelegate( - [this](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { - return HandleWindowProc(hWnd, message, wParam, lParam); - }); -} - -WindowManagerPlugin::~WindowManagerPlugin() { - registrar->UnregisterTopLevelWindowProcDelegate(window_proc_id); - channel = nullptr; -} - -void WindowManagerPlugin::_EmitEvent(std::string eventName) { - if (channel == nullptr) - return; - flutter::EncodableMap args = flutter::EncodableMap(); - args[flutter::EncodableValue("eventName")] = - flutter::EncodableValue(eventName); - channel->InvokeMethod("onEvent", - std::make_unique(args)); -} - -std::optional WindowManagerPlugin::HandleWindowProc(HWND hWnd, - UINT message, - WPARAM wParam, - LPARAM lParam) { - std::optional result = std::nullopt; - - if (message == WM_DPICHANGED) { - window_manager->pixel_ratio_ = - (float)LOWORD(wParam) / USER_DEFAULT_SCREEN_DPI; - window_manager->ForceChildRefresh(); - } - - if (wParam && message == WM_NCCALCSIZE) { - if (window_manager->IsFullScreen() && - window_manager->title_bar_style_ != "normal") { - if (window_manager->is_frameless_) { - adjustNCCALCSIZE(hWnd, reinterpret_cast(lParam)); - } - return 0; - } - // This must always be before handling title_bar_style_ == "hidden" so - // the `if TitleBarStyle.hidden` doesn't get executed. - if (window_manager->is_frameless_) { - if (window_manager->IsMaximized()) { - adjustNCCALCSIZE(hWnd, reinterpret_cast(lParam)); - } - return 0; - } - - // This must always be last. - if (wParam && window_manager->title_bar_style_ == "hidden") { - if (window_manager->IsMaximized()) { - // Adjust the borders when maximized so the app isn't cut off - adjustNCCALCSIZE(hWnd, reinterpret_cast(lParam)); - } else { - NCCALCSIZE_PARAMS* sz = reinterpret_cast(lParam); - // on windows 10, if set to 0, there's a white line at the top - // of the app and I've yet to find a way to remove that. - sz->rgrc[0].top += IsWindows11OrGreater() ? 0 : 1; - // The following lines are required for resizing the window. - // https://github.com/leanflutter/window_manager/issues/483 - sz->rgrc[0].right -= 8; - sz->rgrc[0].bottom -= 8; - sz->rgrc[0].left -= -8; - } - - // Previously (WVR_HREDRAW | WVR_VREDRAW), but returning 0 or 1 doesn't - // actually break anything so I've set it to 0. Unless someone pointed a - // problem in the future. - return 0; - } - } else if (message == WM_NCHITTEST) { - if (!window_manager->is_resizable_) { - return HTNOWHERE; - } - } else if (message == WM_GETMINMAXINFO) { - MINMAXINFO* info = reinterpret_cast(lParam); - // For the special "unconstrained" values, leave the defaults. - if (window_manager->minimum_size_.x != 0) - info->ptMinTrackSize.x = static_cast( - window_manager->minimum_size_.x * window_manager->pixel_ratio_); - if (window_manager->minimum_size_.y != 0) - info->ptMinTrackSize.y = static_cast( - window_manager->minimum_size_.y * window_manager->pixel_ratio_); - if (window_manager->maximum_size_.x != -1) - info->ptMaxTrackSize.x = static_cast( - window_manager->maximum_size_.x * window_manager->pixel_ratio_); - if (window_manager->maximum_size_.y != -1) - info->ptMaxTrackSize.y = static_cast( - window_manager->maximum_size_.y * window_manager->pixel_ratio_); - result = 0; - } else if (message == WM_NCACTIVATE) { - if (wParam != 0) { - _EmitEvent("focus"); - } else { - _EmitEvent("blur"); - } - - if (window_manager->title_bar_style_ == "hidden" || - window_manager->is_frameless_) - return 1; - } else if (message == WM_EXITSIZEMOVE) { - if (window_manager->is_resizing_) { - _EmitEvent("resized"); - window_manager->is_resizing_ = false; - } - if (window_manager->is_moving_) { - _EmitEvent("moved"); - window_manager->is_moving_ = false; - } - return false; - } else if (message == WM_MOVING) { - window_manager->is_moving_ = true; - _EmitEvent("move"); - return false; - } else if (message == WM_SIZING) { - window_manager->is_resizing_ = true; - _EmitEvent("resize"); - - if (window_manager->aspect_ratio_ > 0) { - RECT* rect = (LPRECT)lParam; - - double aspect_ratio = window_manager->aspect_ratio_; - - int new_width = static_cast(rect->right - rect->left); - int new_height = static_cast(rect->bottom - rect->top); - - bool is_resizing_horizontally = - wParam == WMSZ_LEFT || wParam == WMSZ_RIGHT || - wParam == WMSZ_TOPLEFT || wParam == WMSZ_BOTTOMLEFT; - - if (is_resizing_horizontally) { - new_height = static_cast(new_width / aspect_ratio); - } else { - new_width = static_cast(new_height * aspect_ratio); - } - - int left = rect->left; - int top = rect->top; - int right = rect->right; - int bottom = rect->bottom; - - switch (wParam) { - case WMSZ_RIGHT: - case WMSZ_BOTTOM: - right = new_width + left; - bottom = top + new_height; - break; - case WMSZ_TOP: - right = new_width + left; - top = bottom - new_height; - break; - case WMSZ_LEFT: - case WMSZ_TOPLEFT: - left = right - new_width; - top = bottom - new_height; - break; - case WMSZ_TOPRIGHT: - right = left + new_width; - top = bottom - new_height; - break; - case WMSZ_BOTTOMLEFT: - left = right - new_width; - bottom = top + new_height; - break; - case WMSZ_BOTTOMRIGHT: - right = left + new_width; - bottom = top + new_height; - break; - } - - rect->left = left; - rect->top = top; - rect->right = right; - rect->bottom = bottom; - } - } else if (message == WM_SIZE) { - if (window_manager->IsFullScreen() && wParam == SIZE_MAXIMIZED && - window_manager->last_state != STATE_FULLSCREEN_ENTERED) { - _EmitEvent("enter-full-screen"); - window_manager->last_state = STATE_FULLSCREEN_ENTERED; - } else if (!window_manager->IsFullScreen() && wParam == SIZE_RESTORED && - window_manager->last_state == STATE_FULLSCREEN_ENTERED) { - window_manager->ForceChildRefresh(); - _EmitEvent("leave-full-screen"); - window_manager->last_state = STATE_NORMAL; - } else if (window_manager->last_state != STATE_FULLSCREEN_ENTERED) { - if (wParam == SIZE_MAXIMIZED) { - _EmitEvent("maximize"); - window_manager->last_state = STATE_MAXIMIZED; - } else if (wParam == SIZE_MINIMIZED) { - _EmitEvent("minimize"); - window_manager->last_state = STATE_MINIMIZED; - return 0; - } else if (wParam == SIZE_RESTORED) { - if (window_manager->last_state == STATE_MAXIMIZED) { - _EmitEvent("unmaximize"); - window_manager->last_state = STATE_NORMAL; - } else if (window_manager->last_state == STATE_MINIMIZED) { - _EmitEvent("restore"); - window_manager->last_state = STATE_NORMAL; - } - } - } - } else if (message == WM_CLOSE) { - _EmitEvent("close"); - if (window_manager->IsPreventClose()) { - return -1; - } - } else if (message == WM_SHOWWINDOW) { - if (wParam == TRUE) { - _EmitEvent("show"); - } else { - _EmitEvent("hide"); - } - } else if (message == WM_WINDOWPOSCHANGED) { - if (window_manager->IsAlwaysOnBottom()) { - const flutter::EncodableMap& args = { - {flutter::EncodableValue("isAlwaysOnBottom"), - flutter::EncodableValue(true)}}; - window_manager->SetAlwaysOnBottom(args); - } - } - - return result; -} - -void WindowManagerPlugin::HandleMethodCall( - const flutter::MethodCall& method_call, - std::unique_ptr> result) { - std::string method_name = method_call.method_name(); - - if (method_name.compare("ensureInitialized") == 0) { - window_manager->native_window = - ::GetAncestor(registrar->GetView()->GetNativeWindow(), GA_ROOT); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("waitUntilReadyToShow") == 0) { - window_manager->WaitUntilReadyToShow(); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("setAsFrameless") == 0) { - window_manager->SetAsFrameless(); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("destroy") == 0) { - window_manager->Destroy(); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("close") == 0) { - window_manager->Close(); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("isPreventClose") == 0) { - auto value = window_manager->IsPreventClose(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("setPreventClose") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetPreventClose(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("focus") == 0) { - window_manager->Focus(); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("blur") == 0) { - window_manager->Blur(); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("isFocused") == 0) { - bool value = window_manager->IsFocused(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("show") == 0) { - window_manager->Show(); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("hide") == 0) { - window_manager->Hide(); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("isVisible") == 0) { - bool value = window_manager->IsVisible(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("isMaximized") == 0) { - bool value = window_manager->IsMaximized(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("maximize") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->Maximize(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("unmaximize") == 0) { - window_manager->Unmaximize(); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("isMinimized") == 0) { - bool value = window_manager->IsMinimized(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("minimize") == 0) { - window_manager->Minimize(); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("restore") == 0) { - window_manager->Restore(); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("isDockable") == 0) { - bool value = window_manager->IsDockable(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("isDocked") == 0) { - int value = window_manager->IsDocked(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("dock") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->Dock(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("undock") == 0) { - bool value = window_manager->Undock(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("isFullScreen") == 0) { - bool value = window_manager->IsFullScreen(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("setFullScreen") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetFullScreen(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("setAspectRatio") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetAspectRatio(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("setBackgroundColor") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetBackgroundColor(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("getBounds") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - flutter::EncodableMap value = window_manager->GetBounds(args); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("setBounds") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetBounds(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("setMinimumSize") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetMinimumSize(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("setMaximumSize") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetMaximumSize(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("isResizable") == 0) { - bool value = window_manager->IsResizable(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("setResizable") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetResizable(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("isMinimizable") == 0) { - bool value = window_manager->IsMinimizable(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("setMinimizable") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetMinimizable(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("isMaximizable") == 0) { - bool value = window_manager->IsMaximizable(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("setMaximizable") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetMaximizable(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("isClosable") == 0) { - bool value = window_manager->IsClosable(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("setClosable") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetClosable(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("isAlwaysOnTop") == 0) { - bool value = window_manager->IsAlwaysOnTop(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("setAlwaysOnTop") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetAlwaysOnTop(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("isAlwaysOnBottom") == 0) { - bool value = window_manager->IsAlwaysOnBottom(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("setAlwaysOnBottom") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetAlwaysOnBottom(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("getTitle") == 0) { - std::string value = window_manager->GetTitle(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("setTitle") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetTitle(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("setTitleBarStyle") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetTitleBarStyle(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("getTitleBarHeight") == 0) { - int value = window_manager->GetTitleBarHeight(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("isSkipTaskbar") == 0) { - bool value = window_manager->IsSkipTaskbar(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("setSkipTaskbar") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetSkipTaskbar(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("setProgressBar") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetProgressBar(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("setIcon") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetIcon(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("hasShadow") == 0) { - bool value = window_manager->HasShadow(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("setHasShadow") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetHasShadow(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("getOpacity") == 0) { - double value = window_manager->GetOpacity(); - result->Success(flutter::EncodableValue(value)); - } else if (method_name.compare("setOpacity") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetOpacity(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("setBrightness") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetBrightness(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("setIgnoreMouseEvents") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->SetIgnoreMouseEvents(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("popUpWindowMenu") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->PopUpWindowMenu(args); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("startDragging") == 0) { - window_manager->StartDragging(); - result->Success(flutter::EncodableValue(true)); - } else if (method_name.compare("startResizing") == 0) { - const flutter::EncodableMap& args = - std::get(*method_call.arguments()); - window_manager->StartResizing(args); - result->Success(flutter::EncodableValue(true)); - } else { - result->NotImplemented(); - } -} - -} // namespace - -void WindowManagerPluginRegisterWithRegistrar( - FlutterDesktopPluginRegistrarRef registrar) { - WindowManagerPlugin::RegisterWithRegistrar( - flutter::PluginRegistrarManager::GetInstance() - ->GetRegistrar(registrar)); -} +#include "include/window_manager/window_manager_plugin.h" + +// This must be included before many other Windows headers. +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "window_manager.cpp" + +namespace { + +bool IsWindows11OrGreater() { + DWORD dwVersion = 0; + DWORD dwBuild = 0; + +#pragma warning(push) +#pragma warning(disable : 4996) + dwVersion = GetVersion(); + // Get the build number. + if (dwVersion < 0x80000000) + dwBuild = (DWORD)(HIWORD(dwVersion)); +#pragma warning(pop) + + return dwBuild < 22000; +} + +std::unique_ptr< + flutter::MethodChannel, + std::default_delete>> + channel = nullptr; + +class WindowManagerPlugin : public flutter::Plugin { + public: + static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar); + + WindowManagerPlugin(flutter::PluginRegistrarWindows* registrar); + + virtual ~WindowManagerPlugin(); + + private: + WindowManager* window_manager; + flutter::PluginRegistrarWindows* registrar; + + // The ID of the WindowProc delegate registration. + int window_proc_id = -1; + + void WindowManagerPlugin::_EmitEvent(std::string eventName); + // Called for top-level WindowProc delegation. + std::optional WindowManagerPlugin::HandleWindowProc(HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam); + // Called when a method is called on this plugin's channel from Dart. + void HandleMethodCall( + const flutter::MethodCall& method_call, + std::unique_ptr> result); + + void adjustNCCALCSIZE(HWND hwnd, NCCALCSIZE_PARAMS* sz) { + LONG l = 8; + LONG t = 8; + + // HMONITOR monitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + // Don't use `MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST)` above. + // Because if the window is restored from minimized state, the window is not in the correct monitor. + // The monitor is always the left-most monitor. + // https://github.com/leanflutter/window_manager/issues/489 + HMONITOR monitor = MonitorFromRect(&sz->rgrc[0], MONITOR_DEFAULTTONEAREST); + if (monitor != NULL) { + MONITORINFO monitorInfo; + monitorInfo.cbSize = sizeof(MONITORINFO); + if (TRUE == GetMonitorInfo(monitor, &monitorInfo)) { + l = sz->rgrc[0].left - monitorInfo.rcWork.left; + t = sz->rgrc[0].top - monitorInfo.rcWork.top; + } else { + // GetMonitorInfo failed, use (8, 8) as default value + } + } else { + // unreachable code + } + + sz->rgrc[0].left -= l; + sz->rgrc[0].top -= t; + sz->rgrc[0].right += l; + sz->rgrc[0].bottom += t; + } +}; + +// static +void WindowManagerPlugin::RegisterWithRegistrar( + flutter::PluginRegistrarWindows* registrar) { + channel = std::make_unique>( + registrar->messenger(), "window_manager", + &flutter::StandardMethodCodec::GetInstance()); + + auto plugin = std::make_unique(registrar); + + channel->SetMethodCallHandler( + [plugin_pointer = plugin.get()](const auto& call, auto result) { + plugin_pointer->HandleMethodCall(call, std::move(result)); + }); + + registrar->AddPlugin(std::move(plugin)); +} + +WindowManagerPlugin::WindowManagerPlugin( + flutter::PluginRegistrarWindows* registrar) + : registrar(registrar) { + window_manager = new WindowManager(); + window_proc_id = registrar->RegisterTopLevelWindowProcDelegate( + [this](HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { + return HandleWindowProc(hWnd, message, wParam, lParam); + }); +} + +WindowManagerPlugin::~WindowManagerPlugin() { + registrar->UnregisterTopLevelWindowProcDelegate(window_proc_id); + channel = nullptr; +} + +void WindowManagerPlugin::_EmitEvent(std::string eventName) { + if (channel == nullptr) + return; + flutter::EncodableMap args = flutter::EncodableMap(); + args[flutter::EncodableValue("eventName")] = + flutter::EncodableValue(eventName); + channel->InvokeMethod("onEvent", + std::make_unique(args)); +} + +std::optional WindowManagerPlugin::HandleWindowProc(HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam) { + std::optional result = std::nullopt; + + if (message == WM_DPICHANGED) { + window_manager->pixel_ratio_ = + (float)LOWORD(wParam) / USER_DEFAULT_SCREEN_DPI; + window_manager->ForceChildRefresh(); + } + + if (wParam && message == WM_NCCALCSIZE) { + if (window_manager->IsFullScreen() && + window_manager->title_bar_style_ != "normal") { + if (window_manager->is_frameless_) { + adjustNCCALCSIZE(hWnd, reinterpret_cast(lParam)); + } + return 0; + } + // This must always be before handling title_bar_style_ == "hidden" so + // the `if TitleBarStyle.hidden` doesn't get executed. + if (window_manager->is_frameless_) { + if (window_manager->IsMaximized()) { + adjustNCCALCSIZE(hWnd, reinterpret_cast(lParam)); + } + return 0; + } + + // This must always be last. + if (wParam && window_manager->title_bar_style_ == "hidden") { + if (window_manager->IsMaximized()) { + // Adjust the borders when maximized so the app isn't cut off + adjustNCCALCSIZE(hWnd, reinterpret_cast(lParam)); + } else { + NCCALCSIZE_PARAMS* sz = reinterpret_cast(lParam); + // on windows 10, if set to 0, there's a white line at the top + // of the app and I've yet to find a way to remove that. + sz->rgrc[0].top += IsWindows11OrGreater() ? 0 : 1; + // The following lines are required for resizing the window. + // https://github.com/leanflutter/window_manager/issues/483 + sz->rgrc[0].right -= 8; + sz->rgrc[0].bottom -= 8; + sz->rgrc[0].left -= -8; + } + + // Previously (WVR_HREDRAW | WVR_VREDRAW), but returning 0 or 1 doesn't + // actually break anything so I've set it to 0. Unless someone pointed a + // problem in the future. + return 0; + } + } else if (message == WM_NCHITTEST) { + if (!window_manager->is_resizable_) { + return HTNOWHERE; + } + } else if (message == WM_GETMINMAXINFO) { + MINMAXINFO* info = reinterpret_cast(lParam); + // For the special "unconstrained" values, leave the defaults. + if (window_manager->minimum_size_.x != 0) + info->ptMinTrackSize.x = static_cast( + window_manager->minimum_size_.x * window_manager->pixel_ratio_); + if (window_manager->minimum_size_.y != 0) + info->ptMinTrackSize.y = static_cast( + window_manager->minimum_size_.y * window_manager->pixel_ratio_); + if (window_manager->maximum_size_.x != -1) + info->ptMaxTrackSize.x = static_cast( + window_manager->maximum_size_.x * window_manager->pixel_ratio_); + if (window_manager->maximum_size_.y != -1) + info->ptMaxTrackSize.y = static_cast( + window_manager->maximum_size_.y * window_manager->pixel_ratio_); + result = 0; + } else if (message == WM_NCACTIVATE) { + if (wParam != 0) { + _EmitEvent("focus"); + } else { + _EmitEvent("blur"); + } + + if (window_manager->title_bar_style_ == "hidden" || + window_manager->is_frameless_) + return 1; + } else if (message == WM_EXITSIZEMOVE) { + if (window_manager->is_resizing_) { + _EmitEvent("resized"); + window_manager->is_resizing_ = false; + } + if (window_manager->is_moving_) { + _EmitEvent("moved"); + window_manager->is_moving_ = false; + } + return false; + } else if (message == WM_MOVING) { + window_manager->is_moving_ = true; + _EmitEvent("move"); + return false; + } else if (message == WM_SIZING) { + window_manager->is_resizing_ = true; + _EmitEvent("resize"); + + if (window_manager->aspect_ratio_ > 0) { + RECT* rect = (LPRECT)lParam; + + double aspect_ratio = window_manager->aspect_ratio_; + + int new_width = static_cast(rect->right - rect->left); + int new_height = static_cast(rect->bottom - rect->top); + + bool is_resizing_horizontally = + wParam == WMSZ_LEFT || wParam == WMSZ_RIGHT || + wParam == WMSZ_TOPLEFT || wParam == WMSZ_BOTTOMLEFT; + + if (is_resizing_horizontally) { + new_height = static_cast(new_width / aspect_ratio); + } else { + new_width = static_cast(new_height * aspect_ratio); + } + + int left = rect->left; + int top = rect->top; + int right = rect->right; + int bottom = rect->bottom; + + switch (wParam) { + case WMSZ_RIGHT: + case WMSZ_BOTTOM: + right = new_width + left; + bottom = top + new_height; + break; + case WMSZ_TOP: + right = new_width + left; + top = bottom - new_height; + break; + case WMSZ_LEFT: + case WMSZ_TOPLEFT: + left = right - new_width; + top = bottom - new_height; + break; + case WMSZ_TOPRIGHT: + right = left + new_width; + top = bottom - new_height; + break; + case WMSZ_BOTTOMLEFT: + left = right - new_width; + bottom = top + new_height; + break; + case WMSZ_BOTTOMRIGHT: + right = left + new_width; + bottom = top + new_height; + break; + } + + rect->left = left; + rect->top = top; + rect->right = right; + rect->bottom = bottom; + } + } else if (message == WM_SIZE) { + if (window_manager->IsFullScreen() && wParam == SIZE_MAXIMIZED && + window_manager->last_state != STATE_FULLSCREEN_ENTERED) { + _EmitEvent("enter-full-screen"); + window_manager->last_state = STATE_FULLSCREEN_ENTERED; + } else if (!window_manager->IsFullScreen() && wParam == SIZE_RESTORED && + window_manager->last_state == STATE_FULLSCREEN_ENTERED) { + window_manager->ForceChildRefresh(); + _EmitEvent("leave-full-screen"); + window_manager->last_state = STATE_NORMAL; + } else if (window_manager->last_state != STATE_FULLSCREEN_ENTERED) { + if (wParam == SIZE_MAXIMIZED) { + _EmitEvent("maximize"); + window_manager->last_state = STATE_MAXIMIZED; + } else if (wParam == SIZE_MINIMIZED) { + _EmitEvent("minimize"); + window_manager->last_state = STATE_MINIMIZED; + return 0; + } else if (wParam == SIZE_RESTORED) { + if (window_manager->last_state == STATE_MAXIMIZED) { + _EmitEvent("unmaximize"); + window_manager->last_state = STATE_NORMAL; + } else if (window_manager->last_state == STATE_MINIMIZED) { + _EmitEvent("restore"); + window_manager->last_state = STATE_NORMAL; + } + } + } + } else if (message == WM_CLOSE) { + _EmitEvent("close"); + if (window_manager->IsPreventClose()) { + return -1; + } + } else if (message == WM_SHOWWINDOW) { + if (wParam == TRUE) { + _EmitEvent("show"); + } else { + _EmitEvent("hide"); + } + } else if (message == WM_WINDOWPOSCHANGED) { + if (window_manager->IsAlwaysOnBottom()) { + const flutter::EncodableMap& args = { + {flutter::EncodableValue("isAlwaysOnBottom"), + flutter::EncodableValue(true)}}; + window_manager->SetAlwaysOnBottom(args); + } + } + + return result; +} + +void WindowManagerPlugin::HandleMethodCall( + const flutter::MethodCall& method_call, + std::unique_ptr> result) { + std::string method_name = method_call.method_name(); + + if (method_name.compare("ensureInitialized") == 0) { + window_manager->native_window = + ::GetAncestor(registrar->GetView()->GetNativeWindow(), GA_ROOT); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("waitUntilReadyToShow") == 0) { + window_manager->WaitUntilReadyToShow(); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("setAsFrameless") == 0) { + window_manager->SetAsFrameless(); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("destroy") == 0) { + window_manager->Destroy(); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("close") == 0) { + window_manager->Close(); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("isPreventClose") == 0) { + auto value = window_manager->IsPreventClose(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("setPreventClose") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetPreventClose(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("focus") == 0) { + window_manager->Focus(); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("blur") == 0) { + window_manager->Blur(); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("isFocused") == 0) { + bool value = window_manager->IsFocused(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("show") == 0) { + window_manager->Show(); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("hide") == 0) { + window_manager->Hide(); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("isVisible") == 0) { + bool value = window_manager->IsVisible(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("isMaximized") == 0) { + bool value = window_manager->IsMaximized(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("maximize") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->Maximize(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("unmaximize") == 0) { + window_manager->Unmaximize(); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("isMinimized") == 0) { + bool value = window_manager->IsMinimized(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("minimize") == 0) { + window_manager->Minimize(); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("restore") == 0) { + window_manager->Restore(); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("isDockable") == 0) { + bool value = window_manager->IsDockable(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("isDocked") == 0) { + int value = window_manager->IsDocked(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("dock") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->Dock(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("undock") == 0) { + bool value = window_manager->Undock(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("isFullScreen") == 0) { + bool value = window_manager->IsFullScreen(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("setFullScreen") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetFullScreen(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("setAspectRatio") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetAspectRatio(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("setBackgroundColor") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetBackgroundColor(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("getBounds") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + flutter::EncodableMap value = window_manager->GetBounds(args); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("setBounds") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetBounds(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("setMinimumSize") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetMinimumSize(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("setMaximumSize") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetMaximumSize(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("isResizable") == 0) { + bool value = window_manager->IsResizable(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("setResizable") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetResizable(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("isMinimizable") == 0) { + bool value = window_manager->IsMinimizable(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("setMinimizable") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetMinimizable(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("isMaximizable") == 0) { + bool value = window_manager->IsMaximizable(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("setMaximizable") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetMaximizable(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("isClosable") == 0) { + bool value = window_manager->IsClosable(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("setClosable") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetClosable(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("isAlwaysOnTop") == 0) { + bool value = window_manager->IsAlwaysOnTop(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("setAlwaysOnTop") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetAlwaysOnTop(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("isAlwaysOnBottom") == 0) { + bool value = window_manager->IsAlwaysOnBottom(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("setAlwaysOnBottom") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetAlwaysOnBottom(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("getTitle") == 0) { + std::string value = window_manager->GetTitle(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("setTitle") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetTitle(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("setTitleBarStyle") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetTitleBarStyle(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("getTitleBarHeight") == 0) { + int value = window_manager->GetTitleBarHeight(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("isSkipTaskbar") == 0) { + bool value = window_manager->IsSkipTaskbar(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("setSkipTaskbar") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetSkipTaskbar(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("setProgressBar") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetProgressBar(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("setIcon") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetIcon(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("hasShadow") == 0) { + bool value = window_manager->HasShadow(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("setHasShadow") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetHasShadow(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("getOpacity") == 0) { + double value = window_manager->GetOpacity(); + result->Success(flutter::EncodableValue(value)); + } else if (method_name.compare("setOpacity") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetOpacity(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("setBrightness") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetBrightness(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("setIgnoreMouseEvents") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->SetIgnoreMouseEvents(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("popUpWindowMenu") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->PopUpWindowMenu(args); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("startDragging") == 0) { + window_manager->StartDragging(); + result->Success(flutter::EncodableValue(true)); + } else if (method_name.compare("startResizing") == 0) { + const flutter::EncodableMap& args = + std::get(*method_call.arguments()); + window_manager->StartResizing(args); + result->Success(flutter::EncodableValue(true)); + } else { + result->NotImplemented(); + } +} + +} // namespace + +void WindowManagerPluginRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar) { + WindowManagerPlugin::RegisterWithRegistrar( + flutter::PluginRegistrarManager::GetInstance() + ->GetRegistrar(registrar)); +} diff --git a/pubspec.lock b/pubspec.lock index 7ad2eb91..910c5e41 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,54 +1,62 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + ansi_styles: + dependency: transitive + description: + name: ansi_styles + sha256: "9c656cc12b3c27b17dd982b2cc5c0cfdfbdabd7bc8f3ae5e8542d9867b47ce8a" + url: "https://pub.dev" + source: hosted + version: "0.3.2+1" args: dependency: transitive description: name: args - sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" + sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6 url: "https://pub.dev" source: hosted - version: "2.5.0" + version: "2.6.0" async: dependency: transitive description: name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + sha256: d2872f9c19731c2e5f10444b14686eb7cc85c76274bd6c16e1816bff9a3bab63 url: "https://pub.dev" source: hosted - version: "2.11.0" + version: "2.12.0" boolean_selector: dependency: transitive description: name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" url: "https://pub.dev" source: hosted - version: "2.1.1" - build_config: + version: "2.1.2" + charcode: dependency: transitive description: - name: build_config - sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + name: charcode + sha256: fb98c0f6d12c920a02ee2d998da788bca066ca5f148492b7085ee23372b12306 url: "https://pub.dev" source: hosted - version: "1.1.1" - characters: + version: "1.3.1" + cli_launcher: dependency: transitive description: - name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + name: cli_launcher + sha256: "5e7e0282b79e8642edd6510ee468ae2976d847a0a29b3916e85f5fa1bfe24005" url: "https://pub.dev" source: hosted - version: "1.3.0" - checked_yaml: + version: "0.3.1" + cli_util: dependency: transitive description: - name: checked_yaml - sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff + name: cli_util + sha256: c05b7406fdabc7a49a3929d4af76bcaccbbffcbcdcf185b082e1ae07da323d19 url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "0.4.1" clock: dependency: transitive description: @@ -61,44 +69,26 @@ packages: dependency: transitive description: name: collection - sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a - url: "https://pub.dev" - source: hosted - version: "1.18.0" - dependency_validator: - dependency: "direct dev" - description: - name: dependency_validator - sha256: f727a5627aa405965fab4aef4f468e50a9b632ba0737fd2f98c932fec6d712b9 + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" url: "https://pub.dev" source: hosted - version: "3.2.3" - fake_async: + version: "1.19.1" + conventional_commit: dependency: transitive description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + name: conventional_commit + sha256: dec15ad1118f029c618651a4359eb9135d8b88f761aa24e4016d061cd45948f2 url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "0.6.0+1" file: dependency: transitive description: name: file - sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 url: "https://pub.dev" source: hosted - version: "7.0.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" + version: "7.0.1" glob: dependency: transitive description: @@ -107,6 +97,38 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + graphs: + dependency: transitive + description: + name: graphs + sha256: "741bbf84165310a68ff28fe9e727332eef1407342fca52759cb21ad8177bb8d0" + url: "https://pub.dev" + source: hosted + version: "2.3.2" + http: + dependency: transitive + description: + name: http + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 + url: "https://pub.dev" + source: hosted + version: "1.2.2" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "76d306a1c3afb33fe82e2bbacad62a61f409b5634c915fceb0d799de1a913360" + url: "https://pub.dev" + source: hosted + version: "4.1.1" + intl: + dependency: transitive + description: + name: intl + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + url: "https://pub.dev" + source: hosted + version: "0.19.0" io: dependency: transitive description: @@ -123,94 +145,78 @@ packages: url: "https://pub.dev" source: hosted version: "4.9.0" - leak_tracker: + matcher: dependency: transitive description: - name: leak_tracker - sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" + name: matcher + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "10.0.5" - leak_tracker_flutter_testing: - dependency: transitive + version: "0.12.17" + melos: + dependency: "direct dev" description: - name: leak_tracker_flutter_testing - sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" + name: melos + sha256: a62abfa8c7826cec927f8585572bb9adf591be152150494d879ca2c75118809d url: "https://pub.dev" source: hosted - version: "3.0.5" - leak_tracker_testing: + version: "6.2.0" + meta: dependency: transitive description: - name: leak_tracker_testing - sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" + name: meta + sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c url: "https://pub.dev" source: hosted - version: "3.0.1" - lints: + version: "1.16.0" + mustache_template: dependency: transitive description: - name: lints - sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" + name: mustache_template + sha256: a46e26f91445bfb0b60519be280555b06792460b27b19e2b19ad5b9740df5d1c url: "https://pub.dev" source: hosted - version: "4.0.0" - logging: + version: "2.0.0" + path: dependency: transitive description: - name: logging - sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" url: "https://pub.dev" source: hosted - version: "1.2.0" - matcher: + version: "1.9.1" + platform: dependency: transitive description: - name: matcher - sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" url: "https://pub.dev" source: hosted - version: "0.12.16+1" - material_color_utilities: + version: "3.1.6" + pool: dependency: transitive description: - name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + name: pool + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" url: "https://pub.dev" source: hosted - version: "0.11.1" - meta: + version: "1.5.1" + process: dependency: transitive description: - name: meta - sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 - url: "https://pub.dev" - source: hosted - version: "1.15.0" - mostly_reasonable_lints: - dependency: "direct dev" - description: - name: mostly_reasonable_lints - sha256: e19fec63536866ba307b3dfbc258b4bce9b3745129f038006b56b4067c6293d8 + name: process + sha256: "21e54fd2faf1b5bdd5102afd25012184a6793927648ea81eea80552ac9405b32" url: "https://pub.dev" source: hosted - version: "0.1.2" - package_config: + version: "5.0.2" + prompts: dependency: transitive description: - name: package_config - sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + name: prompts + sha256: "3773b845e85a849f01e793c4fc18a45d52d7783b4cb6c0569fad19f9d0a774a1" url: "https://pub.dev" source: hosted - version: "2.1.0" - path: - dependency: "direct main" - description: - name: path - sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" - url: "https://pub.dev" - source: hosted - version: "1.9.0" + version: "2.0.0" pub_semver: dependency: transitive description: @@ -219,27 +225,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - pubspec_parse: + pub_updater: dependency: transitive description: - name: pubspec_parse - sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 + name: pub_updater + sha256: "54e8dc865349059ebe7f163d6acce7c89eb958b8047e6d6e80ce93b13d7c9e60" url: "https://pub.dev" source: hosted - version: "1.2.3" - screen_retriever: - dependency: "direct main" + version: "0.4.0" + pubspec: + dependency: transitive description: - name: screen_retriever - sha256: "6ee02c8a1158e6dae7ca430da79436e3b1c9563c8cf02f524af997c201ac2b90" + name: pubspec + sha256: f534a50a2b4d48dc3bc0ec147c8bd7c304280fff23b153f3f11803c4d49d927e url: "https://pub.dev" source: hosted - version: "0.1.9" - sky_engine: + version: "2.3.0" + quiver: dependency: transitive - description: flutter - source: sdk - version: "0.0.99" + description: + name: quiver + sha256: ea0b925899e64ecdfbf9c7becb60d5b50e706ade44a85b2363be2a22d88117d2 + url: "https://pub.dev" + source: hosted + version: "3.2.2" source_span: dependency: transitive description: @@ -252,10 +261,10 @@ packages: dependency: transitive description: name: stack_trace - sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + sha256: "9f47fd3630d76be3ab26f0ee06d213679aa425996925ff3feffdec504931c377" url: "https://pub.dev" source: hosted - version: "1.11.1" + version: "1.12.0" stream_channel: dependency: transitive description: @@ -268,10 +277,10 @@ packages: dependency: transitive description: name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + sha256: "0bd04f5bb74fcd6ff0606a888a30e917af9bd52820b178eaa464beb11dca84b6" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.4.0" term_glyph: dependency: transitive description: @@ -284,26 +293,34 @@ packages: dependency: transitive description: name: test_api - sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" + sha256: "664d3a9a64782fcdeb83ce9c6b39e78fd2971d4e37827b9b06c3aa1edc5e760c" url: "https://pub.dev" source: hosted - version: "0.7.2" - vector_math: + version: "0.7.3" + typed_data: dependency: transitive description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 url: "https://pub.dev" source: hosted - version: "2.1.4" - vm_service: + version: "1.4.0" + uri: dependency: transitive description: - name: vm_service - sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" + name: uri + sha256: "889eea21e953187c6099802b7b4cf5219ba8f3518f604a1033064d45b1b8268a" url: "https://pub.dev" source: hosted - version: "14.2.5" + version: "1.0.0" + web: + dependency: transitive + description: + name: web + sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb + url: "https://pub.dev" + source: hosted + version: "1.1.0" yaml: dependency: transitive description: @@ -312,6 +329,13 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.2" + yaml_edit: + dependency: transitive + description: + name: yaml_edit + sha256: e9c1a3543d2da0db3e90270dbb1e4eebc985ee5e3ffe468d83224472b2194a5f + url: "https://pub.dev" + source: hosted + version: "2.2.1" sdks: - dart: ">=3.3.0 <4.0.0" - flutter: ">=3.18.0-18.0.pre.54" + dart: ">=3.5.0 <4.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 9cdb4391..7b9be4ff 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,42 +1,9 @@ -name: window_manager -description: This plugin allows Flutter desktop apps to resizing and repositioning the window. -version: 0.4.2 +name: window_manager_workspace homepage: https://github.com/leanflutter/window_manager - -platforms: - linux: - macos: - windows: - -topics: - - window - - window-resize - - window-manager - - desktop - - desktop-window +publish_to: none environment: sdk: ">=3.0.0 <4.0.0" - flutter: ">=3.3.0" - -dependencies: - flutter: - sdk: flutter - path: ^1.8.2 - screen_retriever: ^0.1.9 dev_dependencies: - dependency_validator: ^3.0.0 - flutter_test: - sdk: flutter - mostly_reasonable_lints: ^0.1.2 - -flutter: - plugin: - platforms: - linux: - pluginClass: WindowManagerPlugin - macos: - pluginClass: WindowManagerPlugin - windows: - pluginClass: WindowManagerPlugin + melos: ^6.2.0