diff --git a/packages/device_info_plus/device_info_plus/README.md b/packages/device_info_plus/device_info_plus/README.md index cc10daefc7..739faa4a80 100644 --- a/packages/device_info_plus/device_info_plus/README.md +++ b/packages/device_info_plus/device_info_plus/README.md @@ -16,10 +16,10 @@ Get current device information from within the Flutter application. ## Requirements -- Flutter >=3.29.0 -- Dart >=3.7.0 <4.0.0 -- iOS >=12.0 -- macOS >=10.14 +- Flutter >=3.41.0 +- Dart >=3.11.0 <4.0.0 +- iOS >=13.0 +- macOS >=10.15 - Java 17 - Kotlin 2.2.0 - Android Gradle Plugin >=8.12.1 diff --git a/packages/device_info_plus/device_info_plus/example/.metadata b/packages/device_info_plus/device_info_plus/example/.metadata deleted file mode 100644 index 911b6b722d..0000000000 --- a/packages/device_info_plus/device_info_plus/example/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# This file tracks properties of this Flutter project. -# Used by Flutter tool to assess capabilities and perform upgrades etc. -# -# This file should be version controlled and should not be manually edited. - -version: - revision: 81a45ec2e5f80fa71d5135f1702ce540558b416d - channel: beta - -project_type: app diff --git a/packages/device_info_plus/device_info_plus/example/ios/Flutter/AppFrameworkInfo.plist b/packages/device_info_plus/device_info_plus/example/ios/Flutter/AppFrameworkInfo.plist index 8c6e56146e..ab8e063fe8 100644 --- a/packages/device_info_plus/device_info_plus/example/ios/Flutter/AppFrameworkInfo.plist +++ b/packages/device_info_plus/device_info_plus/example/ios/Flutter/AppFrameworkInfo.plist @@ -20,7 +20,5 @@ ???? CFBundleVersion 1.0 - MinimumOSVersion - 12.0 diff --git a/packages/device_info_plus/device_info_plus/example/ios/Runner.xcodeproj/project.pbxproj b/packages/device_info_plus/device_info_plus/example/ios/Runner.xcodeproj/project.pbxproj index 075d8eecde..e52dbe9053 100644 --- a/packages/device_info_plus/device_info_plus/example/ios/Runner.xcodeproj/project.pbxproj +++ b/packages/device_info_plus/device_info_plus/example/ios/Runner.xcodeproj/project.pbxproj @@ -451,7 +451,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -469,7 +469,7 @@ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -579,7 +579,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -628,7 +628,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -648,7 +648,7 @@ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -671,7 +671,7 @@ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/packages/device_info_plus/device_info_plus/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/packages/device_info_plus/device_info_plus/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 8e3ca5dfe1..e3773d42e2 100644 --- a/packages/device_info_plus/device_info_plus/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/packages/device_info_plus/device_info_plus/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -26,6 +26,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit" shouldUseLaunchSchemeArgsEnv = "YES"> diff --git a/packages/device_info_plus/device_info_plus/example/ios/Runner/AppDelegate.swift b/packages/device_info_plus/device_info_plus/example/ios/Runner/AppDelegate.swift index b636303481..c30b367ec0 100644 --- a/packages/device_info_plus/device_info_plus/example/ios/Runner/AppDelegate.swift +++ b/packages/device_info_plus/device_info_plus/example/ios/Runner/AppDelegate.swift @@ -1,13 +1,16 @@ -import UIKit import Flutter +import UIKit @main -@objc class AppDelegate: FlutterAppDelegate { +@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { - GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } + + func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { + GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) + } } diff --git a/packages/device_info_plus/device_info_plus/example/ios/Runner/Info.plist b/packages/device_info_plus/device_info_plus/example/ios/Runner/Info.plist index c30f9332f1..2bc6a54b47 100644 --- a/packages/device_info_plus/device_info_plus/example/ios/Runner/Info.plist +++ b/packages/device_info_plus/device_info_plus/example/ios/Runner/Info.plist @@ -26,6 +26,27 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneClassName + UIWindowScene + UISceneConfigurationName + flutter + UISceneDelegateClassName + FlutterSceneDelegate + UISceneStoryboardFile + Main + + + + UIApplicationSupportsIndirectInputEvents UILaunchStoryboardName diff --git a/packages/device_info_plus/device_info_plus/example/pubspec.yaml b/packages/device_info_plus/device_info_plus/example/pubspec.yaml index ae6911c419..b99543ed16 100644 --- a/packages/device_info_plus/device_info_plus/example/pubspec.yaml +++ b/packages/device_info_plus/device_info_plus/example/pubspec.yaml @@ -13,13 +13,13 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - flutter_lints: ">=4.0.0 <6.0.0" + flutter_lints: ^6.0.0 flutter: uses-material-design: true environment: - sdk: '>=3.7.0 <4.0.0' - flutter: '>=3.29.0' + sdk: '>=3.11.0 <4.0.0' + flutter: '>=3.41.0' diff --git a/packages/device_info_plus/device_info_plus/example/windows/CMakeLists.txt b/packages/device_info_plus/device_info_plus/example/windows/CMakeLists.txt index abf90408ef..13aa15d2a2 100644 --- a/packages/device_info_plus/device_info_plus/example/windows/CMakeLists.txt +++ b/packages/device_info_plus/device_info_plus/example/windows/CMakeLists.txt @@ -1,13 +1,16 @@ -cmake_minimum_required(VERSION 3.15) -project(example LANGUAGES CXX) +# Project-level configuration. +cmake_minimum_required(VERSION 3.14) +project(device_info_plus_example LANGUAGES CXX) -set(BINARY_NAME "example") +# The name of the executable created for the application. Change this to change +# the on-disk name of your application. +set(BINARY_NAME "device_info_plus_example") -cmake_policy(SET CMP0063 NEW) +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent +# versions of CMake. +cmake_policy(VERSION 3.14...3.25) -set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") - -# Configure build options. +# Define build configuration option. get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) if(IS_MULTICONFIG) set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" @@ -20,7 +23,7 @@ else() "Debug" "Profile" "Release") endif() endif() - +# Define settings for the Profile build mode. set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") @@ -30,6 +33,10 @@ set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") add_definitions(-DUNICODE -D_UNICODE) # Compilation settings that should be applied to most targets. +# +# Be cautious about adding new options here, as plugins use this function by +# default. In most cases, you should add new options to specific targets instead +# of modifying this function. function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_17) target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") @@ -38,14 +45,14 @@ function(APPLY_STANDARD_SETTINGS TARGET) target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") endfunction() -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") - # Flutter library and tool build rules. +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") add_subdirectory(${FLUTTER_MANAGED_DIR}) -# Application build +# Application build; see runner/CMakeLists.txt. add_subdirectory("runner") + # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) @@ -80,6 +87,12 @@ if(PLUGIN_BUNDLED_LIBRARIES) COMPONENT Runtime) endif() +# Copy the native assets provided by the build.dart from all packages. +set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") +install(DIRECTORY "${NATIVE_ASSETS_DIR}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + # 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") diff --git a/packages/device_info_plus/device_info_plus/example/windows/flutter/CMakeLists.txt b/packages/device_info_plus/device_info_plus/example/windows/flutter/CMakeLists.txt index b02c5485c9..903f4899d6 100644 --- a/packages/device_info_plus/device_info_plus/example/windows/flutter/CMakeLists.txt +++ b/packages/device_info_plus/device_info_plus/example/windows/flutter/CMakeLists.txt @@ -1,4 +1,5 @@ -cmake_minimum_required(VERSION 3.15) +# This file controls Flutter-level build steps. It should not be edited. +cmake_minimum_required(VERSION 3.14) set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") @@ -9,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake) # 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") @@ -91,7 +97,7 @@ add_custom_command( COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" - windows-x64 $ + ${FLUTTER_TARGET_PLATFORM} $ VERBATIM ) add_custom_target(flutter_assemble DEPENDS diff --git a/packages/device_info_plus/device_info_plus/example/windows/runner/CMakeLists.txt b/packages/device_info_plus/device_info_plus/example/windows/runner/CMakeLists.txt index 977e38b5d1..394917c053 100644 --- a/packages/device_info_plus/device_info_plus/example/windows/runner/CMakeLists.txt +++ b/packages/device_info_plus/device_info_plus/example/windows/runner/CMakeLists.txt @@ -1,18 +1,40 @@ -cmake_minimum_required(VERSION 3.15) +cmake_minimum_required(VERSION 3.14) project(runner LANGUAGES CXX) +# Define the application target. To change its name, change BINARY_NAME in the +# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer +# work. +# +# Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} WIN32 "flutter_window.cpp" "main.cpp" - "run_loop.cpp" "utils.cpp" "win32_window.cpp" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" "Runner.rc" "runner.exe.manifest" ) + +# Apply the standard set of build settings. This can be removed for applications +# that need different build settings. apply_standard_settings(${BINARY_NAME}) + +# Add preprocessor definitions for the build version. +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") +target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") + +# Disable Windows macros that collide with C++ standard library functions. target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") + +# Add dependency libraries and include directories. Add any application-specific +# dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") + +# Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/packages/device_info_plus/device_info_plus/example/windows/runner/Runner.rc b/packages/device_info_plus/device_info_plus/example/windows/runner/Runner.rc index 13f98c0aef..7dfc972eb4 100644 --- a/packages/device_info_plus/device_info_plus/example/windows/runner/Runner.rc +++ b/packages/device_info_plus/device_info_plus/example/windows/runner/Runner.rc @@ -60,14 +60,14 @@ IDI_APP_ICON ICON "resources\\app_icon.ico" // Version // -#ifdef FLUTTER_BUILD_NUMBER -#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER +#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 +#define VERSION_AS_NUMBER 1,0,0,0 #endif -#ifdef FLUTTER_BUILD_NAME -#define VERSION_AS_STRING #FLUTTER_BUILD_NAME +#if defined(FLUTTER_VERSION) +#define VERSION_AS_STRING FLUTTER_VERSION #else #define VERSION_AS_STRING "1.0.0" #endif @@ -90,12 +90,12 @@ BEGIN BLOCK "040904e4" BEGIN VALUE "CompanyName", "io.flutter.plugins.deviceinfoexample" "\0" - VALUE "FileDescription", "A new Flutter project." "\0" + VALUE "FileDescription", "device_info_plus_example" "\0" VALUE "FileVersion", VERSION_AS_STRING "\0" - VALUE "InternalName", "example" "\0" - VALUE "LegalCopyright", "Copyright (C) 2021 io.flutter.plugins.deviceinfoexample. All rights reserved." "\0" - VALUE "OriginalFilename", "example.exe" "\0" - VALUE "ProductName", "example" "\0" + VALUE "InternalName", "device_info_plus_example" "\0" + VALUE "LegalCopyright", "Copyright (C) 2026 io.flutter.plugins.deviceinfoexample. All rights reserved." "\0" + VALUE "OriginalFilename", "device_info_plus_example.exe" "\0" + VALUE "ProductName", "device_info_plus_example" "\0" VALUE "ProductVersion", VERSION_AS_STRING "\0" END END diff --git a/packages/device_info_plus/device_info_plus/example/windows/runner/flutter_window.cpp b/packages/device_info_plus/device_info_plus/example/windows/runner/flutter_window.cpp index 0f0105d995..955ee3038f 100644 --- a/packages/device_info_plus/device_info_plus/example/windows/runner/flutter_window.cpp +++ b/packages/device_info_plus/device_info_plus/example/windows/runner/flutter_window.cpp @@ -4,9 +4,8 @@ #include "flutter/generated_plugin_registrant.h" -FlutterWindow::FlutterWindow(RunLoop *run_loop, - const flutter::DartProject &project) - : run_loop_(run_loop), project_(project) {} +FlutterWindow::FlutterWindow(const flutter::DartProject& project) + : project_(project) {} FlutterWindow::~FlutterWindow() {} @@ -26,14 +25,22 @@ bool FlutterWindow::OnCreate() { return false; } RegisterPlugins(flutter_controller_->engine()); - run_loop_->RegisterFlutterInstance(flutter_controller_->engine()); SetChildContent(flutter_controller_->view()->GetNativeWindow()); + + flutter_controller_->engine()->SetNextFrameCallback([&]() { + this->Show(); + }); + + // Flutter can complete the first frame before the "show window" callback is + // registered. The following call ensures a frame is pending to ensure the + // window is shown. It is a no-op if the first frame hasn't completed yet. + flutter_controller_->ForceRedraw(); + return true; } void FlutterWindow::OnDestroy() { if (flutter_controller_) { - run_loop_->UnregisterFlutterInstance(flutter_controller_->engine()); flutter_controller_ = nullptr; } @@ -44,7 +51,7 @@ LRESULT FlutterWindow::MessageHandler(HWND hwnd, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept { - // Give Flutter, including plugins, an opporutunity to handle window messages. + // Give Flutter, including plugins, an opportunity to handle window messages. if (flutter_controller_) { std::optional result = flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, @@ -55,9 +62,9 @@ FlutterWindow::MessageHandler(HWND hwnd, UINT const message, } switch (message) { - case WM_FONTCHANGE: - flutter_controller_->engine()->ReloadSystemFonts(); - break; + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; } return Win32Window::MessageHandler(hwnd, message, wparam, lparam); diff --git a/packages/device_info_plus/device_info_plus/example/windows/runner/flutter_window.h b/packages/device_info_plus/device_info_plus/example/windows/runner/flutter_window.h index 69234d4f5e..6da0652f05 100644 --- a/packages/device_info_plus/device_info_plus/example/windows/runner/flutter_window.h +++ b/packages/device_info_plus/device_info_plus/example/windows/runner/flutter_window.h @@ -6,29 +6,23 @@ #include -#include "run_loop.h" #include "win32_window.h" // A window that does nothing but host a Flutter view. class FlutterWindow : public Win32Window { -public: - // Creates a new FlutterWindow driven by the |run_loop|, hosting a - // Flutter view running |project|. - explicit FlutterWindow(RunLoop *run_loop, - const flutter::DartProject &project); + public: + // Creates a new FlutterWindow hosting a Flutter view running |project|. + explicit FlutterWindow(const flutter::DartProject& project); virtual ~FlutterWindow(); -protected: + 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 run loop driving events for this window. - RunLoop *run_loop_; - + private: // The project to run. flutter::DartProject project_; @@ -36,4 +30,4 @@ class FlutterWindow : public Win32Window { std::unique_ptr flutter_controller_; }; -#endif // RUNNER_FLUTTER_WINDOW_H_ +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/packages/device_info_plus/device_info_plus/example/windows/runner/main.cpp b/packages/device_info_plus/device_info_plus/example/windows/runner/main.cpp index 098956860e..4502701479 100644 --- a/packages/device_info_plus/device_info_plus/example/windows/runner/main.cpp +++ b/packages/device_info_plus/device_info_plus/example/windows/runner/main.cpp @@ -3,7 +3,6 @@ #include #include "flutter_window.h" -#include "run_loop.h" #include "utils.h" int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, @@ -18,23 +17,26 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, // plugins. ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); - RunLoop run_loop; - flutter::DartProject project(L"data"); - std::vector command_line_arguments = GetCommandLineArguments(); + std::vector command_line_arguments = + GetCommandLineArguments(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - FlutterWindow window(&run_loop, project); + FlutterWindow window(project); Win32Window::Point origin(10, 10); Win32Window::Size size(1280, 720); - if (!window.CreateAndShow(L"example", origin, size)) { + if (!window.Create(L"device_info_plus_example", origin, size)) { return EXIT_FAILURE; } window.SetQuitOnClose(true); - run_loop.Run(); + ::MSG msg; + while (::GetMessage(&msg, nullptr, 0, 0)) { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } ::CoUninitialize(); return EXIT_SUCCESS; diff --git a/packages/device_info_plus/device_info_plus/example/windows/runner/resource.h b/packages/device_info_plus/device_info_plus/example/windows/runner/resource.h index d5d958dc42..66a65d1e4a 100644 --- a/packages/device_info_plus/device_info_plus/example/windows/runner/resource.h +++ b/packages/device_info_plus/device_info_plus/example/windows/runner/resource.h @@ -2,15 +2,15 @@ // Microsoft Visual C++ generated include file. // Used by Runner.rc // -#define IDI_APP_ICON 101 +#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 +#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/packages/device_info_plus/device_info_plus/example/windows/runner/run_loop.cpp b/packages/device_info_plus/device_info_plus/example/windows/runner/run_loop.cpp deleted file mode 100644 index 31b89f6229..0000000000 --- a/packages/device_info_plus/device_info_plus/example/windows/runner/run_loop.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "run_loop.h" - -#include - -#include - -RunLoop::RunLoop() {} - -RunLoop::~RunLoop() {} - -void RunLoop::Run() { - bool keep_running = true; - TimePoint next_flutter_event_time = TimePoint::clock::now(); - while (keep_running) { - std::chrono::nanoseconds wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - TimePoint::clock::now()); - ::MsgWaitForMultipleObjects( - 0, nullptr, FALSE, static_cast(wait_duration.count() / 1000), - QS_ALLINPUT); - bool processed_events = false; - MSG message; - // All pending Windows messages must be processed; MsgWaitForMultipleObjects - // won't return again for items left in the queue after PeekMessage. - while (::PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) { - processed_events = true; - if (message.message == WM_QUIT) { - keep_running = false; - break; - } - ::TranslateMessage(&message); - ::DispatchMessage(&message); - // Allow Flutter to process messages each time a Windows message is - // processed, to prevent starvation. - next_flutter_event_time = - std::min(next_flutter_event_time, ProcessFlutterMessages()); - } - // If the PeekMessage loop didn't run, process Flutter messages. - if (!processed_events) { - next_flutter_event_time = - std::min(next_flutter_event_time, ProcessFlutterMessages()); - } - } -} - -void RunLoop::RegisterFlutterInstance( - flutter::FlutterEngine *flutter_instance) { - flutter_instances_.insert(flutter_instance); -} - -void RunLoop::UnregisterFlutterInstance( - flutter::FlutterEngine *flutter_instance) { - flutter_instances_.erase(flutter_instance); -} - -RunLoop::TimePoint RunLoop::ProcessFlutterMessages() { - TimePoint next_event_time = TimePoint::max(); - for (auto instance : flutter_instances_) { - std::chrono::nanoseconds wait_duration = instance->ProcessMessages(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, TimePoint::clock::now() + wait_duration); - } - } - return next_event_time; -} diff --git a/packages/device_info_plus/device_info_plus/example/windows/runner/run_loop.h b/packages/device_info_plus/device_info_plus/example/windows/runner/run_loop.h deleted file mode 100644 index 7fe1aaccc2..0000000000 --- a/packages/device_info_plus/device_info_plus/example/windows/runner/run_loop.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef RUNNER_RUN_LOOP_H_ -#define RUNNER_RUN_LOOP_H_ - -#include - -#include -#include - -// A runloop that will service events for Flutter instances as well -// as native messages. -class RunLoop { -public: - RunLoop(); - ~RunLoop(); - - // Prevent copying - RunLoop(RunLoop const &) = delete; - RunLoop &operator=(RunLoop const &) = delete; - - // Runs the run loop until the application quits. - void Run(); - - // Registers the given Flutter instance for event servicing. - void RegisterFlutterInstance(flutter::FlutterEngine *flutter_instance); - - // Unregisters the given Flutter instance from event servicing. - void UnregisterFlutterInstance(flutter::FlutterEngine *flutter_instance); - -private: - using TimePoint = std::chrono::steady_clock::time_point; - - // Processes all currently pending messages for registered Flutter instances. - TimePoint ProcessFlutterMessages(); - - std::set flutter_instances_; -}; - -#endif // RUNNER_RUN_LOOP_H_ diff --git a/packages/device_info_plus/device_info_plus/example/windows/runner/runner.exe.manifest b/packages/device_info_plus/device_info_plus/example/windows/runner/runner.exe.manifest index c977c4a425..153653e8d6 100644 --- a/packages/device_info_plus/device_info_plus/example/windows/runner/runner.exe.manifest +++ b/packages/device_info_plus/device_info_plus/example/windows/runner/runner.exe.manifest @@ -7,14 +7,8 @@ - + - - - - - - diff --git a/packages/device_info_plus/device_info_plus/example/windows/runner/utils.cpp b/packages/device_info_plus/device_info_plus/example/windows/runner/utils.cpp index 7758aabf38..3a0b46511a 100644 --- a/packages/device_info_plus/device_info_plus/example/windows/runner/utils.cpp +++ b/packages/device_info_plus/device_info_plus/example/windows/runner/utils.cpp @@ -24,7 +24,7 @@ void CreateAndAttachConsole() { 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); + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); if (argv == nullptr) { return std::vector(); } @@ -41,21 +41,23 @@ std::vector GetCommandLineArguments() { return command_line_arguments; } -std::string Utf8FromUtf16(const wchar_t *utf16_string) { +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(); - } + unsigned int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr) + -1; // remove the trailing null character + int input_length = (int)wcslen(utf16_string); std::string utf8_string; + if (target_length == 0 || target_length > utf8_string.max_size()) { + return utf8_string; + } utf8_string.resize(target_length); int converted_length = ::WideCharToMultiByte( - CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, -1, utf8_string.data(), - target_length, nullptr, nullptr); + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + input_length, utf8_string.data(), target_length, nullptr, nullptr); if (converted_length == 0) { return std::string(); } diff --git a/packages/device_info_plus/device_info_plus/example/windows/runner/utils.h b/packages/device_info_plus/device_info_plus/example/windows/runner/utils.h index ff43ce2ce5..3879d54755 100644 --- a/packages/device_info_plus/device_info_plus/example/windows/runner/utils.h +++ b/packages/device_info_plus/device_info_plus/example/windows/runner/utils.h @@ -10,10 +10,10 @@ 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); +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_ +#endif // RUNNER_UTILS_H_ diff --git a/packages/device_info_plus/device_info_plus/example/windows/runner/win32_window.cpp b/packages/device_info_plus/device_info_plus/example/windows/runner/win32_window.cpp index 90ff01e592..60608d0fe5 100644 --- a/packages/device_info_plus/device_info_plus/example/windows/runner/win32_window.cpp +++ b/packages/device_info_plus/device_info_plus/example/windows/runner/win32_window.cpp @@ -1,13 +1,31 @@ #include "win32_window.h" +#include #include #include "resource.h" namespace { +/// Window attribute that enables dark mode window decorations. +/// +/// Redefined in case the developer's machine has a Windows SDK older than +/// version 10.0.22000.0. +/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute +#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE +#define DWMWA_USE_IMMERSIVE_DARK_MODE 20 +#endif + constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; +/// Registry key for app theme preference. +/// +/// A value of 0 indicates apps should use dark mode. A non-zero or missing +/// value indicates apps should use light mode. +constexpr const wchar_t kGetPreferredBrightnessRegKey[] = + L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; +constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; + // The number of Win32Window objects that currently exist. static int g_active_window_count = 0; @@ -27,23 +45,23 @@ void EnableFullDpiSupportIfAvailable(HWND hwnd) { return; } auto enable_non_client_dpi_scaling = - reinterpret_cast( + reinterpret_cast( GetProcAddress(user32_module, "EnableNonClientDpiScaling")); if (enable_non_client_dpi_scaling != nullptr) { enable_non_client_dpi_scaling(hwnd); - FreeLibrary(user32_module); } + FreeLibrary(user32_module); } -} // namespace +} // namespace // Manages the Win32Window's window class registration. class WindowClassRegistrar { -public: + public: ~WindowClassRegistrar() = default; - // Returns the singleton registar instance. - static WindowClassRegistrar *GetInstance() { + // Returns the singleton registrar instance. + static WindowClassRegistrar* GetInstance() { if (!instance_) { instance_ = new WindowClassRegistrar(); } @@ -52,23 +70,23 @@ class WindowClassRegistrar { // Returns the name of the window class, registering the class if it hasn't // previously been registered. - const wchar_t *GetWindowClass(); + const wchar_t* GetWindowClass(); // Unregisters the window class. Should only be called if there are no // instances of the window. void UnregisterWindowClass(); -private: + private: WindowClassRegistrar() = default; - static WindowClassRegistrar *instance_; + static WindowClassRegistrar* instance_; bool class_registered_ = false; }; -WindowClassRegistrar *WindowClassRegistrar::instance_ = nullptr; +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; -const wchar_t *WindowClassRegistrar::GetWindowClass() { +const wchar_t* WindowClassRegistrar::GetWindowClass() { if (!class_registered_) { WNDCLASS window_class{}; window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); @@ -93,18 +111,21 @@ void WindowClassRegistrar::UnregisterWindowClass() { class_registered_ = false; } -Win32Window::Win32Window() { ++g_active_window_count; } +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) { +bool Win32Window::Create(const std::wstring& title, + const Point& origin, + const Size& size) { Destroy(); - const wchar_t *window_class = + const wchar_t* window_class = WindowClassRegistrar::GetInstance()->GetWindowClass(); const POINT target_point = {static_cast(origin.x), @@ -114,7 +135,7 @@ bool Win32Window::CreateAndShow(const std::wstring &title, const Point &origin, double scale_factor = dpi / 96.0; HWND window = CreateWindow( - window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 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); @@ -123,22 +144,29 @@ bool Win32Window::CreateAndShow(const std::wstring &title, const Point &origin, return false; } + UpdateTheme(window); + return OnCreate(); } +bool Win32Window::Show() { + return ShowWindow(window_handle_, SW_SHOWNORMAL); +} + // static -LRESULT CALLBACK Win32Window::WndProc(HWND const window, UINT const message, +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); + auto window_struct = reinterpret_cast(lparam); SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast(window_struct->lpCreateParams)); - auto that = static_cast(window_struct->lpCreateParams); + auto that = static_cast(window_struct->lpCreateParams); EnableFullDpiSupportIfAvailable(window); that->window_handle_ = window; - } else if (Win32Window *that = GetThisFromHandle(window)) { + } else if (Win32Window* that = GetThisFromHandle(window)) { return that->MessageHandler(window, message, wparam, lparam); } @@ -146,42 +174,48 @@ LRESULT CALLBACK Win32Window::WndProc(HWND const window, UINT const message, } LRESULT -Win32Window::MessageHandler(HWND hwnd, UINT const message, WPARAM const wparam, +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); + 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; } - 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); + 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; } - return 0; - } - case WM_ACTIVATE: - if (child_content_ != nullptr) { - SetFocus(child_content_); - } - return 0; + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + + case WM_DWMCOLORIZATIONCOLORCHANGED: + UpdateTheme(hwnd); + return 0; } return DefWindowProc(window_handle_, message, wparam, lparam); @@ -199,8 +233,8 @@ void Win32Window::Destroy() { } } -Win32Window *Win32Window::GetThisFromHandle(HWND const window) noexcept { - return reinterpret_cast( +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( GetWindowLongPtr(window, GWLP_USERDATA)); } @@ -221,7 +255,9 @@ RECT Win32Window::GetClientArea() { return frame; } -HWND Win32Window::GetHandle() { return window_handle_; } +HWND Win32Window::GetHandle() { + return window_handle_; +} void Win32Window::SetQuitOnClose(bool quit_on_close) { quit_on_close_ = quit_on_close; @@ -235,3 +271,18 @@ bool Win32Window::OnCreate() { void Win32Window::OnDestroy() { // No-op; provided for subclasses. } + +void Win32Window::UpdateTheme(HWND const window) { + DWORD light_mode; + DWORD light_mode_size = sizeof(light_mode); + LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, + kGetPreferredBrightnessRegValue, + RRF_RT_REG_DWORD, nullptr, &light_mode, + &light_mode_size); + + if (result == ERROR_SUCCESS) { + BOOL enable_dark_mode = light_mode == 0; + DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, + &enable_dark_mode, sizeof(enable_dark_mode)); + } +} diff --git a/packages/device_info_plus/device_info_plus/example/windows/runner/win32_window.h b/packages/device_info_plus/device_info_plus/example/windows/runner/win32_window.h index 7b518125bb..e901dde684 100644 --- a/packages/device_info_plus/device_info_plus/example/windows/runner/win32_window.h +++ b/packages/device_info_plus/device_info_plus/example/windows/runner/win32_window.h @@ -11,7 +11,7 @@ // inherited from by classes that wish to specialize with custom // rendering and input handling class Win32Window { -public: + public: struct Point { unsigned int x; unsigned int y; @@ -28,14 +28,16 @@ class Win32Window { Win32Window(); virtual ~Win32Window(); - // Creates and shows a win32 window with |title| and position and size using + // Creates a win32 window with |title| that is positioned and sized 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); + // consistent size this function will scale the inputted width and height as + // as appropriate for the default monitor. The window is invisible until + // |Show| is called. Returns true if the window was created successfully. + bool Create(const std::wstring& title, const Point& origin, const Size& size); + + // Show the current window. Returns true if the window was successfully shown. + bool Show(); // Release OS resources associated with window. void Destroy(); @@ -53,11 +55,12 @@ class Win32Window { // Return a RECT representing the bounds of the current client area. RECT GetClientArea(); -protected: + 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, + virtual LRESULT MessageHandler(HWND window, + UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept; @@ -68,20 +71,24 @@ class Win32Window { // Called when Destroy is called. virtual void OnDestroy(); -private: + 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 + // responds to changes in DPI. All other messages are handled by // MessageHandler. - static LRESULT CALLBACK WndProc(HWND const window, UINT const message, + 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; + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + // Update the window frame's theme to match the system theme. + static void UpdateTheme(HWND const window); bool quit_on_close_ = false; @@ -92,4 +99,4 @@ class Win32Window { HWND child_content_ = nullptr; }; -#endif // RUNNER_WIN32_WINDOW_H_ +#endif // RUNNER_WIN32_WINDOW_H_ diff --git a/packages/device_info_plus/device_info_plus/lib/device_info_plus.dart b/packages/device_info_plus/device_info_plus/lib/device_info_plus.dart index f5acdb5cb7..3bbc836d34 100644 --- a/packages/device_info_plus/device_info_plus/lib/device_info_plus.dart +++ b/packages/device_info_plus/device_info_plus/lib/device_info_plus.dart @@ -60,10 +60,8 @@ class DeviceInfoPlugin { /// Information derived from `UIDevice`. /// /// See: https://developer.apple.com/documentation/uikit/uidevice - Future get iosInfo async => - _cachedIosDeviceInfo ??= IosDeviceInfo.fromMap( - (await _platform.deviceInfo()).data, - ); + Future get iosInfo async => _cachedIosDeviceInfo ??= + IosDeviceInfo.fromMap((await _platform.deviceInfo()).data); /// This information does not change from call to call. Cache it. LinuxDeviceInfo? _cachedLinuxDeviceInfo; @@ -71,9 +69,8 @@ class DeviceInfoPlugin { /// Information derived from `/etc/os-release`. /// /// See: https://www.freedesktop.org/software/systemd/man/os-release.html - Future get linuxInfo async => - _cachedLinuxDeviceInfo ??= - await _platform.deviceInfo() as LinuxDeviceInfo; + Future get linuxInfo async => _cachedLinuxDeviceInfo ??= + await _platform.deviceInfo() as LinuxDeviceInfo; /// This information does not change from call to call. Cache it. WebBrowserInfo? _cachedWebBrowserInfo; @@ -86,10 +83,8 @@ class DeviceInfoPlugin { MacOsDeviceInfo? _cachedMacosDeviceInfo; /// Returns device information for macos. Information sourced from Sysctl. - Future get macOsInfo async => - _cachedMacosDeviceInfo ??= MacOsDeviceInfo.fromMap( - (await _platform.deviceInfo()).data, - ); + Future get macOsInfo async => _cachedMacosDeviceInfo ??= + MacOsDeviceInfo.fromMap((await _platform.deviceInfo()).data); WindowsDeviceInfo? _cachedWindowsDeviceInfo; diff --git a/packages/device_info_plus/device_info_plus/lib/src/device_info_plus_web.dart b/packages/device_info_plus/device_info_plus/lib/src/device_info_plus_web.dart index c9f153a1c9..d84c31ffb3 100644 --- a/packages/device_info_plus/device_info_plus/lib/src/device_info_plus_web.dart +++ b/packages/device_info_plus/device_info_plus/lib/src/device_info_plus_web.dart @@ -10,7 +10,7 @@ import 'model/web_browser_info.dart'; /// The web implementation of the BatteryPlusPlatform of the BatteryPlus plugin. class DeviceInfoPlusWebPlugin extends DeviceInfoPlatform { /// Constructs a DeviceInfoPlusPlugin. - DeviceInfoPlusWebPlugin(navigator) : _navigator = navigator; + DeviceInfoPlusWebPlugin(html.Navigator navigator) : _navigator = navigator; final html.Navigator _navigator; diff --git a/packages/device_info_plus/device_info_plus/lib/src/device_info_plus_windows.dart b/packages/device_info_plus/device_info_plus/lib/src/device_info_plus_windows.dart index d4385abb77..6a847aa448 100644 --- a/packages/device_info_plus/device_info_plus/lib/src/device_info_plus_windows.dart +++ b/packages/device_info_plus/device_info_plus/lib/src/device_info_plus_windows.dart @@ -30,12 +30,11 @@ class DeviceInfoPlusWindowsPlugin extends DeviceInfoPlatform { // package:win32, so we have to manually define it here. // // ignore: non_constant_identifier_names - void Function(Pointer) RtlGetVersion = DynamicLibrary.open( - 'ntdll.dll', - ).lookupFunction< - Void Function(Pointer), - void Function(Pointer) - >('RtlGetVersion'); + void Function(Pointer) RtlGetVersion = + DynamicLibrary.open('ntdll.dll').lookupFunction< + Void Function(Pointer), + void Function(Pointer) + >('RtlGetVersion'); /// Returns a [WindowsDeviceInfo] with information about the device. @override @@ -46,37 +45,32 @@ class DeviceInfoPlusWindowsPlugin extends DeviceInfoPlatform { @visibleForTesting WindowsDeviceInfo getInfo() { final systemInfo = calloc(); - final osVersionInfo = - calloc() - ..ref.dwOSVersionInfoSize = sizeOf(); + final osVersionInfo = calloc() + ..ref.dwOSVersionInfoSize = sizeOf(); try { - final currentVersionKey = Registry.openPath( - RegistryHive.localMachine, - path: r'SOFTWARE\Microsoft\Windows NT\CurrentVersion', + final currentVersionKey = LOCAL_MACHINE.open( + r'SOFTWARE\Microsoft\Windows NT\CurrentVersion', ); - final buildLab = currentVersionKey.getStringValue('BuildLab') ?? ''; - final buildLabEx = currentVersionKey.getStringValue('BuildLabEx') ?? ''; + final buildLab = currentVersionKey.getString('BuildLab') ?? ''; + final buildLabEx = currentVersionKey.getString('BuildLabEx') ?? ''; final digitalProductId = - currentVersionKey.getBinaryValue('DigitalProductId') ?? + currentVersionKey.getBinary('DigitalProductId') ?? Uint8List.fromList([]); final displayVersion = - currentVersionKey.getStringValue('DisplayVersion') ?? ''; - final editionId = currentVersionKey.getStringValue('EditionID') ?? ''; + currentVersionKey.getString('DisplayVersion') ?? ''; + final editionId = currentVersionKey.getString('EditionID') ?? ''; final installDate = DateTime.fromMillisecondsSinceEpoch( - 1000 * (currentVersionKey.getIntValue('InstallDate') ?? 0), + 1000 * (currentVersionKey.getInt('InstallDate') ?? 0), ); - final productId = currentVersionKey.getStringValue('ProductID') ?? ''; - var productName = currentVersionKey.getStringValue('ProductName') ?? ''; + final productId = currentVersionKey.getString('ProductID') ?? ''; + var productName = currentVersionKey.getString('ProductName') ?? ''; final registeredOwner = - currentVersionKey.getStringValue('RegisteredOwner') ?? ''; - final releaseId = currentVersionKey.getStringValue('ReleaseId') ?? ''; + currentVersionKey.getString('RegisteredOwner') ?? ''; + final releaseId = currentVersionKey.getString('ReleaseId') ?? ''; - final sqmClientKey = Registry.openPath( - RegistryHive.localMachine, - path: r'SOFTWARE\Microsoft\SQMClient', - ); - final machineId = sqmClientKey.getStringValue('MachineId') ?? ''; + final sqmClientKey = LOCAL_MACHINE.open(r'SOFTWARE\Microsoft\SQMClient'); + final machineId = sqmClientKey.getString('MachineId') ?? ''; GetSystemInfo(systemInfo); @@ -102,7 +96,7 @@ class DeviceInfoPlusWindowsPlugin extends DeviceInfoPlatform { servicePackMinor: osVersionInfo.ref.wServicePackMinor, suitMask: osVersionInfo.ref.wSuiteMask, productType: osVersionInfo.ref.wProductType, - reserved: osVersionInfo.ref.wReserved, + reserved: 0, buildLab: buildLab, buildLabEx: buildLabEx, digitalProductId: digitalProductId, @@ -127,10 +121,10 @@ class DeviceInfoPlusWindowsPlugin extends DeviceInfoPlatform { final memoryInKilobytes = calloc(); try { final result = GetPhysicallyInstalledSystemMemory(memoryInKilobytes); - if (result != 0) { + if (result.value) { return memoryInKilobytes.value ~/ 1024; } else { - developer.log('Failed to get system memory', error: GetLastError()); + developer.log('Failed to get system memory', error: result.error); return 0; } } finally { @@ -143,7 +137,7 @@ class DeviceInfoPlusWindowsPlugin extends DeviceInfoPlatform { // We call this a first time to get the length of the string in characters, // so we can allocate sufficient memory. final nSize = calloc(); - GetComputerNameEx(ComputerNameDnsFullyQualified, nullptr, nSize); + GetComputerNameEx(ComputerNameDnsFullyQualified, null, nSize); // Now allocate memory for a native string and call this a second time. final lpBuffer = wsalloc(nSize.value); @@ -154,10 +148,10 @@ class DeviceInfoPlusWindowsPlugin extends DeviceInfoPlatform { nSize, ); - if (result != 0) { + if (result.value) { return lpBuffer.toDartString(); } else { - developer.log('Failed to get computer name', error: GetLastError()); + developer.log('Failed to get computer name', error: result.error); return ""; } } finally { @@ -173,10 +167,10 @@ class DeviceInfoPlusWindowsPlugin extends DeviceInfoPlatform { final pcbBuffer = calloc()..value = maxLength + 1; try { final result = GetUserName(lpBuffer, pcbBuffer); - if (result != 0) { + if (result.value) { return lpBuffer.toDartString(); } else { - developer.log('Failed to get user name', error: GetLastError()); + developer.log('Failed to get user name', error: result.error); return ""; } } finally { diff --git a/packages/device_info_plus/device_info_plus/pubspec.yaml b/packages/device_info_plus/device_info_plus/pubspec.yaml index 48eef447cf..c6d7626dd6 100644 --- a/packages/device_info_plus/device_info_plus/pubspec.yaml +++ b/packages/device_info_plus/device_info_plus/pubspec.yaml @@ -30,24 +30,23 @@ flutter: dependencies: device_info_plus_platform_interface: ^7.0.3 - ffi: ^2.1.4 + ffi: ^2.2.0 file: ^7.0.1 flutter: sdk: flutter flutter_web_plugins: sdk: flutter - meta: ^1.16.0 - web: ^1.1.0 - win32: ^5.11.0 - win32_registry: ^2.1.0 + meta: ^1.17.0 + web: ^1.1.1 + win32: ^6.0.0 + win32_registry: ^3.0.2 dev_dependencies: - flutter_lints: ^5.0.0 + flutter_lints: ^6.0.0 flutter_test: sdk: flutter - mockito: ^5.4.5 - test: ^1.25.15 + mockito: ^5.6.4 environment: - sdk: ">=3.7.0 <4.0.0" - flutter: ">=3.29.0" + sdk: ">=3.11.0 <4.0.0" + flutter: ">=3.41.0" diff --git a/packages/device_info_plus/device_info_plus/test/device_info_plus_windows_test.dart b/packages/device_info_plus/device_info_plus/test/device_info_plus_windows_test.dart index 6d7765d66b..67b36c7fda 100644 --- a/packages/device_info_plus/device_info_plus/test/device_info_plus_windows_test.dart +++ b/packages/device_info_plus/device_info_plus/test/device_info_plus_windows_test.dart @@ -13,8 +13,8 @@ void main() { expect(DeviceInfoPlatform.instance, isA()); }); test('system-memory-in-megabytes', () async { - final systemMemoryInMegabytes = - DeviceInfoPlusWindowsPlugin().getSystemMemoryInMegabytes(); + final systemMemoryInMegabytes = DeviceInfoPlusWindowsPlugin() + .getSystemMemoryInMegabytes(); // It's a reasonable expectation that any computer executing this test has // >512MB RAM diff --git a/packages/device_info_plus/device_info_plus_platform_interface/pubspec.yaml b/packages/device_info_plus/device_info_plus_platform_interface/pubspec.yaml index 90083edac6..1742f01208 100644 --- a/packages/device_info_plus/device_info_plus_platform_interface/pubspec.yaml +++ b/packages/device_info_plus/device_info_plus_platform_interface/pubspec.yaml @@ -7,15 +7,15 @@ repository: https://github.com/fluttercommunity/plus_plugins/tree/main/packages/ dependencies: flutter: sdk: flutter - meta: ^1.16.0 + meta: ^1.17.0 plugin_platform_interface: ^2.1.8 dev_dependencies: - flutter_lints: ">=5.0.0 <7.0.0" + flutter_lints: ^6.0.0 flutter_test: sdk: flutter mockito: ^5.4.0 environment: - sdk: ">=3.7.0 <4.0.0" - flutter: ">=3.29.0" + sdk: ">=3.11.0 <4.0.0" + flutter: ">=3.41.0"