From dad63e7f1b560c065b6d2a0bedff2df54be425ac Mon Sep 17 00:00:00 2001 From: James Clarke Date: Wed, 9 Dec 2020 06:34:37 -0800 Subject: [PATCH 01/17] Windows: Add CoreWindow implementation of FlutterWindowsView (Flutter#70205) --- ci/licenses_golden/licenses_flutter | 4 + shell/platform/common/cpp/engine_switches.cc | 2 + shell/platform/windows/BUILD.gn | 9 + .../platform/windows/angle_surface_manager.cc | 24 + .../client_wrapper/flutter_view_controller.cc | 17 + .../include/flutter/dart_project.h | 18 + .../include/flutter/flutter_view.h | 2 + .../include/flutter/flutter_view_controller.h | 16 +- .../windows/flutter_windows_winuwp.cc | 51 +- shell/platform/windows/key_event_handler.cc | 4 + .../platform/windows/public/flutter_windows.h | 16 + shell/platform/windows/system_utils_winuwp.cc | 33 +- shell/platform/windows/uwp_flutter_window.cc | 486 ++++++++++++++++++ shell/platform/windows/uwp_flutter_window.h | 176 +++++++ shell/platform/windows/uwp_game_pad.cc | 223 ++++++++ shell/platform/windows/uwp_game_pad.h | 85 +++ .../platform/windows/window_binding_handler.h | 14 +- 17 files changed, 1152 insertions(+), 28 deletions(-) create mode 100644 shell/platform/windows/uwp_flutter_window.cc create mode 100644 shell/platform/windows/uwp_flutter_window.h create mode 100644 shell/platform/windows/uwp_game_pad.cc create mode 100644 shell/platform/windows/uwp_game_pad.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 786a7377d7900..7e77c15c8a964 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1457,6 +1457,10 @@ FILE: ../../../flutter/shell/platform/windows/task_runner_win32.cc FILE: ../../../flutter/shell/platform/windows/task_runner_win32.h FILE: ../../../flutter/shell/platform/windows/task_runner_winuwp.cc FILE: ../../../flutter/shell/platform/windows/task_runner_winuwp.h +FILE: ../../../flutter/shell/platform/windows/uwp_flutter_window.cc +FILE: ../../../flutter/shell/platform/windows/uwp_flutter_window.h +FILE: ../../../flutter/shell/platform/windows/uwp_game_pad.cc +FILE: ../../../flutter/shell/platform/windows/uwp_game_pad.h FILE: ../../../flutter/shell/platform/windows/text_input_plugin.cc FILE: ../../../flutter/shell/platform/windows/text_input_plugin.h FILE: ../../../flutter/shell/platform/windows/win32_dpi_utils.cc diff --git a/shell/platform/common/cpp/engine_switches.cc b/shell/platform/common/cpp/engine_switches.cc index f19d43cbb5fd2..98ec045425246 100644 --- a/shell/platform/common/cpp/engine_switches.cc +++ b/shell/platform/common/cpp/engine_switches.cc @@ -16,6 +16,7 @@ std::vector GetSwitchesFromEnvironment() { // Read engine switches from the environment in debug/profile. If release mode // support is needed in the future, it should likely use a whitelist. #ifndef FLUTTER_RELEASE +#ifndef WINUWP const char* switch_count_key = "FLUTTER_ENGINE_SWITCHES"; const int kMaxSwitchCount = 50; const char* switch_count_string = std::getenv(switch_count_key); @@ -36,6 +37,7 @@ std::vector GetSwitchesFromEnvironment() { << ", but " << switch_key.str() << " is missing." << std::endl; } } +#endif // !WINUWP #endif // !FLUTTER_RELEASE return switches; } diff --git a/shell/platform/windows/BUILD.gn b/shell/platform/windows/BUILD.gn index 873125ad4ebef..313579eacff37 100644 --- a/shell/platform/windows/BUILD.gn +++ b/shell/platform/windows/BUILD.gn @@ -13,6 +13,10 @@ config("relative_angle_headers") { include_dirs = [ "//third_party/angle/include" ] } +config("usecorewindow") { + defines = [ "USECOREWINDOW" ] +} + # Any files that are built by clients (client_wrapper code, library headers for # implementations using this shared code, etc.) include the public headers # assuming they are in the include path. This configuration should be added to @@ -80,6 +84,10 @@ source_set("flutter_windows_source") { "system_utils_winuwp.cc", "task_runner_winuwp.cc", "task_runner_winuwp.h", + "uwp_flutter_window.cc", + "uwp_flutter_window.h", + "uwp_game_pad.cc", + "uwp_game_pad.h", ] } else { sources += [ @@ -103,6 +111,7 @@ source_set("flutter_windows_source") { configs += [ "//flutter/shell/platform/common/cpp:desktop_library_implementation", "//third_party/angle:gl_prototypes", + ":usecorewindow", ] public_configs = [ ":relative_angle_headers" ] diff --git a/shell/platform/windows/angle_surface_manager.cc b/shell/platform/windows/angle_surface_manager.cc index 32c2bc3de0d2b..8a8b03a36a096 100644 --- a/shell/platform/windows/angle_surface_manager.cc +++ b/shell/platform/windows/angle_surface_manager.cc @@ -4,6 +4,15 @@ #include "flutter/shell/platform/windows/angle_surface_manager.h" +#ifdef WINUWP +#include +#include +#endif + +#ifdef USECOREWINDOW +#include +#endif + #include #include @@ -188,10 +197,23 @@ bool AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target, EGL_FIXED_SIZE_ANGLE, EGL_TRUE, EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE}; +#ifndef WINUWP surface = eglCreateWindowSurface( egl_display_, egl_config_, static_cast(std::get(*render_target)), surfaceAttributes); +#else +#ifdef USECOREWINDOW + auto thing = std::get(*render_target); +#else + auto thing = + std::get(*render_target); +#endif + surface = eglCreateWindowSurface( + egl_display_, egl_config_, + static_cast(winrt::get_abi(thing)), + surfaceAttributes); +#endif if (surface == EGL_NO_SURFACE) { std::cerr << "Surface creation failed." << std::endl; } @@ -212,6 +234,8 @@ void AngleSurfaceManager::ResizeSurface(WindowsRenderTarget* render_target, // preserve the previous surface contents. This resize approach could be // further optimized if Angle exposed a public entrypoint for // SwapChain11::reset or SwapChain11::resize. + // a possible starting point for that could build on + // eglPostSubBufferNV(egl_display_, render_surface_, 1, 1, width, height); DestroySurface(); if (!CreateSurface(render_target, width, height)) { std::cerr << "AngleSurfaceManager::ResizeSurface failed to create surface" diff --git a/shell/platform/windows/client_wrapper/flutter_view_controller.cc b/shell/platform/windows/client_wrapper/flutter_view_controller.cc index 2724b27881f22..727c313e37fed 100644 --- a/shell/platform/windows/client_wrapper/flutter_view_controller.cc +++ b/shell/platform/windows/client_wrapper/flutter_view_controller.cc @@ -9,6 +9,7 @@ namespace flutter { +#ifndef WINUWP FlutterViewController::FlutterViewController(int width, int height, const DartProject& project) { @@ -22,6 +23,22 @@ FlutterViewController::FlutterViewController(int width, view_ = std::make_unique( FlutterDesktopViewControllerGetView(controller_)); } +#else +FlutterViewController::FlutterViewController( + ABI::Windows::UI::Core::CoreWindow* window, + const DartProject& project) { + engine_ = std::make_unique(project); + controller_ = FlutterDesktopViewControllerCreateFromCoreWindow( + window, + engine_->RelinquishEngine()); + if (!controller_) { + std::cerr << "Failed to create view controller." << std::endl; + return; + } + view_ = std::make_unique( + FlutterDesktopViewControllerGetView(controller_)); +} +#endif FlutterViewController::~FlutterViewController() { if (controller_) { diff --git a/shell/platform/windows/client_wrapper/include/flutter/dart_project.h b/shell/platform/windows/client_wrapper/include/flutter/dart_project.h index 9dff236ff2cd5..95e5ca0d94bea 100644 --- a/shell/platform/windows/client_wrapper/include/flutter/dart_project.h +++ b/shell/platform/windows/client_wrapper/include/flutter/dart_project.h @@ -13,6 +13,7 @@ namespace flutter { // A set of Flutter and Dart assets used to initialize a Flutter engine. class DartProject { public: + #ifndef WINUWP // Creates a DartProject from a directory path. The directory should contain // the following top-level items: // - icudtl.dat (provided as a resource by the Flutter tool) @@ -26,6 +27,23 @@ class DartProject { icu_data_path_ = path + L"\\icudtl.dat"; aot_library_path_ = path + L"\\app.so"; } + #else + // Creates a DartProject from a series of absolute paths. + // The directory should contain the following top-level items: + // - icudtl.dat (provided as a resource by the Flutter tool) + // - flutter_assets (as built by the Flutter tool) + // - app.so, for an AOT build (as built by the Flutter tool) + // + // The path can either be absolute, or relative to the directory containing + // the running executable. + explicit DartProject(const std::wstring& assetspath, + const std::wstring& icupath, + const std::wstring& aotpath) { + assets_path_ = assetspath; + icu_data_path_ = icupath; + aot_library_path_ = aotpath; + } + #endif ~DartProject() = default; diff --git a/shell/platform/windows/client_wrapper/include/flutter/flutter_view.h b/shell/platform/windows/client_wrapper/include/flutter/flutter_view.h index 18c908e977deb..91765c4477673 100644 --- a/shell/platform/windows/client_wrapper/include/flutter/flutter_view.h +++ b/shell/platform/windows/client_wrapper/include/flutter/flutter_view.h @@ -20,8 +20,10 @@ class FlutterView { FlutterView(FlutterView const&) = delete; FlutterView& operator=(FlutterView const&) = delete; +#ifndef WINUWP // Returns the backing HWND for the view. HWND GetNativeWindow() { return FlutterDesktopViewGetHWND(view_); } + #endif private: // Handle for interacting with the C API's view. diff --git a/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h b/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h index f39a7e70c980e..463b97c25d0a7 100644 --- a/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h +++ b/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h @@ -8,6 +8,10 @@ #include #include +#ifdef WINUWP +#include +#endif + #include #include @@ -26,13 +30,23 @@ namespace flutter { // methods in the C API directly, as this class will do that internally. class FlutterViewController { public: +#ifndef WINUWP // Creates a FlutterView that can be parented into a Windows View hierarchy - // either using HWNDs or in the future into a CoreWindow, or using compositor. + // either using HWNDs. // // |dart_project| will be used to configure the engine backing this view. explicit FlutterViewController(int width, int height, const DartProject& project); +#else + // Creates a FlutterView that can be parented into a Windows View hierarchy + // either using CoreWindow. + // + // |dart_project| will be used to configure the engine backing this view. + explicit FlutterViewController( + ABI::Windows::UI::Core::CoreWindow* window, + const DartProject& project); +#endif virtual ~FlutterViewController(); diff --git a/shell/platform/windows/flutter_windows_winuwp.cc b/shell/platform/windows/flutter_windows_winuwp.cc index 35cd27e25f661..5a5f45871c77b 100644 --- a/shell/platform/windows/flutter_windows_winuwp.cc +++ b/shell/platform/windows/flutter_windows_winuwp.cc @@ -15,31 +15,38 @@ #include #include +#include "flutter//shell/platform/windows/uwp_flutter_window.h" // nogncheck #include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h" #include "flutter/shell/platform/common/cpp/incoming_message_dispatcher.h" -FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate( - int width, - int height, - FlutterDesktopEngineRef engine) { - // TODO add WINUWP implementation. - return nullptr; -} - -uint64_t FlutterDesktopEngineProcessMessages(FlutterDesktopEngineRef engine) { - // TODO add WINUWP implementation. - return 0; +// Returns the engine corresponding to the given opaque API handle. +static flutter::FlutterWindowsEngine* EngineFromHandle( + FlutterDesktopEngineRef ref) { + return reinterpret_cast(ref); } -void FlutterDesktopPluginRegistrarRegisterTopLevelWindowProcDelegate( - FlutterDesktopPluginRegistrarRef registrar, - FlutterDesktopWindowProcCallback delegate, - void* user_data) { - // TODO add WINUWP implementation. -} - -void FlutterDesktopPluginRegistrarUnregisterTopLevelWindowProcDelegate( - FlutterDesktopPluginRegistrarRef registrar, - FlutterDesktopWindowProcCallback delegate) { - // TODO add WINUWP implementation. +FlutterDesktopViewControllerRef +FlutterDesktopViewControllerCreateFromCoreWindow( + ABI::Windows::UI::Core::CoreWindow* window, + FlutterDesktopEngineRef engine) { + std::unique_ptr window_wrapper = + std::make_unique(window); + + auto state = std::make_unique(); + state->view = + std::make_unique(std::move(window_wrapper)); + state->view->CreateRenderSurface(); + + // Take ownership of the engine, starting it if necessary. + state->view->SetEngine( + std::unique_ptr(EngineFromHandle(engine))); + if (!state->view->GetEngine()->running()) { + if (!state->view->GetEngine()->RunWithEntrypoint(nullptr)) { + return nullptr; + } + } + + // Must happen after engine is running. + state->view->SendInitialBounds(); + return state.release(); } diff --git a/shell/platform/windows/key_event_handler.cc b/shell/platform/windows/key_event_handler.cc index 9b562f8f0944e..a4587a364e30b 100644 --- a/shell/platform/windows/key_event_handler.cc +++ b/shell/platform/windows/key_event_handler.cc @@ -45,6 +45,7 @@ const int kNumLock = 1 << 12; const int kScrollLock = 1 << 13; namespace { +#ifndef WINUWP /// Calls GetKeyState() an all modifier keys and packs the result in an int, /// with the re-defined values declared above for compatibility with the Flutter /// framework. @@ -81,6 +82,7 @@ int GetModsForKeyState() { mods |= kScrollLock; return mods; } +#endif } // namespace KeyEventHandler::KeyEventHandler(flutter::BinaryMessenger* messenger) @@ -108,7 +110,9 @@ void KeyEventHandler::KeyboardHook(FlutterWindowsView* view, event.AddMember(kScanCodeKey, scancode, allocator); event.AddMember(kCharacterCodePointKey, character, allocator); event.AddMember(kKeyMapKey, kWindowsKeyMap, allocator); +#ifndef WINUWP event.AddMember(kModifiersKey, GetModsForKeyState(), allocator); +#endif switch (action) { case WM_KEYDOWN: diff --git a/shell/platform/windows/public/flutter_windows.h b/shell/platform/windows/public/flutter_windows.h index dbcaf8df17035..22874534957ed 100644 --- a/shell/platform/windows/public/flutter_windows.h +++ b/shell/platform/windows/public/flutter_windows.h @@ -9,6 +9,10 @@ #include #include +#ifdef WINUWP +#include +#endif + #include "flutter_export.h" #include "flutter_messenger.h" #include "flutter_plugin_registrar.h" @@ -57,6 +61,7 @@ typedef struct { // ========== View Controller ========== +#ifndef WINUWP // Creates a view that hosts and displays the given engine instance. // // This takes ownership of |engine|, so FlutterDesktopEngineDestroy should no @@ -74,6 +79,13 @@ FLUTTER_EXPORT FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(int width, int height, FlutterDesktopEngineRef engine); +#else +//TODO +FLUTTER_EXPORT FlutterDesktopViewControllerRef +FlutterDesktopViewControllerCreateFromCoreWindow( + ABI::Windows::UI::Core::CoreWindow* window, + FlutterDesktopEngineRef engine); +#endif // Shuts down the engine instance associated with |controller|, and cleans up // associated state. @@ -161,8 +173,10 @@ FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine); // ========== View ========== +#ifndef WINUWP // Return backing HWND for manipulation in host application. FLUTTER_EXPORT HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view); +#endif // ========== Plugin Registrar (extensions) ========== // These are Windows-specific extensions to flutter_plugin_registrar.h @@ -186,6 +200,7 @@ typedef bool (*FlutterDesktopWindowProcCallback)(HWND /* hwnd */, FLUTTER_EXPORT FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView( FlutterDesktopPluginRegistrarRef registrar); +#ifndef WINUWP FLUTTER_EXPORT void FlutterDesktopPluginRegistrarRegisterTopLevelWindowProcDelegate( FlutterDesktopPluginRegistrarRef registrar, @@ -196,6 +211,7 @@ FLUTTER_EXPORT void FlutterDesktopPluginRegistrarUnregisterTopLevelWindowProcDelegate( FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopWindowProcCallback delegate); +#endif // ========== Freestanding Utilities ========== diff --git a/shell/platform/windows/system_utils_winuwp.cc b/shell/platform/windows/system_utils_winuwp.cc index 85278dc0a6dd5..d23c06b9eeb8d 100644 --- a/shell/platform/windows/system_utils_winuwp.cc +++ b/shell/platform/windows/system_utils_winuwp.cc @@ -15,20 +15,47 @@ namespace flutter { std::vector GetPreferredLanguageInfo() { std::vector languages = GetPreferredLanguages(); std::vector language_info; - // TODO populate via WinRT + for (auto language : languages) { + language_info.push_back(ParseLanguageName(language)); + } return language_info; } std::vector GetPreferredLanguages() { std::vector languages; - // TODO populate via WinRT + languages.push_back(L"en-US"); + languages.push_back(L"en"); + return languages; } LanguageInfo ParseLanguageName(std::wstring language_name) { LanguageInfo info; - // TODO populate via WinRT + // Split by '-', discarding any suplemental language info (-x-foo). + std::vector components; + std::istringstream stream(Utf8FromUtf16(language_name)); + std::string component; + while (getline(stream, component, '-')) { + if (component == "x") { + break; + } + components.push_back(component); + } + + // Determine which components are which. + info.language = components[0]; + if (components.size() == 3) { + info.script = components[1]; + info.region = components[2]; + } else if (components.size() == 2) { + // A script code will always be four characters long. + if (components[1].size() == 4) { + info.script = components[1]; + } else { + info.region = components[1]; + } + } return info; } diff --git a/shell/platform/windows/uwp_flutter_window.cc b/shell/platform/windows/uwp_flutter_window.cc new file mode 100644 index 0000000000000..61c84371c549a --- /dev/null +++ b/shell/platform/windows/uwp_flutter_window.cc @@ -0,0 +1,486 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/windows/uwp_flutter_window.h" + +namespace flutter { + +WinRTFlutterWindow::WinRTFlutterWindow( + ABI::Windows::UI::Core::CoreWindow* window) + : game_controller_thread_running_(false), + running_on_xbox_(false), + xbox_overscan_x_offset_(0), + xbox_overscan_y_offset_(0), + current_display_info_(nullptr) { + winrt::Windows::UI::Core::CoreWindow cw{nullptr}; + winrt::copy_from_abi(cw, window); + window_ = cw; + + SetEventHandlers(); + SetupGamePad(); + SetupXboxSpecific(); + + current_display_info_ = winrt::Windows::Graphics::Display:: + DisplayInformation::GetForCurrentView(); +} + +WindowsRenderTarget WinRTFlutterWindow::GetRenderTarget() { +#ifdef USECOREWINDOW + return WindowsRenderTarget(window_); +#else + compositor_ = winrt::Windows::UI::Composition::Compositor(); + target_ = compositor_.CreateTargetForCurrentView(); + visual_tree_root_ = compositor_.CreateContainerVisual(); + target_.Root(visual_tree_root_); + + cursor_visual_ = CreateCursorVisual(); + + if (game_controller_thread_running_) { + visual_tree_root_.Children().InsertAtTop(cursor_visual_); + } + + sprite_visual_ = compositor_.CreateSpriteVisual(); + if (running_on_xbox_) { + sprite_visual_.Offset( + {xbox_overscan_x_offset_, xbox_overscan_y_offset_, 1.0}); + } else { + sprite_visual_.Offset({1.0, 1.0, 1.0}); + ApplyInverseDpiScalingTransform(); + } + visual_tree_root_.Children().InsertAtBottom(sprite_visual_); + + auto bounds = GetBounds(current_display_info_, true); + + sprite_visual_.Size({bounds.width, bounds.height}); + return WindowsRenderTarget(sprite_visual_); +#endif +} + +void WinRTFlutterWindow::ApplyInverseDpiScalingTransform() { + // apply inverse transform to negate built in DPI scaling so we can render at + // native scale + auto dpiScale = GetDpiScale(); + sprite_visual_.Scale({1 / dpiScale, 1 / dpiScale, 1 / dpiScale}); +} + +PhysicalWindowBounds WinRTFlutterWindow::GetPhysicalWindowBounds() { + auto bounds = GetBounds(current_display_info_, true); + return {static_cast(bounds.width), + static_cast(bounds.height)}; +} + +void WinRTFlutterWindow::UpdateFlutterCursor(const std::string& cursor_name) { + // TODO +} + +float WinRTFlutterWindow::GetDpiScale() { + auto disp = winrt::Windows::Graphics::Display::DisplayInformation:: + GetForCurrentView(); + + return GetDpiScale(disp); +} + +WinRTWindowBounds WinRTFlutterWindow::GetBounds( + winrt::Windows::Graphics::Display::DisplayInformation const& disp, + bool physical) { + auto appView = + winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView(); + auto bounds = appView.VisibleBounds(); + if (running_on_xbox_) { + return {bounds.Width + (bounds.X), bounds.Height + (bounds.Y)}; + } + + if (physical) { + // Return the height in physical pixels + return {bounds.Width * static_cast(disp.RawPixelsPerViewPixel()), + bounds.Height * static_cast(disp.RawPixelsPerViewPixel())}; + } + + return {bounds.Width, bounds.Height}; +} + +float WinRTFlutterWindow::GetDpiScale( + winrt::Windows::Graphics::Display::DisplayInformation const& disp) { + float dpi = disp.LogicalDpi(); + auto rawdpi = disp.RawDpiX(); + auto rawwidth = disp.ScreenHeightInRawPixels(); + auto scale = disp.ResolutionScale(); + auto rawperview = disp.RawPixelsPerViewPixel(); + + // because XBOX has display scaling off, logicalDpi retuns 96 which is + // incorrect + // TODO check if rawperview is more acurate + if (running_on_xbox_) { + return 1.5; + } + // TODO do we need this on 10X? + // return dpi/96.0 * 0.8; + return static_cast(rawperview); +} + +WinRTFlutterWindow::~WinRTFlutterWindow() { + OutputDebugString(L"Destoryed UWP FlutterWindow"); +} + +void WinRTFlutterWindow::SetView(WindowBindingHandlerDelegate* view) { + binding_handler_delegate_ = view; +} + +void WinRTFlutterWindow::SetEventHandlers() { + auto appView = + winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView(); + + appView.SetDesiredBoundsMode(winrt::Windows::UI::ViewManagement:: + ApplicationViewBoundsMode::UseCoreWindow); + + appView.VisibleBoundsChanged({this, &WinRTFlutterWindow::OnBoundsChanged}); + + window_.PointerPressed({this, &WinRTFlutterWindow::OnPointerPressed}); + window_.PointerReleased({this, &WinRTFlutterWindow::OnPointerReleased}); + window_.PointerMoved({this, &WinRTFlutterWindow::OnPointerMoved}); + window_.PointerWheelChanged( + {this, &WinRTFlutterWindow::OnPointerWheelChanged}); + + // TODO mouse leave + // TODO fontchanged + + window_.KeyUp({this, &WinRTFlutterWindow::OnKeyUp}); + window_.KeyDown({this, &WinRTFlutterWindow::OnKeyDown}); + window_.CharacterReceived({this, &WinRTFlutterWindow::OnCharacterReceived}); + + auto disp = winrt::Windows::Graphics::Display::DisplayInformation:: + GetForCurrentView(); + disp.DpiChanged({this, &WinRTFlutterWindow::OnDpiChanged}); +} + +void WinRTFlutterWindow::StartGamepadCursorThread() { + if (worker_loop_ != nullptr && + worker_loop_.Status() == + winrt::Windows::Foundation::AsyncStatus::Started) { + return; + } + + winrt::Windows::UI::Core::CoreDispatcher dispatcher = window_.Dispatcher(); + + auto workItemHandler = winrt::Windows::System::Threading::WorkItemHandler( + [this, dispatcher](winrt::Windows::Foundation::IAsyncAction action) { + while (action.Status() == + winrt::Windows::Foundation::AsyncStatus::Started) { + dispatcher.RunAsync( + winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, + [this, dispatcher]() { game_pad_->Process(); }); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + }); + + worker_loop_ = winrt::Windows::System::Threading::ThreadPool::RunAsync( + workItemHandler, winrt::Windows::System::Threading::WorkItemPriority::Low, + winrt::Windows::System::Threading::WorkItemOptions::TimeSliced); +} + +void WinRTFlutterWindow::SetupGamePad() { + DualAxisCallback leftStick = [=](double x, double y) { + OnGamePadLeftStickMoved(x, y); + }; + + DualAxisCallback rightStick = [=](double x, double y) { + OnGamePadRightStickMoved(x, y); + }; + + ButtonCallback pressedcallback = + [=](winrt::Windows::Gaming::Input::GamepadButtons buttons) { + OnGamePadButtonPressed(buttons); + }; + + ButtonCallback releasedcallback = + [=](winrt::Windows::Gaming::Input::GamepadButtons buttons) { + OnGamePadButtonReleased(buttons); + }; + GamepadAddedRemovedCallback changed = [=]() { + OnGamePadControllersChanged(); + }; + + game_pad_ = std::make_unique(leftStick, rightStick, nullptr, + nullptr, pressedcallback, + releasedcallback, changed); + game_pad_->Initialize(); +} + +void WinRTFlutterWindow::SetupXboxSpecific() { + running_on_xbox_ = + winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo() + .DeviceFamily() == L"Windows.Xbox"; + + if (running_on_xbox_) { + bool result = + winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView() + .SetDesiredBoundsMode(winrt::Windows::UI::ViewManagement:: + ApplicationViewBoundsMode::UseCoreWindow); + if (!result) { + OutputDebugString(L"Couldn't set bounds mode."); + } + + auto appView = winrt::Windows::UI::ViewManagement::ApplicationView:: + GetForCurrentView(); + auto bounds = appView.VisibleBounds(); + + // the offset /2 represents how much off-screan the core window is + // positioned unclear why disabling overscan doesn't correct this + xbox_overscan_x_offset_ = bounds.X / 2; + xbox_overscan_y_offset_ = bounds.Y / 2; + } +} + +void WinRTFlutterWindow::OnDpiChanged( + winrt::Windows::Graphics::Display::DisplayInformation const& args, + winrt::Windows::Foundation::IInspectable const&) { + ApplyInverseDpiScalingTransform(); + + auto bounds = GetBounds(current_display_info_, true); + + binding_handler_delegate_->OnWindowSizeChanged( + static_cast(bounds.width), static_cast(bounds.height)); +} + +void WinRTFlutterWindow::OnPointerPressed( + winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::PointerEventArgs const& args) { + auto x = GetPosX(args); + auto y = GetPosY(args); + + binding_handler_delegate_->OnPointerDown( + x, y, FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); +} + +void WinRTFlutterWindow::OnPointerReleased( + winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::PointerEventArgs const& args) { + auto x = GetPosX(args); + auto y = GetPosY(args); + + binding_handler_delegate_->OnPointerUp( + x, y, FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); +} + +void WinRTFlutterWindow::OnPointerMoved( + winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::PointerEventArgs const& args) { + auto x = GetPosX(args); + auto y = GetPosY(args); + + binding_handler_delegate_->OnPointerMove(x, y); +} + +void WinRTFlutterWindow::OnPointerWheelChanged( + winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::PointerEventArgs const& args) { + auto x = GetPosX(args); + auto y = GetPosY(args); + auto delta = args.CurrentPoint().Properties().MouseWheelDelta(); + binding_handler_delegate_->OnScroll(x, y, 0, -delta, 1); +} + +double WinRTFlutterWindow::GetPosX( + winrt::Windows::UI::Core::PointerEventArgs const& args) { + // TODO cache this + const double inverseDpiScale = GetDpiScale(); + + return static_cast( + (args.CurrentPoint().Position().X - xbox_overscan_x_offset_) * + inverseDpiScale); +} + +double WinRTFlutterWindow::GetPosY( + winrt::Windows::UI::Core::PointerEventArgs const& args) { + // TODO cache this + const double inverseDpiScale = GetDpiScale(); + return static_cast( + (args.CurrentPoint().Position().Y - xbox_overscan_y_offset_) * + inverseDpiScale); +} + +void WinRTFlutterWindow::OnBoundsChanged( + winrt::Windows::UI::ViewManagement::ApplicationView const& appView, + winrt::Windows::Foundation::IInspectable const&) { + if (binding_handler_delegate_) { +#ifndef USECOREWINDOW + auto bounds = GetBounds(current_display_info_, true); + + binding_handler_delegate_->OnWindowSizeChanged( + static_cast(bounds.width), static_cast(bounds.height)); + sprite_visual_.Size({bounds.width, bounds.height}); +#endif + } +} + +void WinRTFlutterWindow::OnKeyUp( + winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::KeyEventArgs const& args) { + // TODO: system key (back) and unicode handling + auto status = args.KeyStatus(); + unsigned int scancode = status.ScanCode; + int key = static_cast(args.VirtualKey()); + char32_t chararacter = static_cast(key | 32); + int action = 0x0101; + binding_handler_delegate_->OnKey(key, scancode, action, chararacter); +} + +void WinRTFlutterWindow::OnKeyDown( + winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::KeyEventArgs const& args) { + // TODO: system key (back) and unicode handling + auto status = args.KeyStatus(); + unsigned int scancode = status.ScanCode; + int key = static_cast(args.VirtualKey()); + char32_t chararacter = static_cast(key | 32); + int action = 0x0100; + binding_handler_delegate_->OnKey(key, scancode, action, chararacter); +} + +void WinRTFlutterWindow::OnCharacterReceived( + winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::CharacterReceivedEventArgs const& args) { + auto key = args.KeyCode(); + wchar_t keycode = static_cast(key); + if (keycode >= u' ') { + std::u16string text({keycode}); + binding_handler_delegate_->OnText(text); + } +} + +void WinRTFlutterWindow::OnGamePadLeftStickMoved(double x, double y) { + static const int CURSORSCALE = 30; + + auto newx = cursor_visual_.Offset().x + (CURSORSCALE * static_cast(x)); + + auto newy = + cursor_visual_.Offset().y + (CURSORSCALE * -static_cast(y)); + + auto logicalBounds = GetBounds(current_display_info_, false); + + if (newx > 0 && newy > 0 && newx < logicalBounds.width && + newy < logicalBounds.height) { + cursor_visual_.Offset({newx, newy, 0}); + if (!running_on_xbox_) { + const double inverseDpiScale = GetDpiScale(); + binding_handler_delegate_->OnPointerMove( + cursor_visual_.Offset().x * inverseDpiScale, + cursor_visual_.Offset().y * inverseDpiScale); + } else { + binding_handler_delegate_->OnPointerMove(cursor_visual_.Offset().x, + cursor_visual_.Offset().y); + } + } +} + +void WinRTFlutterWindow::OnGamePadRightStickMoved(double x, double y) { + static const double controllerScrollMultiplier = 3; + + if (!running_on_xbox_) { + const double inverseDpiScale = GetDpiScale(); + + binding_handler_delegate_->OnScroll( + cursor_visual_.Offset().x * inverseDpiScale, + cursor_visual_.Offset().y * inverseDpiScale, + x * controllerScrollMultiplier, y * controllerScrollMultiplier, 1); + } else { + binding_handler_delegate_->OnScroll( + cursor_visual_.Offset().x, cursor_visual_.Offset().y, + x * controllerScrollMultiplier, y * controllerScrollMultiplier, 1); + } +} + +void WinRTFlutterWindow::OnGamePadButtonPressed( + winrt::Windows::Gaming::Input::GamepadButtons buttons) { + if ((buttons & winrt::Windows::Gaming::Input::GamepadButtons::A) == + winrt::Windows::Gaming::Input::GamepadButtons::A) { + if (!running_on_xbox_) { + const double inverseDpiScale = GetDpiScale(); + binding_handler_delegate_->OnPointerDown( + cursor_visual_.Offset().x * inverseDpiScale, + cursor_visual_.Offset().y * inverseDpiScale, + FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); + } else { + binding_handler_delegate_->OnPointerDown( + cursor_visual_.Offset().x, cursor_visual_.Offset().y, + FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); + } + } +} + +void WinRTFlutterWindow::OnGamePadButtonReleased( + winrt::Windows::Gaming::Input::GamepadButtons buttons) { + if ((buttons & winrt::Windows::Gaming::Input::GamepadButtons::A) == + winrt::Windows::Gaming::Input::GamepadButtons::A) { + if (!running_on_xbox_) { + const double inverseDpiScale = GetDpiScale(); + + binding_handler_delegate_->OnPointerUp( + cursor_visual_.Offset().x * inverseDpiScale, + cursor_visual_.Offset().y * inverseDpiScale, + FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); + } else { + binding_handler_delegate_->OnPointerUp( + cursor_visual_.Offset().x, cursor_visual_.Offset().y, + FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); + } + } +} + +void WinRTFlutterWindow::OnGamePadControllersChanged() { + // TODO lock here + if (game_pad_->HasController()) { + if (!game_controller_thread_running_) { + if (cursor_visual_ != nullptr) { + visual_tree_root_.Children().InsertAtTop(cursor_visual_); + } + StartGamepadCursorThread(); + game_controller_thread_running_ = true; + } else { + if (cursor_visual_ != nullptr) { + visual_tree_root_.Children().Remove(cursor_visual_); + } + game_controller_thread_running_ = false; + // TODO stop game thread + } + } +} + +winrt::Windows::UI::Composition::Visual +WinRTFlutterWindow::CreateCursorVisual() { + auto container = compositor_.CreateContainerVisual(); + container.Offset( + {window_.Bounds().Width / 2, window_.Bounds().Height / 2, 1.0}); + + const float SIZE = 30; + auto cursor_visual = compositor_.CreateShapeVisual(); + cursor_visual.Size({SIZE, SIZE}); + + // compensate for overscan in cursor visual + cursor_visual.Offset({xbox_overscan_x_offset_, xbox_overscan_y_offset_, 1.0}); + + winrt::Windows::UI::Composition::CompositionEllipseGeometry circle = + compositor_.CreateEllipseGeometry(); + circle.Radius({SIZE / 2, SIZE / 2}); + + auto circleshape = compositor_.CreateSpriteShape(circle); + circleshape.FillBrush( + compositor_.CreateColorBrush(winrt::Windows::UI::Colors::Black())); + circleshape.Offset({SIZE / 2, SIZE / 2}); + + cursor_visual.Shapes().Append(circleshape); + + winrt::Windows::UI::Composition::Visual visual = + cursor_visual.as(); + + visual.CompositeMode(winrt::Windows::UI::Composition:: + CompositionCompositeMode::DestinationInvert); + + visual.AnchorPoint({0.5, 0.5}); + container.Children().InsertAtTop(visual); + + return container; +} + +} // namespace flutter diff --git a/shell/platform/windows/uwp_flutter_window.h b/shell/platform/windows/uwp_flutter_window.h new file mode 100644 index 0000000000000..a824199bcfccf --- /dev/null +++ b/shell/platform/windows/uwp_flutter_window.h @@ -0,0 +1,176 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_UWP_FLUTTER_WINDOW_H_ +#define FLUTTER_SHELL_PLATFORM_WINDOWS_UWP_FLUTTER_WINDOW_H_ + +#include "flutter/shell/platform/windows/flutter_windows_view.h" +#include "flutter/shell/platform/windows/public/flutter_windows.h" +#include "flutter/shell/platform/windows/uwp_game_pad.h" +#include "flutter/shell/platform/windows/window_binding_handler.h" + +#include "flutter/shell/platform/embedder/embedder.h" + +#include +#include +#include +#include +#include +#include +#include "winrt/Windows.System.Threading.h" +#include "winrt/Windows.UI.Core.h" + +#include +#include +#include + +namespace flutter { + +struct WinRTWindowBounds { + float width; + float height; +}; + +// Implements a UWP CoreWindow. Underlying window has been created and provided +// by the runner. +// +// Specifically handles window events within windows. +class WinRTFlutterWindow : public WindowBindingHandler { + public: + explicit WinRTFlutterWindow(ABI::Windows::UI::Core::CoreWindow* window); + + virtual ~WinRTFlutterWindow(); + + // |SetView| + void SetView(WindowBindingHandlerDelegate* view) override; + + // |GetRenderTarget| + WindowsRenderTarget GetRenderTarget() override; + + // |GetDpiScale| + float GetDpiScale() override; + + // |GetPhysicalWindowBounds| + PhysicalWindowBounds GetPhysicalWindowBounds() override; + + // |UpdateFlutterCursor| + void UpdateFlutterCursor(const std::string& cursor_name) override; + + private: + WinRTWindowBounds GetBounds( + winrt::Windows::Graphics::Display::DisplayInformation const& disp, + bool physical); + + // float GetPhysicalWidth(); + + // float GetPhysicalHeight(); + + // float GetLogicalWidth(); + + // float GetLogicalHeight(); + + // float GetWidth( + // winrt::Windows::Graphics::Display::DisplayInformation const& disp, + // bool physical); + + // float GetHeight( + // winrt::Windows::Graphics::Display::DisplayInformation const& disp, + // bool physical); + + float GetDpiScale( + winrt::Windows::Graphics::Display::DisplayInformation const&); + + void ApplyInverseDpiScalingTransform(); + + void SetEventHandlers(); + + void OnDpiChanged( + winrt::Windows::Graphics::Display::DisplayInformation const& args, + winrt::Windows::Foundation::IInspectable const&); + + void OnPointerPressed(winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::PointerEventArgs const& args); + + void OnPointerReleased( + winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::PointerEventArgs const& args); + + void OnBoundsChanged( + winrt::Windows::UI::ViewManagement::ApplicationView const& appView, + winrt::Windows::Foundation::IInspectable const&); + + void OnPointerMoved(winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::PointerEventArgs const& args); + + void OnPointerWheelChanged( + winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::PointerEventArgs const& args); + + void OnKeyUp(winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::KeyEventArgs const& args); + + void OnKeyDown(winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::KeyEventArgs const& args); + + void OnCharacterReceived( + winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::UI::Core::CharacterReceivedEventArgs const& args); + + void OnGamePadLeftStickMoved(double x, double y); + + void OnGamePadRightStickMoved(double x, double y); + + void OnGamePadButtonPressed( + winrt::Windows::Gaming::Input::GamepadButtons buttons); + + void OnGamePadButtonReleased( + winrt::Windows::Gaming::Input::GamepadButtons buttons); + + void OnGamePadControllersChanged(); + + winrt::Windows::UI::Composition::Visual CreateCursorVisual(); + + void StartGamepadCursorThread(); + + void SetupGamePad(); + + void SetupXboxSpecific(); + + double GetPosX(winrt::Windows::UI::Core::PointerEventArgs const& args); + double GetPosY(winrt::Windows::UI::Core::PointerEventArgs const& args); + + winrt::Windows::Foundation::IAsyncAction worker_loop_{nullptr}; + + // The backing CoreWindow. nullptr if not set. + winrt::Windows::UI::Core::CoreWindow window_{nullptr}; + + // A pointer to a FlutterWindowsView that can be used to update engine + // windowing and input state. + WindowBindingHandlerDelegate* binding_handler_delegate_; + + winrt::Windows::UI::Composition::Compositor compositor_{nullptr}; + + winrt::Windows::UI::Composition::CompositionTarget target_{nullptr}; + + winrt::Windows::UI::Composition::ContainerVisual visual_tree_root_{nullptr}; + + winrt::Windows::UI::Composition::Visual cursor_visual_{nullptr}; + + winrt::Windows::UI::Composition::SpriteVisual sprite_visual_{nullptr}; + + std::unique_ptr game_pad_{nullptr}; + + bool game_controller_thread_running_; + + bool running_on_xbox_; + + float xbox_overscan_x_offset_; + float xbox_overscan_y_offset_; + + winrt::Windows::Graphics::Display::DisplayInformation current_display_info_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_UWP_FLUTTER_WINDOW_H_ diff --git a/shell/platform/windows/uwp_game_pad.cc b/shell/platform/windows/uwp_game_pad.cc new file mode 100644 index 0000000000000..5a43ae2ae5b36 --- /dev/null +++ b/shell/platform/windows/uwp_game_pad.cc @@ -0,0 +1,223 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/windows/uwp_game_pad.h" + +namespace flutter { + +WinRTGamePad::WinRTGamePad(DualAxisCallback leftstick, + DualAxisCallback rightstick, + SingleAxisCallback lefttrigger, + SingleAxisCallback righttrigger, + ButtonCallback pressedcb, + ButtonCallback releasedcb, + GamepadAddedRemovedCallback changedcb) + : pressed_buttons_(winrt::Windows::Gaming::Input::GamepadButtons::None), + left_stick_x_value_(0), + left_stick_y_value_(0), + right_stick_x_value_(0), + right_stick_y_value_(0), + left_trigger_value_(0), + right_trigger_value_(0) { + left_stick_callback_ = leftstick; + right_stick_callback_ = rightstick; + + left_trigger_callback_ = lefttrigger; + right_trigger_callback_ = righttrigger; + + button_pressed_callback_ = pressedcb; + button_released_callback_ = releasedcb; + + arrival_departure_callback_ = changedcb; +} + +void WinRTGamePad::Initialize() { + RefreshCachedGamepads(); + + winrt::Windows::Gaming::Input::Gamepad::GamepadAdded( + {this, &WinRTGamePad::OnGamepadAdded}); + winrt::Windows::Gaming::Input::Gamepad::GamepadRemoved( + {this, &WinRTGamePad::OnGamepadRemoved}); + + current_game_pad_ = GetLastGamepad(); + current_gamepad_needs_refresh_ = false; +} + +bool WinRTGamePad::HasController() { + return current_game_pad_ != nullptr; +} + +void WinRTGamePad::OnGamepadAdded( + winrt::Windows::Foundation::IInspectable const& th, + winrt::Windows::Gaming::Input::Gamepad const& args) { + enumerated_game_pads_.push_back(args); + auto most_recent = GetLastGamepad(); + if (current_game_pad_ != most_recent) { + current_game_pad_ = most_recent; + } + if (this->arrival_departure_callback_ != nullptr) { + arrival_departure_callback_(); + } +} + +void WinRTGamePad::OnGamepadRemoved( + winrt::Windows::Foundation::IInspectable const&, + winrt::Windows::Gaming::Input::Gamepad const& /*args*/) { + RefreshCachedGamepads(); +} + +void WinRTGamePad::RefreshCachedGamepads() { + // enumerated_game_pads_.clear(); + // auto gamepads = winrt::Windows::Gaming::Input::Gamepad::Gamepads(); + // for (auto gamepad : gamepads) { + // enumerated_game_pads_.push_back(gamepad); + //} +} + +const winrt::Windows::Gaming::Input::Gamepad* WinRTGamePad::GetLastGamepad() { + winrt::Windows::Gaming::Input::Gamepad* gamepad = nullptr; + + if (enumerated_game_pads_.size() > 0) { + gamepad = &enumerated_game_pads_.back(); + } + + return gamepad; +} + +bool isValid(double value) { + if (value > 0.1 || value < -0.1) { + return true; + } + return false; +} + +void WinRTGamePad::Process() { + if (current_gamepad_needs_refresh_) { + auto mostRecentGamepad = GetLastGamepad(); + if (current_game_pad_ != mostRecentGamepad) { + current_game_pad_ = mostRecentGamepad; + } + current_gamepad_needs_refresh_ = false; + } + + if (current_game_pad_ == nullptr) { + return; + } + + last_reading_ = current_game_pad_->GetCurrentReading(); + + int exitComboPressed = 0; + + namespace gi = winrt::Windows::Gaming::Input; + + GamePadButtonPressedInternal(last_reading_.Buttons); + + if (last_reading_.LeftThumbstickX != left_stick_x_value_) { + left_stick_x_value_ = last_reading_.LeftThumbstickX; + } + + if (last_reading_.LeftThumbstickY != left_stick_y_value_) { + left_stick_y_value_ = last_reading_.LeftThumbstickY; + } + + if (isValid(left_stick_x_value_) || isValid(left_stick_y_value_)) { + RaiseLeftStickMoved(left_stick_x_value_, left_stick_y_value_); + } + + if (last_reading_.RightThumbstickX != right_stick_x_value_) { + right_stick_x_value_ = last_reading_.RightThumbstickX; + } + + if (last_reading_.RightThumbstickY != right_stick_y_value_) { + right_stick_y_value_ = last_reading_.RightThumbstickY; + } + + if (isValid(right_stick_x_value_) || isValid(right_stick_y_value_)) { + RaiseRightStickMoved(right_stick_x_value_, right_stick_y_value_); + } + + if (last_reading_.LeftTrigger != 0 && + last_reading_.LeftTrigger != left_trigger_value_) { + left_trigger_value_ = last_reading_.LeftTrigger; + RaiseLeftTriggerMoved(left_trigger_value_); + } + + if (last_reading_.RightTrigger != 0 && + last_reading_.RightTrigger != right_trigger_value_) { + right_trigger_value_ = last_reading_.RightTrigger; + RaiseRightTriggerMoved(right_trigger_value_); + } +} + +void WinRTGamePad::GamePadButtonPressedInternal( + winrt::Windows::Gaming::Input::GamepadButtons state) { + namespace wgi = winrt::Windows::Gaming::Input; + + static const wgi::GamepadButtons AllButtons[] = { + wgi::GamepadButtons::A, wgi::GamepadButtons::B, + wgi::GamepadButtons::DPadDown, wgi::GamepadButtons::DPadLeft, + wgi::GamepadButtons::DPadRight, wgi::GamepadButtons::DPadUp}; + + for (const auto e : AllButtons) { + // if button is pressed + if ((e & state) == e) { + // if we have not sent a pressed already + if ((pressed_buttons_ & e) != e) { + // send pressed callback + if (button_pressed_callback_ != nullptr) { + button_pressed_callback_(e); + } + + // set the bit + pressed_buttons_ |= e; + } + } + + // if button is not pressed + if ((e & state) != e) { + // if we have sent a pressed already + if ((pressed_buttons_ & e) == e) { + // send callback + if (button_released_callback_ != nullptr) { + button_released_callback_(e); + } + + // set the pressed bit + pressed_buttons_ &= ~e; + } + } + } +} + +void WinRTGamePad::RaiseGameGamePadButtonPressed( + winrt::Windows::Gaming::Input::GamepadButtons b) {} + +void WinRTGamePad::RaiseGameGamePadButtonReleased( + winrt::Windows::Gaming::Input::GamepadButtons b) {} + +void WinRTGamePad::RaiseLeftStickMoved(double x, double y) { + if (left_stick_callback_ != nullptr) { + left_stick_callback_(x, y); + } +} + +void WinRTGamePad::RaiseRightStickMoved(double x, double y) { + if (right_stick_callback_ != nullptr) { + right_stick_callback_(x, y); + } +} + +void WinRTGamePad::RaiseLeftTriggerMoved(double value) { + if (left_trigger_callback_ != nullptr) { + left_trigger_callback_(value); + } +} + +void WinRTGamePad::RaiseRightTriggerMoved(double value) { + if (right_trigger_callback_ != nullptr) { + right_trigger_callback_(value); + } +} + +} // namespace flutter diff --git a/shell/platform/windows/uwp_game_pad.h b/shell/platform/windows/uwp_game_pad.h new file mode 100644 index 0000000000000..440fdd0d9ea4b --- /dev/null +++ b/shell/platform/windows/uwp_game_pad.h @@ -0,0 +1,85 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_GAME_PAD_H_ +#define FLUTTER_SHELL_PLATFORM_WINDOWS_GAME_PAD_H_ + +#include +#include +#include + +namespace flutter { + +using SingleAxisCallback = std::function; +using DualAxisCallback = std::function; +using ButtonCallback = + std::function; +using GamepadAddedRemovedCallback = std::function; + +class WinRTGamePad { + public: + WinRTGamePad(DualAxisCallback, + DualAxisCallback, + SingleAxisCallback, + SingleAxisCallback, + ButtonCallback, + ButtonCallback, + GamepadAddedRemovedCallback); + + void Initialize(); + + void Process(); + + bool HasController(); + + private: + const winrt::Windows::Gaming::Input::Gamepad* GetLastGamepad(); + + void OnGamepadAdded(winrt::Windows::Foundation::IInspectable const& sender, + winrt::Windows::Gaming::Input::Gamepad const& args); + void OnGamepadRemoved(winrt::Windows::Foundation::IInspectable const& sender, + winrt::Windows::Gaming::Input::Gamepad const& args); + void RefreshCachedGamepads(); + + void GamePadButtonPressedInternal( + winrt::Windows::Gaming::Input::GamepadButtons b); + + void RaiseLeftStickMoved(double x, double y); + void RaiseRightStickMoved(double x, double y); + void RaiseLeftTriggerMoved(double value); + void RaiseRightTriggerMoved(double value); + + void RaiseGameGamePadButtonPressed( + winrt::Windows::Gaming::Input::GamepadButtons); + + void RaiseGameGamePadButtonReleased( + winrt::Windows::Gaming::Input::GamepadButtons); + + std::vector enumerated_game_pads_; + winrt::Windows::Gaming::Input::GamepadReading last_reading_; + const winrt::Windows::Gaming::Input::Gamepad* current_game_pad_; + + bool current_gamepad_needs_refresh_; + double left_trigger_value_; + double right_trigger_value_; + double left_stick_x_value_; + double left_stick_y_value_; + double right_stick_x_value_; + double right_stick_y_value_; + + DualAxisCallback left_stick_callback_; + DualAxisCallback right_stick_callback_; + SingleAxisCallback left_trigger_callback_; + SingleAxisCallback right_trigger_callback_; + + ButtonCallback button_pressed_callback_; + ButtonCallback button_released_callback_; + GamepadAddedRemovedCallback arrival_departure_callback_; + + winrt::Windows::Gaming::Input::GamepadButtons pressed_buttons_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_GAME_PAD_H_ diff --git a/shell/platform/windows/window_binding_handler.h b/shell/platform/windows/window_binding_handler.h index 50eba0587765f..cfa4ac132f463 100644 --- a/shell/platform/windows/window_binding_handler.h +++ b/shell/platform/windows/window_binding_handler.h @@ -7,6 +7,10 @@ #include +#ifdef WINUWP +#include +#endif + #include #include @@ -23,8 +27,14 @@ struct PhysicalWindowBounds { size_t height; }; -using WindowsRenderTarget = std::variant< - /*winrt::Windows::UI::Composition::SpriteVisual, */ HWND>; +#ifdef WINUWP +using WindowsRenderTarget = + std::variant; +#else +using WindowsRenderTarget = std::variant; +#endif // Abstract class for binding Windows platform windows to Flutter views. class WindowBindingHandler { From ff6c258e60151cd6ab5f72aed9e3c482bbb85319 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Thu, 14 Jan 2021 06:37:19 -0800 Subject: [PATCH 02/17] Enable a subset of unit tests for the winuwp target --- BUILD.gn | 4 +++- shell/platform/windows/BUILD.gn | 27 ++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index 192675c280bbd..b3911d1a4348b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -159,8 +159,10 @@ group("flutter") { if (is_win) { if (target_os == "winuwp") { - # TODO: Add winnup variant of the unit tests here; see + # TODO: Add winnup variant of client_wrapper_windows_unittests here; see # https://github.com/flutter/flutter/issues/70197 + public_deps += + [ "//flutter/shell/platform/windows:flutter_windows_unittests" ] } else { public_deps += [ "//flutter/shell/platform/windows:flutter_windows_unittests", diff --git a/shell/platform/windows/BUILD.gn b/shell/platform/windows/BUILD.gn index 313579eacff37..3fc4ea4425511 100644 --- a/shell/platform/windows/BUILD.gn +++ b/shell/platform/windows/BUILD.gn @@ -161,7 +161,32 @@ test_fixtures("flutter_windows_fixtures") { } if (target_os == "winuwp") { - # disabled until the uwp implementation is present + executable("flutter_windows_unittests") { + testonly = true + + libs = [ "windowsapp.lib" ] + + sources = [ + # "flutter_project_bundle_unittests.cc", //TODO failing due to switches test failing + # "flutter_windows_engine_unittests.cc", //TODO failing to send / receive platform message get plugins working first + "string_conversion_unittests.cc", + "system_utils_unittests.cc", + "testing/engine_embedder_api_modifier.h", + ] + + public_configs = [ "//flutter:config" ] + + deps = [ + ":flutter_windows_fixtures", + ":flutter_windows_headers", + ":flutter_windows_source", + "//flutter/shell/platform/common/cpp:common_cpp", + "//flutter/shell/platform/embedder:embedder_as_internal_library", + "//flutter/shell/platform/embedder:embedder_test_utils", + "//flutter/testing", + "//third_party/rapidjson", + ] + } } else { executable("flutter_windows_unittests") { testonly = true From f0c8f1b2a2679f8c28ecbb22ad6f7a3b766d46d2 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sun, 17 Jan 2021 03:38:10 -0800 Subject: [PATCH 03/17] CR feedback: rename UwpFlutterWindow and UwpGamePad --- ci/licenses_golden/licenses_flutter | 8 +- shell/platform/windows/BUILD.gn | 8 +- ...ter_window.cc => flutter_window_winuwp.cc} | 84 +++++++++---------- ...utter_window.h => flutter_window_winuwp.h} | 30 ++----- .../windows/flutter_windows_winuwp.cc | 4 +- .../{uwp_game_pad.cc => game_pad_winuwp.cc} | 46 +++++----- .../{uwp_game_pad.h => game_pad_winuwp.h} | 4 +- 7 files changed, 84 insertions(+), 100 deletions(-) rename shell/platform/windows/{uwp_flutter_window.cc => flutter_window_winuwp.cc} (86%) rename shell/platform/windows/{uwp_flutter_window.h => flutter_window_winuwp.h} (87%) rename shell/platform/windows/{uwp_game_pad.cc => game_pad_winuwp.cc} (83%) rename shell/platform/windows/{uwp_game_pad.h => game_pad_winuwp.h} (97%) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 7e77c15c8a964..20fd8d653d0d9 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1426,6 +1426,8 @@ FILE: ../../../flutter/shell/platform/windows/cursor_handler.h FILE: ../../../flutter/shell/platform/windows/flutter_project_bundle.cc FILE: ../../../flutter/shell/platform/windows/flutter_project_bundle.h FILE: ../../../flutter/shell/platform/windows/flutter_project_bundle_unittests.cc +FILE: ../../../flutter/shell/platform/windows/flutter_window_winuwp.cc +FILE: ../../../flutter/shell/platform/windows/flutter_window_winuwp.h FILE: ../../../flutter/shell/platform/windows/flutter_windows.cc FILE: ../../../flutter/shell/platform/windows/flutter_windows_engine.cc FILE: ../../../flutter/shell/platform/windows/flutter_windows_engine.h @@ -1434,6 +1436,8 @@ FILE: ../../../flutter/shell/platform/windows/flutter_windows_view.cc FILE: ../../../flutter/shell/platform/windows/flutter_windows_view.h FILE: ../../../flutter/shell/platform/windows/flutter_windows_win32.cc FILE: ../../../flutter/shell/platform/windows/flutter_windows_winuwp.cc +FILE: ../../../flutter/shell/platform/windows/game_pad_winuwp.cc +FILE: ../../../flutter/shell/platform/windows/game_pad_winuwp.h FILE: ../../../flutter/shell/platform/windows/key_event_handler.cc FILE: ../../../flutter/shell/platform/windows/key_event_handler.h FILE: ../../../flutter/shell/platform/windows/keyboard_hook_handler.h @@ -1457,10 +1461,6 @@ FILE: ../../../flutter/shell/platform/windows/task_runner_win32.cc FILE: ../../../flutter/shell/platform/windows/task_runner_win32.h FILE: ../../../flutter/shell/platform/windows/task_runner_winuwp.cc FILE: ../../../flutter/shell/platform/windows/task_runner_winuwp.h -FILE: ../../../flutter/shell/platform/windows/uwp_flutter_window.cc -FILE: ../../../flutter/shell/platform/windows/uwp_flutter_window.h -FILE: ../../../flutter/shell/platform/windows/uwp_game_pad.cc -FILE: ../../../flutter/shell/platform/windows/uwp_game_pad.h FILE: ../../../flutter/shell/platform/windows/text_input_plugin.cc FILE: ../../../flutter/shell/platform/windows/text_input_plugin.h FILE: ../../../flutter/shell/platform/windows/win32_dpi_utils.cc diff --git a/shell/platform/windows/BUILD.gn b/shell/platform/windows/BUILD.gn index 3fc4ea4425511..75137252e28a3 100644 --- a/shell/platform/windows/BUILD.gn +++ b/shell/platform/windows/BUILD.gn @@ -78,16 +78,16 @@ source_set("flutter_windows_source") { # Target-specific sources. if (target_os == "winuwp") { sources += [ + "flutter_window_winuwp.cc", + "flutter_window_winuwp.h", "flutter_windows_winuwp.cc", + "game_pad_winuwp.cc", + "game_pad_winuwp.h", "platform_handler_winuwp.cc", "platform_handler_winuwp.h", "system_utils_winuwp.cc", "task_runner_winuwp.cc", "task_runner_winuwp.h", - "uwp_flutter_window.cc", - "uwp_flutter_window.h", - "uwp_game_pad.cc", - "uwp_game_pad.h", ] } else { sources += [ diff --git a/shell/platform/windows/uwp_flutter_window.cc b/shell/platform/windows/flutter_window_winuwp.cc similarity index 86% rename from shell/platform/windows/uwp_flutter_window.cc rename to shell/platform/windows/flutter_window_winuwp.cc index 61c84371c549a..b9505e9155cac 100644 --- a/shell/platform/windows/uwp_flutter_window.cc +++ b/shell/platform/windows/flutter_window_winuwp.cc @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/windows/uwp_flutter_window.h" +#include "flutter/shell/platform/windows/flutter_window_winuwp.h" namespace flutter { -WinRTFlutterWindow::WinRTFlutterWindow( +FlutterWindowWinUWP::FlutterWindowWinUWP( ABI::Windows::UI::Core::CoreWindow* window) : game_controller_thread_running_(false), running_on_xbox_(false), @@ -25,7 +25,7 @@ WinRTFlutterWindow::WinRTFlutterWindow( DisplayInformation::GetForCurrentView(); } -WindowsRenderTarget WinRTFlutterWindow::GetRenderTarget() { +WindowsRenderTarget FlutterWindowWinUWP::GetRenderTarget() { #ifdef USECOREWINDOW return WindowsRenderTarget(window_); #else @@ -57,31 +57,31 @@ WindowsRenderTarget WinRTFlutterWindow::GetRenderTarget() { #endif } -void WinRTFlutterWindow::ApplyInverseDpiScalingTransform() { +void FlutterWindowWinUWP::ApplyInverseDpiScalingTransform() { // apply inverse transform to negate built in DPI scaling so we can render at // native scale auto dpiScale = GetDpiScale(); sprite_visual_.Scale({1 / dpiScale, 1 / dpiScale, 1 / dpiScale}); } -PhysicalWindowBounds WinRTFlutterWindow::GetPhysicalWindowBounds() { +PhysicalWindowBounds FlutterWindowWinUWP::GetPhysicalWindowBounds() { auto bounds = GetBounds(current_display_info_, true); return {static_cast(bounds.width), static_cast(bounds.height)}; } -void WinRTFlutterWindow::UpdateFlutterCursor(const std::string& cursor_name) { +void FlutterWindowWinUWP::UpdateFlutterCursor(const std::string& cursor_name) { // TODO } -float WinRTFlutterWindow::GetDpiScale() { +float FlutterWindowWinUWP::GetDpiScale() { auto disp = winrt::Windows::Graphics::Display::DisplayInformation:: GetForCurrentView(); return GetDpiScale(disp); } -WinRTWindowBounds WinRTFlutterWindow::GetBounds( +WindowBoundsWinUWP FlutterWindowWinUWP::GetBounds( winrt::Windows::Graphics::Display::DisplayInformation const& disp, bool physical) { auto appView = @@ -100,7 +100,7 @@ WinRTWindowBounds WinRTFlutterWindow::GetBounds( return {bounds.Width, bounds.Height}; } -float WinRTFlutterWindow::GetDpiScale( +float FlutterWindowWinUWP::GetDpiScale( winrt::Windows::Graphics::Display::DisplayInformation const& disp) { float dpi = disp.LogicalDpi(); auto rawdpi = disp.RawDpiX(); @@ -119,42 +119,42 @@ float WinRTFlutterWindow::GetDpiScale( return static_cast(rawperview); } -WinRTFlutterWindow::~WinRTFlutterWindow() { +FlutterWindowWinUWP::~FlutterWindowWinUWP() { OutputDebugString(L"Destoryed UWP FlutterWindow"); } -void WinRTFlutterWindow::SetView(WindowBindingHandlerDelegate* view) { +void FlutterWindowWinUWP::SetView(WindowBindingHandlerDelegate* view) { binding_handler_delegate_ = view; } -void WinRTFlutterWindow::SetEventHandlers() { +void FlutterWindowWinUWP::SetEventHandlers() { auto appView = winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView(); appView.SetDesiredBoundsMode(winrt::Windows::UI::ViewManagement:: ApplicationViewBoundsMode::UseCoreWindow); - appView.VisibleBoundsChanged({this, &WinRTFlutterWindow::OnBoundsChanged}); + appView.VisibleBoundsChanged({this, &FlutterWindowWinUWP::OnBoundsChanged}); - window_.PointerPressed({this, &WinRTFlutterWindow::OnPointerPressed}); - window_.PointerReleased({this, &WinRTFlutterWindow::OnPointerReleased}); - window_.PointerMoved({this, &WinRTFlutterWindow::OnPointerMoved}); + window_.PointerPressed({this, &FlutterWindowWinUWP::OnPointerPressed}); + window_.PointerReleased({this, &FlutterWindowWinUWP::OnPointerReleased}); + window_.PointerMoved({this, &FlutterWindowWinUWP::OnPointerMoved}); window_.PointerWheelChanged( - {this, &WinRTFlutterWindow::OnPointerWheelChanged}); + {this, &FlutterWindowWinUWP::OnPointerWheelChanged}); // TODO mouse leave // TODO fontchanged - window_.KeyUp({this, &WinRTFlutterWindow::OnKeyUp}); - window_.KeyDown({this, &WinRTFlutterWindow::OnKeyDown}); - window_.CharacterReceived({this, &WinRTFlutterWindow::OnCharacterReceived}); + window_.KeyUp({this, &FlutterWindowWinUWP::OnKeyUp}); + window_.KeyDown({this, &FlutterWindowWinUWP::OnKeyDown}); + window_.CharacterReceived({this, &FlutterWindowWinUWP::OnCharacterReceived}); auto disp = winrt::Windows::Graphics::Display::DisplayInformation:: GetForCurrentView(); - disp.DpiChanged({this, &WinRTFlutterWindow::OnDpiChanged}); + disp.DpiChanged({this, &FlutterWindowWinUWP::OnDpiChanged}); } -void WinRTFlutterWindow::StartGamepadCursorThread() { +void FlutterWindowWinUWP::StartGamepadCursorThread() { if (worker_loop_ != nullptr && worker_loop_.Status() == winrt::Windows::Foundation::AsyncStatus::Started) { @@ -179,7 +179,7 @@ void WinRTFlutterWindow::StartGamepadCursorThread() { winrt::Windows::System::Threading::WorkItemOptions::TimeSliced); } -void WinRTFlutterWindow::SetupGamePad() { +void FlutterWindowWinUWP::SetupGamePad() { DualAxisCallback leftStick = [=](double x, double y) { OnGamePadLeftStickMoved(x, y); }; @@ -201,13 +201,13 @@ void WinRTFlutterWindow::SetupGamePad() { OnGamePadControllersChanged(); }; - game_pad_ = std::make_unique(leftStick, rightStick, nullptr, + game_pad_ = std::make_unique(leftStick, rightStick, nullptr, nullptr, pressedcallback, releasedcallback, changed); game_pad_->Initialize(); } -void WinRTFlutterWindow::SetupXboxSpecific() { +void FlutterWindowWinUWP::SetupXboxSpecific() { running_on_xbox_ = winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo() .DeviceFamily() == L"Windows.Xbox"; @@ -232,7 +232,7 @@ void WinRTFlutterWindow::SetupXboxSpecific() { } } -void WinRTFlutterWindow::OnDpiChanged( +void FlutterWindowWinUWP::OnDpiChanged( winrt::Windows::Graphics::Display::DisplayInformation const& args, winrt::Windows::Foundation::IInspectable const&) { ApplyInverseDpiScalingTransform(); @@ -243,7 +243,7 @@ void WinRTFlutterWindow::OnDpiChanged( static_cast(bounds.width), static_cast(bounds.height)); } -void WinRTFlutterWindow::OnPointerPressed( +void FlutterWindowWinUWP::OnPointerPressed( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args) { auto x = GetPosX(args); @@ -253,7 +253,7 @@ void WinRTFlutterWindow::OnPointerPressed( x, y, FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); } -void WinRTFlutterWindow::OnPointerReleased( +void FlutterWindowWinUWP::OnPointerReleased( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args) { auto x = GetPosX(args); @@ -263,7 +263,7 @@ void WinRTFlutterWindow::OnPointerReleased( x, y, FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); } -void WinRTFlutterWindow::OnPointerMoved( +void FlutterWindowWinUWP::OnPointerMoved( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args) { auto x = GetPosX(args); @@ -272,7 +272,7 @@ void WinRTFlutterWindow::OnPointerMoved( binding_handler_delegate_->OnPointerMove(x, y); } -void WinRTFlutterWindow::OnPointerWheelChanged( +void FlutterWindowWinUWP::OnPointerWheelChanged( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args) { auto x = GetPosX(args); @@ -281,7 +281,7 @@ void WinRTFlutterWindow::OnPointerWheelChanged( binding_handler_delegate_->OnScroll(x, y, 0, -delta, 1); } -double WinRTFlutterWindow::GetPosX( +double FlutterWindowWinUWP::GetPosX( winrt::Windows::UI::Core::PointerEventArgs const& args) { // TODO cache this const double inverseDpiScale = GetDpiScale(); @@ -291,7 +291,7 @@ double WinRTFlutterWindow::GetPosX( inverseDpiScale); } -double WinRTFlutterWindow::GetPosY( +double FlutterWindowWinUWP::GetPosY( winrt::Windows::UI::Core::PointerEventArgs const& args) { // TODO cache this const double inverseDpiScale = GetDpiScale(); @@ -300,7 +300,7 @@ double WinRTFlutterWindow::GetPosY( inverseDpiScale); } -void WinRTFlutterWindow::OnBoundsChanged( +void FlutterWindowWinUWP::OnBoundsChanged( winrt::Windows::UI::ViewManagement::ApplicationView const& appView, winrt::Windows::Foundation::IInspectable const&) { if (binding_handler_delegate_) { @@ -314,7 +314,7 @@ void WinRTFlutterWindow::OnBoundsChanged( } } -void WinRTFlutterWindow::OnKeyUp( +void FlutterWindowWinUWP::OnKeyUp( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::KeyEventArgs const& args) { // TODO: system key (back) and unicode handling @@ -326,7 +326,7 @@ void WinRTFlutterWindow::OnKeyUp( binding_handler_delegate_->OnKey(key, scancode, action, chararacter); } -void WinRTFlutterWindow::OnKeyDown( +void FlutterWindowWinUWP::OnKeyDown( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::KeyEventArgs const& args) { // TODO: system key (back) and unicode handling @@ -338,7 +338,7 @@ void WinRTFlutterWindow::OnKeyDown( binding_handler_delegate_->OnKey(key, scancode, action, chararacter); } -void WinRTFlutterWindow::OnCharacterReceived( +void FlutterWindowWinUWP::OnCharacterReceived( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::CharacterReceivedEventArgs const& args) { auto key = args.KeyCode(); @@ -349,7 +349,7 @@ void WinRTFlutterWindow::OnCharacterReceived( } } -void WinRTFlutterWindow::OnGamePadLeftStickMoved(double x, double y) { +void FlutterWindowWinUWP::OnGamePadLeftStickMoved(double x, double y) { static const int CURSORSCALE = 30; auto newx = cursor_visual_.Offset().x + (CURSORSCALE * static_cast(x)); @@ -374,7 +374,7 @@ void WinRTFlutterWindow::OnGamePadLeftStickMoved(double x, double y) { } } -void WinRTFlutterWindow::OnGamePadRightStickMoved(double x, double y) { +void FlutterWindowWinUWP::OnGamePadRightStickMoved(double x, double y) { static const double controllerScrollMultiplier = 3; if (!running_on_xbox_) { @@ -391,7 +391,7 @@ void WinRTFlutterWindow::OnGamePadRightStickMoved(double x, double y) { } } -void WinRTFlutterWindow::OnGamePadButtonPressed( +void FlutterWindowWinUWP::OnGamePadButtonPressed( winrt::Windows::Gaming::Input::GamepadButtons buttons) { if ((buttons & winrt::Windows::Gaming::Input::GamepadButtons::A) == winrt::Windows::Gaming::Input::GamepadButtons::A) { @@ -409,7 +409,7 @@ void WinRTFlutterWindow::OnGamePadButtonPressed( } } -void WinRTFlutterWindow::OnGamePadButtonReleased( +void FlutterWindowWinUWP::OnGamePadButtonReleased( winrt::Windows::Gaming::Input::GamepadButtons buttons) { if ((buttons & winrt::Windows::Gaming::Input::GamepadButtons::A) == winrt::Windows::Gaming::Input::GamepadButtons::A) { @@ -428,7 +428,7 @@ void WinRTFlutterWindow::OnGamePadButtonReleased( } } -void WinRTFlutterWindow::OnGamePadControllersChanged() { +void FlutterWindowWinUWP::OnGamePadControllersChanged() { // TODO lock here if (game_pad_->HasController()) { if (!game_controller_thread_running_) { @@ -448,7 +448,7 @@ void WinRTFlutterWindow::OnGamePadControllersChanged() { } winrt::Windows::UI::Composition::Visual -WinRTFlutterWindow::CreateCursorVisual() { +FlutterWindowWinUWP::CreateCursorVisual() { auto container = compositor_.CreateContainerVisual(); container.Offset( {window_.Bounds().Width / 2, window_.Bounds().Height / 2, 1.0}); diff --git a/shell/platform/windows/uwp_flutter_window.h b/shell/platform/windows/flutter_window_winuwp.h similarity index 87% rename from shell/platform/windows/uwp_flutter_window.h rename to shell/platform/windows/flutter_window_winuwp.h index a824199bcfccf..c128f47ce0a3f 100644 --- a/shell/platform/windows/uwp_flutter_window.h +++ b/shell/platform/windows/flutter_window_winuwp.h @@ -5,9 +5,9 @@ #ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_UWP_FLUTTER_WINDOW_H_ #define FLUTTER_SHELL_PLATFORM_WINDOWS_UWP_FLUTTER_WINDOW_H_ +#include "flutter/shell/platform/windows/game_pad_winuwp.h" #include "flutter/shell/platform/windows/flutter_windows_view.h" #include "flutter/shell/platform/windows/public/flutter_windows.h" -#include "flutter/shell/platform/windows/uwp_game_pad.h" #include "flutter/shell/platform/windows/window_binding_handler.h" #include "flutter/shell/platform/embedder/embedder.h" @@ -27,7 +27,7 @@ namespace flutter { -struct WinRTWindowBounds { +struct WindowBoundsWinUWP { float width; float height; }; @@ -36,11 +36,11 @@ struct WinRTWindowBounds { // by the runner. // // Specifically handles window events within windows. -class WinRTFlutterWindow : public WindowBindingHandler { +class FlutterWindowWinUWP : public WindowBindingHandler { public: - explicit WinRTFlutterWindow(ABI::Windows::UI::Core::CoreWindow* window); + explicit FlutterWindowWinUWP(ABI::Windows::UI::Core::CoreWindow* window); - virtual ~WinRTFlutterWindow(); + virtual ~FlutterWindowWinUWP(); // |SetView| void SetView(WindowBindingHandlerDelegate* view) override; @@ -58,26 +58,10 @@ class WinRTFlutterWindow : public WindowBindingHandler { void UpdateFlutterCursor(const std::string& cursor_name) override; private: - WinRTWindowBounds GetBounds( + WindowBoundsWinUWP GetBounds( winrt::Windows::Graphics::Display::DisplayInformation const& disp, bool physical); - // float GetPhysicalWidth(); - - // float GetPhysicalHeight(); - - // float GetLogicalWidth(); - - // float GetLogicalHeight(); - - // float GetWidth( - // winrt::Windows::Graphics::Display::DisplayInformation const& disp, - // bool physical); - - // float GetHeight( - // winrt::Windows::Graphics::Display::DisplayInformation const& disp, - // bool physical); - float GetDpiScale( winrt::Windows::Graphics::Display::DisplayInformation const&); @@ -159,7 +143,7 @@ class WinRTFlutterWindow : public WindowBindingHandler { winrt::Windows::UI::Composition::SpriteVisual sprite_visual_{nullptr}; - std::unique_ptr game_pad_{nullptr}; + std::unique_ptr game_pad_{nullptr}; bool game_controller_thread_running_; diff --git a/shell/platform/windows/flutter_windows_winuwp.cc b/shell/platform/windows/flutter_windows_winuwp.cc index 5a5f45871c77b..3d2df1a0d7d54 100644 --- a/shell/platform/windows/flutter_windows_winuwp.cc +++ b/shell/platform/windows/flutter_windows_winuwp.cc @@ -15,7 +15,7 @@ #include #include -#include "flutter//shell/platform/windows/uwp_flutter_window.h" // nogncheck +#include "flutter//shell/platform/windows/flutter_window_winuwp.h" // nogncheck #include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h" #include "flutter/shell/platform/common/cpp/incoming_message_dispatcher.h" @@ -30,7 +30,7 @@ FlutterDesktopViewControllerCreateFromCoreWindow( ABI::Windows::UI::Core::CoreWindow* window, FlutterDesktopEngineRef engine) { std::unique_ptr window_wrapper = - std::make_unique(window); + std::make_unique(window); auto state = std::make_unique(); state->view = diff --git a/shell/platform/windows/uwp_game_pad.cc b/shell/platform/windows/game_pad_winuwp.cc similarity index 83% rename from shell/platform/windows/uwp_game_pad.cc rename to shell/platform/windows/game_pad_winuwp.cc index 5a43ae2ae5b36..94edeaf6ae2a1 100644 --- a/shell/platform/windows/uwp_game_pad.cc +++ b/shell/platform/windows/game_pad_winuwp.cc @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/windows/uwp_game_pad.h" +#include "flutter/shell/platform/windows/game_pad_winuwp.h" namespace flutter { -WinRTGamePad::WinRTGamePad(DualAxisCallback leftstick, +GamePadWinUWP::GamePadWinUWP(DualAxisCallback leftstick, DualAxisCallback rightstick, SingleAxisCallback lefttrigger, SingleAxisCallback righttrigger, @@ -32,23 +32,23 @@ WinRTGamePad::WinRTGamePad(DualAxisCallback leftstick, arrival_departure_callback_ = changedcb; } -void WinRTGamePad::Initialize() { +void GamePadWinUWP::Initialize() { RefreshCachedGamepads(); winrt::Windows::Gaming::Input::Gamepad::GamepadAdded( - {this, &WinRTGamePad::OnGamepadAdded}); + {this, &GamePadWinUWP::OnGamepadAdded}); winrt::Windows::Gaming::Input::Gamepad::GamepadRemoved( - {this, &WinRTGamePad::OnGamepadRemoved}); + {this, &GamePadWinUWP::OnGamepadRemoved}); current_game_pad_ = GetLastGamepad(); current_gamepad_needs_refresh_ = false; } -bool WinRTGamePad::HasController() { +bool GamePadWinUWP::HasController() { return current_game_pad_ != nullptr; } -void WinRTGamePad::OnGamepadAdded( +void GamePadWinUWP::OnGamepadAdded( winrt::Windows::Foundation::IInspectable const& th, winrt::Windows::Gaming::Input::Gamepad const& args) { enumerated_game_pads_.push_back(args); @@ -61,21 +61,21 @@ void WinRTGamePad::OnGamepadAdded( } } -void WinRTGamePad::OnGamepadRemoved( +void GamePadWinUWP::OnGamepadRemoved( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::Gaming::Input::Gamepad const& /*args*/) { RefreshCachedGamepads(); } -void WinRTGamePad::RefreshCachedGamepads() { - // enumerated_game_pads_.clear(); - // auto gamepads = winrt::Windows::Gaming::Input::Gamepad::Gamepads(); - // for (auto gamepad : gamepads) { - // enumerated_game_pads_.push_back(gamepad); - //} +void GamePadWinUWP::RefreshCachedGamepads() { + enumerated_game_pads_.clear(); + auto gamepads = winrt::Windows::Gaming::Input::Gamepad::Gamepads(); + for (auto gamepad : gamepads) { + enumerated_game_pads_.push_back(gamepad); + } } -const winrt::Windows::Gaming::Input::Gamepad* WinRTGamePad::GetLastGamepad() { +const winrt::Windows::Gaming::Input::Gamepad* GamePadWinUWP::GetLastGamepad() { winrt::Windows::Gaming::Input::Gamepad* gamepad = nullptr; if (enumerated_game_pads_.size() > 0) { @@ -92,7 +92,7 @@ bool isValid(double value) { return false; } -void WinRTGamePad::Process() { +void GamePadWinUWP::Process() { if (current_gamepad_needs_refresh_) { auto mostRecentGamepad = GetLastGamepad(); if (current_game_pad_ != mostRecentGamepad) { @@ -150,7 +150,7 @@ void WinRTGamePad::Process() { } } -void WinRTGamePad::GamePadButtonPressedInternal( +void GamePadWinUWP::GamePadButtonPressedInternal( winrt::Windows::Gaming::Input::GamepadButtons state) { namespace wgi = winrt::Windows::Gaming::Input; @@ -190,31 +190,31 @@ void WinRTGamePad::GamePadButtonPressedInternal( } } -void WinRTGamePad::RaiseGameGamePadButtonPressed( +void GamePadWinUWP::RaiseGameGamePadButtonPressed( winrt::Windows::Gaming::Input::GamepadButtons b) {} -void WinRTGamePad::RaiseGameGamePadButtonReleased( +void GamePadWinUWP::RaiseGameGamePadButtonReleased( winrt::Windows::Gaming::Input::GamepadButtons b) {} -void WinRTGamePad::RaiseLeftStickMoved(double x, double y) { +void GamePadWinUWP::RaiseLeftStickMoved(double x, double y) { if (left_stick_callback_ != nullptr) { left_stick_callback_(x, y); } } -void WinRTGamePad::RaiseRightStickMoved(double x, double y) { +void GamePadWinUWP::RaiseRightStickMoved(double x, double y) { if (right_stick_callback_ != nullptr) { right_stick_callback_(x, y); } } -void WinRTGamePad::RaiseLeftTriggerMoved(double value) { +void GamePadWinUWP::RaiseLeftTriggerMoved(double value) { if (left_trigger_callback_ != nullptr) { left_trigger_callback_(value); } } -void WinRTGamePad::RaiseRightTriggerMoved(double value) { +void GamePadWinUWP::RaiseRightTriggerMoved(double value) { if (right_trigger_callback_ != nullptr) { right_trigger_callback_(value); } diff --git a/shell/platform/windows/uwp_game_pad.h b/shell/platform/windows/game_pad_winuwp.h similarity index 97% rename from shell/platform/windows/uwp_game_pad.h rename to shell/platform/windows/game_pad_winuwp.h index 440fdd0d9ea4b..4262bef470a45 100644 --- a/shell/platform/windows/uwp_game_pad.h +++ b/shell/platform/windows/game_pad_winuwp.h @@ -17,9 +17,9 @@ using ButtonCallback = std::function; using GamepadAddedRemovedCallback = std::function; -class WinRTGamePad { +class GamePadWinUWP { public: - WinRTGamePad(DualAxisCallback, + GamePadWinUWP(DualAxisCallback, DualAxisCallback, SingleAxisCallback, SingleAxisCallback, From 11ca8f62a1319361f616abc92eebeb00f2f72c18 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sun, 17 Jan 2021 04:38:42 -0800 Subject: [PATCH 04/17] CR Feedback --- shell/platform/common/cpp/engine_switches.cc | 2 ++ .../platform/windows/flutter_window_winuwp.cc | 33 +++++++++++-------- .../platform/windows/flutter_window_winuwp.h | 2 +- shell/platform/windows/game_pad_winuwp.cc | 12 +++---- shell/platform/windows/game_pad_winuwp.h | 12 +++---- 5 files changed, 35 insertions(+), 26 deletions(-) diff --git a/shell/platform/common/cpp/engine_switches.cc b/shell/platform/common/cpp/engine_switches.cc index 98ec045425246..52bafc8738fa0 100644 --- a/shell/platform/common/cpp/engine_switches.cc +++ b/shell/platform/common/cpp/engine_switches.cc @@ -16,6 +16,8 @@ std::vector GetSwitchesFromEnvironment() { // Read engine switches from the environment in debug/profile. If release mode // support is needed in the future, it should likely use a whitelist. #ifndef FLUTTER_RELEASE +// TODO(clarkezone): figure out how to handle engine switches in UWP mode +// https://github.com/flutter/flutter/issues/74153 #ifndef WINUWP const char* switch_count_key = "FLUTTER_ENGINE_SWITCHES"; const int kMaxSwitchCount = 50; diff --git a/shell/platform/windows/flutter_window_winuwp.cc b/shell/platform/windows/flutter_window_winuwp.cc index b9505e9155cac..a623af2039fe8 100644 --- a/shell/platform/windows/flutter_window_winuwp.cc +++ b/shell/platform/windows/flutter_window_winuwp.cc @@ -71,7 +71,8 @@ PhysicalWindowBounds FlutterWindowWinUWP::GetPhysicalWindowBounds() { } void FlutterWindowWinUWP::UpdateFlutterCursor(const std::string& cursor_name) { - // TODO + // TODO(clarkezone): add support for Flutter cursors: + // https://github.com/flutter/flutter/issues/70199 } float FlutterWindowWinUWP::GetDpiScale() { @@ -108,14 +109,15 @@ float FlutterWindowWinUWP::GetDpiScale( auto scale = disp.ResolutionScale(); auto rawperview = disp.RawPixelsPerViewPixel(); + // TODO(clarkezone): ensure DPI handling is correct: // because XBOX has display scaling off, logicalDpi retuns 96 which is - // incorrect - // TODO check if rawperview is more acurate + // incorrect check if rawperview is more acurate. + // Also confirm if we need this workaround on 10X + // https://github.com/flutter/flutter/issues/70198 + if (running_on_xbox_) { return 1.5; } - // TODO do we need this on 10X? - // return dpi/96.0 * 0.8; return static_cast(rawperview); } @@ -142,8 +144,11 @@ void FlutterWindowWinUWP::SetEventHandlers() { window_.PointerWheelChanged( {this, &FlutterWindowWinUWP::OnPointerWheelChanged}); - // TODO mouse leave - // TODO fontchanged + // TODO(clarkezone) support mouse leave handling + // https://github.com/flutter/flutter/issues/70199 + + // TODO(clarkezone) support system font changed + // https://github.com/flutter/flutter/issues/70198 window_.KeyUp({this, &FlutterWindowWinUWP::OnKeyUp}); window_.KeyDown({this, &FlutterWindowWinUWP::OnKeyDown}); @@ -202,8 +207,8 @@ void FlutterWindowWinUWP::SetupGamePad() { }; game_pad_ = std::make_unique(leftStick, rightStick, nullptr, - nullptr, pressedcallback, - releasedcallback, changed); + nullptr, pressedcallback, + releasedcallback, changed); game_pad_->Initialize(); } @@ -283,7 +288,6 @@ void FlutterWindowWinUWP::OnPointerWheelChanged( double FlutterWindowWinUWP::GetPosX( winrt::Windows::UI::Core::PointerEventArgs const& args) { - // TODO cache this const double inverseDpiScale = GetDpiScale(); return static_cast( @@ -293,7 +297,6 @@ double FlutterWindowWinUWP::GetPosX( double FlutterWindowWinUWP::GetPosY( winrt::Windows::UI::Core::PointerEventArgs const& args) { - // TODO cache this const double inverseDpiScale = GetDpiScale(); return static_cast( (args.CurrentPoint().Position().Y - xbox_overscan_y_offset_) * @@ -317,7 +320,9 @@ void FlutterWindowWinUWP::OnBoundsChanged( void FlutterWindowWinUWP::OnKeyUp( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::KeyEventArgs const& args) { - // TODO: system key (back) and unicode handling + // TODO(clarkezone) complete keyboard handling including + // system key (back), unicode handling, shortcut support + // https://github.com/flutter/flutter/issues/70202 auto status = args.KeyStatus(); unsigned int scancode = status.ScanCode; int key = static_cast(args.VirtualKey()); @@ -329,7 +334,9 @@ void FlutterWindowWinUWP::OnKeyUp( void FlutterWindowWinUWP::OnKeyDown( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::KeyEventArgs const& args) { - // TODO: system key (back) and unicode handling + // TODO(clarkezone) complete keyboard handling including + // system key (back), unicode handling, shortcut support + // https://github.com/flutter/flutter/issues/70202 auto status = args.KeyStatus(); unsigned int scancode = status.ScanCode; int key = static_cast(args.VirtualKey()); diff --git a/shell/platform/windows/flutter_window_winuwp.h b/shell/platform/windows/flutter_window_winuwp.h index c128f47ce0a3f..55f4b3347f313 100644 --- a/shell/platform/windows/flutter_window_winuwp.h +++ b/shell/platform/windows/flutter_window_winuwp.h @@ -5,8 +5,8 @@ #ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_UWP_FLUTTER_WINDOW_H_ #define FLUTTER_SHELL_PLATFORM_WINDOWS_UWP_FLUTTER_WINDOW_H_ -#include "flutter/shell/platform/windows/game_pad_winuwp.h" #include "flutter/shell/platform/windows/flutter_windows_view.h" +#include "flutter/shell/platform/windows/game_pad_winuwp.h" #include "flutter/shell/platform/windows/public/flutter_windows.h" #include "flutter/shell/platform/windows/window_binding_handler.h" diff --git a/shell/platform/windows/game_pad_winuwp.cc b/shell/platform/windows/game_pad_winuwp.cc index 94edeaf6ae2a1..2f0da512ffcae 100644 --- a/shell/platform/windows/game_pad_winuwp.cc +++ b/shell/platform/windows/game_pad_winuwp.cc @@ -7,12 +7,12 @@ namespace flutter { GamePadWinUWP::GamePadWinUWP(DualAxisCallback leftstick, - DualAxisCallback rightstick, - SingleAxisCallback lefttrigger, - SingleAxisCallback righttrigger, - ButtonCallback pressedcb, - ButtonCallback releasedcb, - GamepadAddedRemovedCallback changedcb) + DualAxisCallback rightstick, + SingleAxisCallback lefttrigger, + SingleAxisCallback righttrigger, + ButtonCallback pressedcb, + ButtonCallback releasedcb, + GamepadAddedRemovedCallback changedcb) : pressed_buttons_(winrt::Windows::Gaming::Input::GamepadButtons::None), left_stick_x_value_(0), left_stick_y_value_(0), diff --git a/shell/platform/windows/game_pad_winuwp.h b/shell/platform/windows/game_pad_winuwp.h index 4262bef470a45..b18f097df950e 100644 --- a/shell/platform/windows/game_pad_winuwp.h +++ b/shell/platform/windows/game_pad_winuwp.h @@ -20,12 +20,12 @@ using GamepadAddedRemovedCallback = std::function; class GamePadWinUWP { public: GamePadWinUWP(DualAxisCallback, - DualAxisCallback, - SingleAxisCallback, - SingleAxisCallback, - ButtonCallback, - ButtonCallback, - GamepadAddedRemovedCallback); + DualAxisCallback, + SingleAxisCallback, + SingleAxisCallback, + ButtonCallback, + ButtonCallback, + GamepadAddedRemovedCallback); void Initialize(); From a4df955834c4f7069eb733a3aafd984e09c341c1 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sun, 17 Jan 2021 05:07:07 -0800 Subject: [PATCH 05/17] CR Feedback --- shell/platform/windows/BUILD.gn | 4 ++-- shell/platform/windows/system_utils_winuwp.cc | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/shell/platform/windows/BUILD.gn b/shell/platform/windows/BUILD.gn index 75137252e28a3..92f53ecfa9035 100644 --- a/shell/platform/windows/BUILD.gn +++ b/shell/platform/windows/BUILD.gn @@ -167,8 +167,8 @@ if (target_os == "winuwp") { libs = [ "windowsapp.lib" ] sources = [ - # "flutter_project_bundle_unittests.cc", //TODO failing due to switches test failing - # "flutter_windows_engine_unittests.cc", //TODO failing to send / receive platform message get plugins working first + # "flutter_project_bundle_unittests.cc", //TODO failing due to switches test failing. Blocked on https://github.com/flutter/flutter/issues/74153 + # "flutter_windows_engine_unittests.cc", //TODO failing to send / receive platform message get plugins working first. Blocked on https://github.com/flutter/flutter/issues/74155 "string_conversion_unittests.cc", "system_utils_unittests.cc", "testing/engine_embedder_api_modifier.h", diff --git a/shell/platform/windows/system_utils_winuwp.cc b/shell/platform/windows/system_utils_winuwp.cc index d23c06b9eeb8d..a37203a0e499e 100644 --- a/shell/platform/windows/system_utils_winuwp.cc +++ b/shell/platform/windows/system_utils_winuwp.cc @@ -23,6 +23,9 @@ std::vector GetPreferredLanguageInfo() { std::vector GetPreferredLanguages() { std::vector languages; + // TODO(clarkezone) need to implement a complete version of this function in + // order to get full list of platform languages + // https://github.com/flutter/flutter/issues/74156 languages.push_back(L"en-US"); languages.push_back(L"en"); From 7732cbf49a149617d25e610dd66b9a3db1d7aa03 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sun, 17 Jan 2021 16:09:55 -0800 Subject: [PATCH 06/17] PR feedback more --- shell/platform/windows/angle_surface_manager.cc | 12 ++++++------ .../client_wrapper/include/flutter/flutter_view.h | 2 +- .../include/flutter/flutter_view_controller.h | 8 ++++---- shell/platform/windows/flutter_window_winuwp.cc | 8 ++++---- shell/platform/windows/flutter_window_winuwp.h | 4 ++-- shell/platform/windows/window_binding_handler.h | 8 ++++---- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/shell/platform/windows/angle_surface_manager.cc b/shell/platform/windows/angle_surface_manager.cc index 8a8b03a36a096..6b94f6dae51c5 100644 --- a/shell/platform/windows/angle_surface_manager.cc +++ b/shell/platform/windows/angle_surface_manager.cc @@ -4,6 +4,9 @@ #include "flutter/shell/platform/windows/angle_surface_manager.h" +#include +#include + #ifdef WINUWP #include #include @@ -13,9 +16,6 @@ #include #endif -#include -#include - namespace flutter { AngleSurfaceManager::AngleSurfaceManager() @@ -204,14 +204,14 @@ bool AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target, surfaceAttributes); #else #ifdef USECOREWINDOW - auto thing = std::get(*render_target); + auto target = std::get(*render_target); #else - auto thing = + auto target = std::get(*render_target); #endif surface = eglCreateWindowSurface( egl_display_, egl_config_, - static_cast(winrt::get_abi(thing)), + static_cast(winrt::get_abi(target)), surfaceAttributes); #endif if (surface == EGL_NO_SURFACE) { diff --git a/shell/platform/windows/client_wrapper/include/flutter/flutter_view.h b/shell/platform/windows/client_wrapper/include/flutter/flutter_view.h index 91765c4477673..057d905308eb4 100644 --- a/shell/platform/windows/client_wrapper/include/flutter/flutter_view.h +++ b/shell/platform/windows/client_wrapper/include/flutter/flutter_view.h @@ -23,7 +23,7 @@ class FlutterView { #ifndef WINUWP // Returns the backing HWND for the view. HWND GetNativeWindow() { return FlutterDesktopViewGetHWND(view_); } - #endif +#endif private: // Handle for interacting with the C API's view. diff --git a/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h b/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h index 463b97c25d0a7..b35d5a2512fee 100644 --- a/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h +++ b/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h @@ -8,10 +8,6 @@ #include #include -#ifdef WINUWP -#include -#endif - #include #include @@ -21,6 +17,10 @@ #include "plugin_registrar.h" #include "plugin_registry.h" +#ifdef WINUWP +#include +#endif + namespace flutter { // A controller for a view displaying Flutter content. diff --git a/shell/platform/windows/flutter_window_winuwp.cc b/shell/platform/windows/flutter_window_winuwp.cc index a623af2039fe8..50b0df59a4746 100644 --- a/shell/platform/windows/flutter_window_winuwp.cc +++ b/shell/platform/windows/flutter_window_winuwp.cc @@ -18,8 +18,8 @@ FlutterWindowWinUWP::FlutterWindowWinUWP( window_ = cw; SetEventHandlers(); - SetupGamePad(); - SetupXboxSpecific(); + ConfigureGamePad(); + ConfigureXboxSpecific(); current_display_info_ = winrt::Windows::Graphics::Display:: DisplayInformation::GetForCurrentView(); @@ -184,7 +184,7 @@ void FlutterWindowWinUWP::StartGamepadCursorThread() { winrt::Windows::System::Threading::WorkItemOptions::TimeSliced); } -void FlutterWindowWinUWP::SetupGamePad() { +void FlutterWindowWinUWP::ConfigureGamePad() { DualAxisCallback leftStick = [=](double x, double y) { OnGamePadLeftStickMoved(x, y); }; @@ -212,7 +212,7 @@ void FlutterWindowWinUWP::SetupGamePad() { game_pad_->Initialize(); } -void FlutterWindowWinUWP::SetupXboxSpecific() { +void FlutterWindowWinUWP::ConfigureXboxSpecific() { running_on_xbox_ = winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo() .DeviceFamily() == L"Windows.Xbox"; diff --git a/shell/platform/windows/flutter_window_winuwp.h b/shell/platform/windows/flutter_window_winuwp.h index 55f4b3347f313..81c9ab054b249 100644 --- a/shell/platform/windows/flutter_window_winuwp.h +++ b/shell/platform/windows/flutter_window_winuwp.h @@ -117,9 +117,9 @@ class FlutterWindowWinUWP : public WindowBindingHandler { void StartGamepadCursorThread(); - void SetupGamePad(); + void ConfigureGamePad(); - void SetupXboxSpecific(); + void ConfigureXboxSpecific(); double GetPosX(winrt::Windows::UI::Core::PointerEventArgs const& args); double GetPosY(winrt::Windows::UI::Core::PointerEventArgs const& args); diff --git a/shell/platform/windows/window_binding_handler.h b/shell/platform/windows/window_binding_handler.h index cfa4ac132f463..90262bcdbd923 100644 --- a/shell/platform/windows/window_binding_handler.h +++ b/shell/platform/windows/window_binding_handler.h @@ -7,16 +7,16 @@ #include -#ifdef WINUWP -#include -#endif - #include #include #include "flutter/shell/platform/windows/public/flutter_windows.h" #include "flutter/shell/platform/windows/window_binding_handler_delegate.h" +#ifdef WINUWP +#include +#endif + namespace flutter { class FlutterWindowsView; From 06f1641b6ab83eed220f76f855b60098567fd7b7 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Mon, 18 Jan 2021 09:15:12 -0800 Subject: [PATCH 07/17] More PR feedback addressed --- .../platform/windows/angle_surface_manager.cc | 12 ++++---- .../client_wrapper/flutter_view_controller.cc | 16 +++++----- .../include/flutter/dart_project.h | 30 +++++++++---------- .../platform/windows/public/flutter_windows.h | 17 ++++++----- 4 files changed, 39 insertions(+), 36 deletions(-) diff --git a/shell/platform/windows/angle_surface_manager.cc b/shell/platform/windows/angle_surface_manager.cc index 6b94f6dae51c5..af6225482b110 100644 --- a/shell/platform/windows/angle_surface_manager.cc +++ b/shell/platform/windows/angle_surface_manager.cc @@ -197,12 +197,7 @@ bool AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target, EGL_FIXED_SIZE_ANGLE, EGL_TRUE, EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE}; -#ifndef WINUWP - surface = eglCreateWindowSurface( - egl_display_, egl_config_, - static_cast(std::get(*render_target)), - surfaceAttributes); -#else +#ifdef WINUWP #ifdef USECOREWINDOW auto target = std::get(*render_target); #else @@ -213,6 +208,11 @@ bool AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target, egl_display_, egl_config_, static_cast(winrt::get_abi(target)), surfaceAttributes); +#else + surface = eglCreateWindowSurface( + egl_display_, egl_config_, + static_cast(std::get(*render_target)), + surfaceAttributes); #endif if (surface == EGL_NO_SURFACE) { std::cerr << "Surface creation failed." << std::endl; diff --git a/shell/platform/windows/client_wrapper/flutter_view_controller.cc b/shell/platform/windows/client_wrapper/flutter_view_controller.cc index 727c313e37fed..789e82c8fdcc6 100644 --- a/shell/platform/windows/client_wrapper/flutter_view_controller.cc +++ b/shell/platform/windows/client_wrapper/flutter_view_controller.cc @@ -9,12 +9,13 @@ namespace flutter { -#ifndef WINUWP -FlutterViewController::FlutterViewController(int width, - int height, +#ifdef WINUWP +FlutterViewController::FlutterViewController( + ABI::Windows::UI::Core::CoreWindow* window, const DartProject& project) { engine_ = std::make_unique(project); - controller_ = FlutterDesktopViewControllerCreate(width, height, + controller_ = FlutterDesktopViewControllerCreateFromCoreWindow( + window, engine_->RelinquishEngine()); if (!controller_) { std::cerr << "Failed to create view controller." << std::endl; @@ -24,12 +25,11 @@ FlutterViewController::FlutterViewController(int width, FlutterDesktopViewControllerGetView(controller_)); } #else -FlutterViewController::FlutterViewController( - ABI::Windows::UI::Core::CoreWindow* window, +FlutterViewController::FlutterViewController(int width, + int height, const DartProject& project) { engine_ = std::make_unique(project); - controller_ = FlutterDesktopViewControllerCreateFromCoreWindow( - window, + controller_ = FlutterDesktopViewControllerCreate(width, height, engine_->RelinquishEngine()); if (!controller_) { std::cerr << "Failed to create view controller." << std::endl; diff --git a/shell/platform/windows/client_wrapper/include/flutter/dart_project.h b/shell/platform/windows/client_wrapper/include/flutter/dart_project.h index 95e5ca0d94bea..841aff500b4da 100644 --- a/shell/platform/windows/client_wrapper/include/flutter/dart_project.h +++ b/shell/platform/windows/client_wrapper/include/flutter/dart_project.h @@ -13,21 +13,7 @@ namespace flutter { // A set of Flutter and Dart assets used to initialize a Flutter engine. class DartProject { public: - #ifndef WINUWP - // Creates a DartProject from a directory path. The directory should contain - // the following top-level items: - // - icudtl.dat (provided as a resource by the Flutter tool) - // - flutter_assets (as built by the Flutter tool) - // - app.so, for an AOT build (as built by the Flutter tool) - // - // The path can either be absolute, or relative to the directory containing - // the running executable. - explicit DartProject(const std::wstring& path) { - assets_path_ = path + L"\\flutter_assets"; - icu_data_path_ = path + L"\\icudtl.dat"; - aot_library_path_ = path + L"\\app.so"; - } - #else + #ifdef WINUWP // Creates a DartProject from a series of absolute paths. // The directory should contain the following top-level items: // - icudtl.dat (provided as a resource by the Flutter tool) @@ -43,6 +29,20 @@ class DartProject { icu_data_path_ = icupath; aot_library_path_ = aotpath; } + #else + // Creates a DartProject from a directory path. The directory should contain + // the following top-level items: + // - icudtl.dat (provided as a resource by the Flutter tool) + // - flutter_assets (as built by the Flutter tool) + // - app.so, for an AOT build (as built by the Flutter tool) + // + // The path can either be absolute, or relative to the directory containing + // the running executable. + explicit DartProject(const std::wstring& path) { + assets_path_ = path + L"\\flutter_assets"; + icu_data_path_ = path + L"\\icudtl.dat"; + aot_library_path_ = path + L"\\app.so"; + } #endif ~DartProject() = default; diff --git a/shell/platform/windows/public/flutter_windows.h b/shell/platform/windows/public/flutter_windows.h index 22874534957ed..1e9ae6bc0c637 100644 --- a/shell/platform/windows/public/flutter_windows.h +++ b/shell/platform/windows/public/flutter_windows.h @@ -61,7 +61,6 @@ typedef struct { // ========== View Controller ========== -#ifndef WINUWP // Creates a view that hosts and displays the given engine instance. // // This takes ownership of |engine|, so FlutterDesktopEngineDestroy should no @@ -75,16 +74,20 @@ typedef struct { // The caller owns the returned reference, and is responsible for calling // FlutterDesktopViewControllerDestroy. Returns a null pointer in the event of // an error. -FLUTTER_EXPORT FlutterDesktopViewControllerRef -FlutterDesktopViewControllerCreate(int width, - int height, - FlutterDesktopEngineRef engine); -#else -//TODO +#ifdef WINUWP +// The CoreWindow implementation accepts a pointer to the host CoreWindow +// and view hookup is performed in the construction path. FLUTTER_EXPORT FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreateFromCoreWindow( ABI::Windows::UI::Core::CoreWindow* window, FlutterDesktopEngineRef engine); +#else //!WINUWP +// The Win32 implementation accepts width, height +// with view hookup explicitly performed using the caller using HWND parenting. +FLUTTER_EXPORT FlutterDesktopViewControllerRef +FlutterDesktopViewControllerCreate(int width, + int height, + FlutterDesktopEngineRef engine); #endif // Shuts down the engine instance associated with |controller|, and cleans up From 9acfabeb9fefb89469e4a872cce4ea791b68988a Mon Sep 17 00:00:00 2001 From: James Clarke Date: Mon, 18 Jan 2021 13:47:20 -0800 Subject: [PATCH 08/17] Add missing comments for FlutterWindowWinUWP --- .../platform/windows/flutter_window_winuwp.cc | 22 +++-- .../platform/windows/flutter_window_winuwp.h | 81 ++++++++++++++++--- 2 files changed, 77 insertions(+), 26 deletions(-) diff --git a/shell/platform/windows/flutter_window_winuwp.cc b/shell/platform/windows/flutter_window_winuwp.cc index 50b0df59a4746..ea90c16425e11 100644 --- a/shell/platform/windows/flutter_window_winuwp.cc +++ b/shell/platform/windows/flutter_window_winuwp.cc @@ -8,11 +8,7 @@ namespace flutter { FlutterWindowWinUWP::FlutterWindowWinUWP( ABI::Windows::UI::Core::CoreWindow* window) - : game_controller_thread_running_(false), - running_on_xbox_(false), - xbox_overscan_x_offset_(0), - xbox_overscan_y_offset_(0), - current_display_info_(nullptr) { + : game_controller_thread_running_(false), current_display_info_(nullptr) { winrt::Windows::UI::Core::CoreWindow cw{nullptr}; winrt::copy_from_abi(cw, window); window_ = cw; @@ -40,20 +36,20 @@ WindowsRenderTarget FlutterWindowWinUWP::GetRenderTarget() { visual_tree_root_.Children().InsertAtTop(cursor_visual_); } - sprite_visual_ = compositor_.CreateSpriteVisual(); + render_target_ = compositor_.CreateSpriteVisual(); if (running_on_xbox_) { - sprite_visual_.Offset( + render_target_.Offset( {xbox_overscan_x_offset_, xbox_overscan_y_offset_, 1.0}); } else { - sprite_visual_.Offset({1.0, 1.0, 1.0}); + render_target_.Offset({1.0, 1.0, 1.0}); ApplyInverseDpiScalingTransform(); } - visual_tree_root_.Children().InsertAtBottom(sprite_visual_); + visual_tree_root_.Children().InsertAtBottom(render_target_); auto bounds = GetBounds(current_display_info_, true); - sprite_visual_.Size({bounds.width, bounds.height}); - return WindowsRenderTarget(sprite_visual_); + render_target_.Size({bounds.width, bounds.height}); + return WindowsRenderTarget(render_target_); #endif } @@ -61,7 +57,7 @@ void FlutterWindowWinUWP::ApplyInverseDpiScalingTransform() { // apply inverse transform to negate built in DPI scaling so we can render at // native scale auto dpiScale = GetDpiScale(); - sprite_visual_.Scale({1 / dpiScale, 1 / dpiScale, 1 / dpiScale}); + render_target_.Scale({1 / dpiScale, 1 / dpiScale, 1 / dpiScale}); } PhysicalWindowBounds FlutterWindowWinUWP::GetPhysicalWindowBounds() { @@ -312,7 +308,7 @@ void FlutterWindowWinUWP::OnBoundsChanged( binding_handler_delegate_->OnWindowSizeChanged( static_cast(bounds.width), static_cast(bounds.height)); - sprite_visual_.Size({bounds.width, bounds.height}); + render_target_.Size({bounds.width, bounds.height}); #endif } } diff --git a/shell/platform/windows/flutter_window_winuwp.h b/shell/platform/windows/flutter_window_winuwp.h index 81c9ab054b249..e8030059b9269 100644 --- a/shell/platform/windows/flutter_window_winuwp.h +++ b/shell/platform/windows/flutter_window_winuwp.h @@ -42,116 +42,171 @@ class FlutterWindowWinUWP : public WindowBindingHandler { virtual ~FlutterWindowWinUWP(); - // |SetView| + // |WindowBindingHandler| void SetView(WindowBindingHandlerDelegate* view) override; - // |GetRenderTarget| + // |WindowBindingHandler| WindowsRenderTarget GetRenderTarget() override; - // |GetDpiScale| + // |WindowBindingHandler| float GetDpiScale() override; - // |GetPhysicalWindowBounds| + // |WindowBindingHandler| PhysicalWindowBounds GetPhysicalWindowBounds() override; - // |UpdateFlutterCursor| + // |WindowBindingHandler| void UpdateFlutterCursor(const std::string& cursor_name) override; private: + // Returns a bounds structure containing width and height information + // for the backing CoreWindow in either view or physical pixels depending on + // |physical|. WindowBoundsWinUWP GetBounds( winrt::Windows::Graphics::Display::DisplayInformation const& disp, bool physical); + // Returns a scaling factor representing the current DPI scale applied to the + // backing CoreWindow. float GetDpiScale( winrt::Windows::Graphics::Display::DisplayInformation const&); + // Undo the scale transform applied by the Windows compositor in order to + // render at native scale and produce smooth results on high DPI screens. void ApplyInverseDpiScalingTransform(); + // Hook up event handers for keyboard, mouse, size, DPI changed events on the + // underlying CoreWindow. void SetEventHandlers(); + // Notify current |WindowBindingHandlerDelegate| of DPI Changed events. void OnDpiChanged( winrt::Windows::Graphics::Display::DisplayInformation const& args, winrt::Windows::Foundation::IInspectable const&); + // Notify current |WindowBindingHandlerDelegate| of pointer pressed events. void OnPointerPressed(winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args); + // Notify current |WindowBindingHandlerDelegate| of pointer released events. void OnPointerReleased( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args); + // Notify current |WindowBindingHandlerDelegate| of pointer pressed events. void OnBoundsChanged( winrt::Windows::UI::ViewManagement::ApplicationView const& appView, winrt::Windows::Foundation::IInspectable const&); + // Notify current |WindowBindingHandlerDelegate| of pointer moved events. void OnPointerMoved(winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args); + // Notify current |WindowBindingHandlerDelegate| of mouse wheel events. void OnPointerWheelChanged( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args); + // Notify current |WindowBindingHandlerDelegate| of key up events. void OnKeyUp(winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::KeyEventArgs const& args); + // Notify current |WindowBindingHandlerDelegate| of key down events. void OnKeyDown(winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::KeyEventArgs const& args); + // Notify current |WindowBindingHandlerDelegate| of character received events. void OnCharacterReceived( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::CharacterReceivedEventArgs const& args); + // Notify current |WindowBindingHandlerDelegate| of gamepad right stick events + // as emulated mouse move events. void OnGamePadLeftStickMoved(double x, double y); + // Notify current |WindowBindingHandlerDelegate| of gamepad right stick move + // events delivered as emulated mouse move events. void OnGamePadRightStickMoved(double x, double y); + // Notify current |WindowBindingHandlerDelegate| of left gamepad move events + // delivered as emulated mouse button events. void OnGamePadButtonPressed( winrt::Windows::Gaming::Input::GamepadButtons buttons); + // Notify current |WindowBindingHandlerDelegate| of left gamepad move events + // delivered as emulated mouse button events. void OnGamePadButtonReleased( winrt::Windows::Gaming::Input::GamepadButtons buttons); + // Show and hide the emulated mouse cursor when a gamepad arrives / departs void OnGamePadControllersChanged(); + // Creates a visual representing the emulated cursor and add to the visual + // tree winrt::Windows::UI::Composition::Visual CreateCursorVisual(); + // Starts a low priority polling thread to translate gamepad input to emulated + // mouse events. void StartGamepadCursorThread(); + // consigure callbacks to notify when gamepad hardware events are received. void ConfigureGamePad(); + // Test is current context is running on an xbox device and perform device + // specific initialization. void ConfigureXboxSpecific(); + // Helper to convert from logical point to physical X value. double GetPosX(winrt::Windows::UI::Core::PointerEventArgs const& args); + + // Helper to convert from logical point to physical Y value. double GetPosY(winrt::Windows::UI::Core::PointerEventArgs const& args); + // Helper to convert from logical point to physical Y value. winrt::Windows::Foundation::IAsyncAction worker_loop_{nullptr}; - // The backing CoreWindow. nullptr if not set. + // Member variable holding the backing CoreWindow. nullptr if not set. winrt::Windows::UI::Core::CoreWindow window_{nullptr}; - // A pointer to a FlutterWindowsView that can be used to update engine - // windowing and input state. + // Member variable containing a pointer to a FlutterWindowsView that can be + // used to update engine windowing and input state. WindowBindingHandlerDelegate* binding_handler_delegate_; + // Member variable holding the current active compositor. nullptr if not set. winrt::Windows::UI::Composition::Compositor compositor_{nullptr}; + // Member variable holding the current CompositionTarget for binding the + // rendering context to the CoreWindow. nullptr if not set. winrt::Windows::UI::Composition::CompositionTarget target_{nullptr}; + // Member variable holding the composition tree root object. winrt::Windows::UI::Composition::ContainerVisual visual_tree_root_{nullptr}; + // Member variable holding the composition visual representing the emulated + // cursor visual. winrt::Windows::UI::Composition::Visual cursor_visual_{nullptr}; - winrt::Windows::UI::Composition::SpriteVisual sprite_visual_{nullptr}; + // Compositor object that represents the render target binding the backing + // SwapChain to the CoreWindow. + winrt::Windows::UI::Composition::SpriteVisual render_target_{nullptr}; + // Object responsible for handling the low level interactions with the + // gamepad. std::unique_ptr game_pad_{nullptr}; - bool game_controller_thread_running_; + // Member variable tracking if there is currently a gamepad thread running. + bool game_controller_thread_running_ = false; + + // Member variable tracking if the current context is executing on an XBOX + // device. + bool running_on_xbox_ = false; - bool running_on_xbox_; + // Member variable storing the current X overscan compensation factor. + float xbox_overscan_x_offset_ = 0.0f; - float xbox_overscan_x_offset_; - float xbox_overscan_y_offset_; + // Member variable storing the current Y overscan compensation factor. + float xbox_overscan_y_offset_ = 0.0f; + // Member variable storing the most recent display information. winrt::Windows::Graphics::Display::DisplayInformation current_display_info_; }; From da719b09360812147670025c479bb80ae4fb160b Mon Sep 17 00:00:00 2001 From: James Clarke Date: Tue, 19 Jan 2021 19:49:39 -0800 Subject: [PATCH 09/17] Fix build --- shell/platform/windows/angle_surface_manager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/windows/angle_surface_manager.cc b/shell/platform/windows/angle_surface_manager.cc index af6225482b110..f2695facc6a1f 100644 --- a/shell/platform/windows/angle_surface_manager.cc +++ b/shell/platform/windows/angle_surface_manager.cc @@ -12,7 +12,7 @@ #include #endif -#ifdef USECOREWINDOW +#ifdef WINUWP && USECOREWINDOW #include #endif From 886a3adb54d8a2d80b9e2b196fd5e79303937766 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Tue, 19 Jan 2021 19:58:19 -0800 Subject: [PATCH 10/17] Fix the build --- shell/platform/windows/angle_surface_manager.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/windows/angle_surface_manager.cc b/shell/platform/windows/angle_surface_manager.cc index f2695facc6a1f..6862e3afb3131 100644 --- a/shell/platform/windows/angle_surface_manager.cc +++ b/shell/platform/windows/angle_surface_manager.cc @@ -12,7 +12,7 @@ #include #endif -#ifdef WINUWP && USECOREWINDOW +#if defined(WINUWP) && defined(USECOREWINDOW) #include #endif From 2f25d5ef91c50b4d557cb14e7f0a32a774abfbaf Mon Sep 17 00:00:00 2001 From: James Clarke Date: Tue, 19 Jan 2021 20:13:00 -0800 Subject: [PATCH 11/17] Format --- .../windows/client_wrapper/flutter_view_controller.cc | 5 ++--- .../windows/client_wrapper/include/flutter/dart_project.h | 6 +++--- .../include/flutter/flutter_view_controller.h | 3 +-- shell/platform/windows/public/flutter_windows.h | 4 ++-- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/shell/platform/windows/client_wrapper/flutter_view_controller.cc b/shell/platform/windows/client_wrapper/flutter_view_controller.cc index 789e82c8fdcc6..a4c5a465a1c21 100644 --- a/shell/platform/windows/client_wrapper/flutter_view_controller.cc +++ b/shell/platform/windows/client_wrapper/flutter_view_controller.cc @@ -12,11 +12,10 @@ namespace flutter { #ifdef WINUWP FlutterViewController::FlutterViewController( ABI::Windows::UI::Core::CoreWindow* window, - const DartProject& project) { + const DartProject& project) { engine_ = std::make_unique(project); controller_ = FlutterDesktopViewControllerCreateFromCoreWindow( - window, - engine_->RelinquishEngine()); + window, engine_->RelinquishEngine()); if (!controller_) { std::cerr << "Failed to create view controller." << std::endl; return; diff --git a/shell/platform/windows/client_wrapper/include/flutter/dart_project.h b/shell/platform/windows/client_wrapper/include/flutter/dart_project.h index 841aff500b4da..13d883d420051 100644 --- a/shell/platform/windows/client_wrapper/include/flutter/dart_project.h +++ b/shell/platform/windows/client_wrapper/include/flutter/dart_project.h @@ -13,7 +13,7 @@ namespace flutter { // A set of Flutter and Dart assets used to initialize a Flutter engine. class DartProject { public: - #ifdef WINUWP +#ifdef WINUWP // Creates a DartProject from a series of absolute paths. // The directory should contain the following top-level items: // - icudtl.dat (provided as a resource by the Flutter tool) @@ -29,7 +29,7 @@ class DartProject { icu_data_path_ = icupath; aot_library_path_ = aotpath; } - #else +#else // Creates a DartProject from a directory path. The directory should contain // the following top-level items: // - icudtl.dat (provided as a resource by the Flutter tool) @@ -43,7 +43,7 @@ class DartProject { icu_data_path_ = path + L"\\icudtl.dat"; aot_library_path_ = path + L"\\app.so"; } - #endif +#endif ~DartProject() = default; diff --git a/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h b/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h index b35d5a2512fee..dcab4a7f84229 100644 --- a/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h +++ b/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h @@ -43,8 +43,7 @@ class FlutterViewController { // either using CoreWindow. // // |dart_project| will be used to configure the engine backing this view. - explicit FlutterViewController( - ABI::Windows::UI::Core::CoreWindow* window, + explicit FlutterViewController(ABI::Windows::UI::Core::CoreWindow* window, const DartProject& project); #endif diff --git a/shell/platform/windows/public/flutter_windows.h b/shell/platform/windows/public/flutter_windows.h index 1e9ae6bc0c637..6f4a9b853ae7d 100644 --- a/shell/platform/windows/public/flutter_windows.h +++ b/shell/platform/windows/public/flutter_windows.h @@ -80,8 +80,8 @@ typedef struct { FLUTTER_EXPORT FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreateFromCoreWindow( ABI::Windows::UI::Core::CoreWindow* window, - FlutterDesktopEngineRef engine); -#else //!WINUWP + FlutterDesktopEngineRef engine); +#else //! WINUWP // The Win32 implementation accepts width, height // with view hookup explicitly performed using the caller using HWND parenting. FLUTTER_EXPORT FlutterDesktopViewControllerRef From 04c3b0ebb8ed41ae0715146ee1d406a7c3ecff0e Mon Sep 17 00:00:00 2001 From: James Clarke Date: Wed, 20 Jan 2021 21:16:29 -0800 Subject: [PATCH 12/17] Moah CR feedback --- .../platform/windows/flutter_window_winuwp.cc | 111 ++++++++---------- .../platform/windows/flutter_window_winuwp.h | 74 ++++++------ shell/platform/windows/key_event_handler.cc | 2 + .../platform/windows/public/flutter_windows.h | 8 +- 4 files changed, 99 insertions(+), 96 deletions(-) diff --git a/shell/platform/windows/flutter_window_winuwp.cc b/shell/platform/windows/flutter_window_winuwp.cc index ea90c16425e11..8ca60b02735e0 100644 --- a/shell/platform/windows/flutter_window_winuwp.cc +++ b/shell/platform/windows/flutter_window_winuwp.cc @@ -7,8 +7,7 @@ namespace flutter { FlutterWindowWinUWP::FlutterWindowWinUWP( - ABI::Windows::UI::Core::CoreWindow* window) - : game_controller_thread_running_(false), current_display_info_(nullptr) { + ABI::Windows::UI::Core::CoreWindow* window) { winrt::Windows::UI::Core::CoreWindow cw{nullptr}; winrt::copy_from_abi(cw, window); window_ = cw; @@ -54,8 +53,8 @@ WindowsRenderTarget FlutterWindowWinUWP::GetRenderTarget() { } void FlutterWindowWinUWP::ApplyInverseDpiScalingTransform() { - // apply inverse transform to negate built in DPI scaling so we can render at - // native scale + // Apply inverse transform to negate built in DPI scaling in order to render + // at native scale. auto dpiScale = GetDpiScale(); render_target_.Scale({1 / dpiScale, 1 / dpiScale, 1 / dpiScale}); } @@ -81,9 +80,9 @@ float FlutterWindowWinUWP::GetDpiScale() { WindowBoundsWinUWP FlutterWindowWinUWP::GetBounds( winrt::Windows::Graphics::Display::DisplayInformation const& disp, bool physical) { - auto appView = + winrt::Windows::UI::ViewManagement::ApplicationView app_view = winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView(); - auto bounds = appView.VisibleBounds(); + winrt::Windows::Foundation::Rect bounds = app_view.VisibleBounds(); if (running_on_xbox_) { return {bounds.Width + (bounds.X), bounds.Height + (bounds.Y)}; } @@ -100,39 +99,37 @@ WindowBoundsWinUWP FlutterWindowWinUWP::GetBounds( float FlutterWindowWinUWP::GetDpiScale( winrt::Windows::Graphics::Display::DisplayInformation const& disp) { float dpi = disp.LogicalDpi(); - auto rawdpi = disp.RawDpiX(); - auto rawwidth = disp.ScreenHeightInRawPixels(); + auto raw_dpi = disp.RawDpiX(); + auto raw_width = disp.ScreenHeightInRawPixels(); auto scale = disp.ResolutionScale(); - auto rawperview = disp.RawPixelsPerViewPixel(); + auto raw_per_view = disp.RawPixelsPerViewPixel(); // TODO(clarkezone): ensure DPI handling is correct: // because XBOX has display scaling off, logicalDpi retuns 96 which is - // incorrect check if rawperview is more acurate. - // Also confirm if we need this workaround on 10X + // incorrect check if raw_per_view is more acurate. + // Also confirm if it is necessary to use this workaround on 10X // https://github.com/flutter/flutter/issues/70198 if (running_on_xbox_) { return 1.5; } - return static_cast(rawperview); + return static_cast(raw_per_view); } -FlutterWindowWinUWP::~FlutterWindowWinUWP() { - OutputDebugString(L"Destoryed UWP FlutterWindow"); -} +FlutterWindowWinUWP::~FlutterWindowWinUWP() {} void FlutterWindowWinUWP::SetView(WindowBindingHandlerDelegate* view) { binding_handler_delegate_ = view; } void FlutterWindowWinUWP::SetEventHandlers() { - auto appView = + auto app_view = winrt::Windows::UI::ViewManagement::ApplicationView::GetForCurrentView(); - appView.SetDesiredBoundsMode(winrt::Windows::UI::ViewManagement:: - ApplicationViewBoundsMode::UseCoreWindow); + app_view.SetDesiredBoundsMode(winrt::Windows::UI::ViewManagement:: + ApplicationViewBoundsMode::UseCoreWindow); - appView.VisibleBoundsChanged({this, &FlutterWindowWinUWP::OnBoundsChanged}); + app_view.VisibleBoundsChanged({this, &FlutterWindowWinUWP::OnBoundsChanged}); window_.PointerPressed({this, &FlutterWindowWinUWP::OnPointerPressed}); window_.PointerReleased({this, &FlutterWindowWinUWP::OnPointerReleased}); @@ -150,9 +147,9 @@ void FlutterWindowWinUWP::SetEventHandlers() { window_.KeyDown({this, &FlutterWindowWinUWP::OnKeyDown}); window_.CharacterReceived({this, &FlutterWindowWinUWP::OnCharacterReceived}); - auto disp = winrt::Windows::Graphics::Display::DisplayInformation:: + auto display = winrt::Windows::Graphics::Display::DisplayInformation:: GetForCurrentView(); - disp.DpiChanged({this, &FlutterWindowWinUWP::OnDpiChanged}); + display.DpiChanged({this, &FlutterWindowWinUWP::OnDpiChanged}); } void FlutterWindowWinUWP::StartGamepadCursorThread() { @@ -222,9 +219,9 @@ void FlutterWindowWinUWP::ConfigureXboxSpecific() { OutputDebugString(L"Couldn't set bounds mode."); } - auto appView = winrt::Windows::UI::ViewManagement::ApplicationView:: - GetForCurrentView(); - auto bounds = appView.VisibleBounds(); + winrt::Windows::UI::ViewManagement::ApplicationView app_view = winrt:: + Windows::UI::ViewManagement::ApplicationView::GetForCurrentView(); + winrt::Windows::Foundation::Rect bounds = app_view.VisibleBounds(); // the offset /2 represents how much off-screan the core window is // positioned unclear why disabling overscan doesn't correct this @@ -238,7 +235,7 @@ void FlutterWindowWinUWP::OnDpiChanged( winrt::Windows::Foundation::IInspectable const&) { ApplyInverseDpiScalingTransform(); - auto bounds = GetBounds(current_display_info_, true); + WindowBoundsWinUWP bounds = GetBounds(current_display_info_, true); binding_handler_delegate_->OnWindowSizeChanged( static_cast(bounds.width), static_cast(bounds.height)); @@ -284,33 +281,32 @@ void FlutterWindowWinUWP::OnPointerWheelChanged( double FlutterWindowWinUWP::GetPosX( winrt::Windows::UI::Core::PointerEventArgs const& args) { - const double inverseDpiScale = GetDpiScale(); + const double inverse_dpi_scale = GetDpiScale(); - return static_cast( - (args.CurrentPoint().Position().X - xbox_overscan_x_offset_) * - inverseDpiScale); + return (args.CurrentPoint().Position().X - xbox_overscan_x_offset_) * + inverse_dpi_scale; } double FlutterWindowWinUWP::GetPosY( winrt::Windows::UI::Core::PointerEventArgs const& args) { - const double inverseDpiScale = GetDpiScale(); + const double inverse_dpi_scale = GetDpiScale(); return static_cast( (args.CurrentPoint().Position().Y - xbox_overscan_y_offset_) * - inverseDpiScale); + inverse_dpi_scale); } void FlutterWindowWinUWP::OnBoundsChanged( - winrt::Windows::UI::ViewManagement::ApplicationView const& appView, + winrt::Windows::UI::ViewManagement::ApplicationView const& app_view, winrt::Windows::Foundation::IInspectable const&) { - if (binding_handler_delegate_) { #ifndef USECOREWINDOW + if (binding_handler_delegate_) { auto bounds = GetBounds(current_display_info_, true); binding_handler_delegate_->OnWindowSizeChanged( static_cast(bounds.width), static_cast(bounds.height)); render_target_.Size({bounds.width, bounds.height}); -#endif } +#endif } void FlutterWindowWinUWP::OnKeyUp( @@ -353,23 +349,22 @@ void FlutterWindowWinUWP::OnCharacterReceived( } void FlutterWindowWinUWP::OnGamePadLeftStickMoved(double x, double y) { - static const int CURSORSCALE = 30; + float new_x = + cursor_visual_.Offset().x + (kCursorScale * static_cast(x)); - auto newx = cursor_visual_.Offset().x + (CURSORSCALE * static_cast(x)); + float new_y = + cursor_visual_.Offset().y + (kCursorScale * -static_cast(y)); - auto newy = - cursor_visual_.Offset().y + (CURSORSCALE * -static_cast(y)); + WindowBoundsWinUWP logical_bounds = GetBounds(current_display_info_, false); - auto logicalBounds = GetBounds(current_display_info_, false); - - if (newx > 0 && newy > 0 && newx < logicalBounds.width && - newy < logicalBounds.height) { - cursor_visual_.Offset({newx, newy, 0}); + if (new_x > 0 && new_y > 0 && new_x < logical_bounds.width && + new_y < logical_bounds.height) { + cursor_visual_.Offset({new_x, new_y, 0}); if (!running_on_xbox_) { - const double inverseDpiScale = GetDpiScale(); + const double inverse_dpi_scale = GetDpiScale(); binding_handler_delegate_->OnPointerMove( - cursor_visual_.Offset().x * inverseDpiScale, - cursor_visual_.Offset().y * inverseDpiScale); + cursor_visual_.Offset().x * inverse_dpi_scale, + cursor_visual_.Offset().y * inverse_dpi_scale); } else { binding_handler_delegate_->OnPointerMove(cursor_visual_.Offset().x, cursor_visual_.Offset().y); @@ -378,19 +373,17 @@ void FlutterWindowWinUWP::OnGamePadLeftStickMoved(double x, double y) { } void FlutterWindowWinUWP::OnGamePadRightStickMoved(double x, double y) { - static const double controllerScrollMultiplier = 3; - if (!running_on_xbox_) { - const double inverseDpiScale = GetDpiScale(); + const double inverse_dpi_scale = GetDpiScale(); binding_handler_delegate_->OnScroll( - cursor_visual_.Offset().x * inverseDpiScale, - cursor_visual_.Offset().y * inverseDpiScale, - x * controllerScrollMultiplier, y * controllerScrollMultiplier, 1); + cursor_visual_.Offset().x * inverse_dpi_scale, + cursor_visual_.Offset().y * inverse_dpi_scale, + x * kControllerScrollMultiplier, y * kControllerScrollMultiplier, 1); } else { binding_handler_delegate_->OnScroll( cursor_visual_.Offset().x, cursor_visual_.Offset().y, - x * controllerScrollMultiplier, y * controllerScrollMultiplier, 1); + x * kControllerScrollMultiplier, y * kControllerScrollMultiplier, 1); } } @@ -399,10 +392,10 @@ void FlutterWindowWinUWP::OnGamePadButtonPressed( if ((buttons & winrt::Windows::Gaming::Input::GamepadButtons::A) == winrt::Windows::Gaming::Input::GamepadButtons::A) { if (!running_on_xbox_) { - const double inverseDpiScale = GetDpiScale(); + const double inverse_dpi_scale = GetDpiScale(); binding_handler_delegate_->OnPointerDown( - cursor_visual_.Offset().x * inverseDpiScale, - cursor_visual_.Offset().y * inverseDpiScale, + cursor_visual_.Offset().x * inverse_dpi_scale, + cursor_visual_.Offset().y * inverse_dpi_scale, FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); } else { binding_handler_delegate_->OnPointerDown( @@ -417,11 +410,11 @@ void FlutterWindowWinUWP::OnGamePadButtonReleased( if ((buttons & winrt::Windows::Gaming::Input::GamepadButtons::A) == winrt::Windows::Gaming::Input::GamepadButtons::A) { if (!running_on_xbox_) { - const double inverseDpiScale = GetDpiScale(); + const double inverse_dpi_scale = GetDpiScale(); binding_handler_delegate_->OnPointerUp( - cursor_visual_.Offset().x * inverseDpiScale, - cursor_visual_.Offset().y * inverseDpiScale, + cursor_visual_.Offset().x * inverse_dpi_scale, + cursor_visual_.Offset().y * inverse_dpi_scale, FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); } else { binding_handler_delegate_->OnPointerUp( diff --git a/shell/platform/windows/flutter_window_winuwp.h b/shell/platform/windows/flutter_window_winuwp.h index e8030059b9269..38eed355547f2 100644 --- a/shell/platform/windows/flutter_window_winuwp.h +++ b/shell/platform/windows/flutter_window_winuwp.h @@ -70,69 +70,70 @@ class FlutterWindowWinUWP : public WindowBindingHandler { float GetDpiScale( winrt::Windows::Graphics::Display::DisplayInformation const&); - // Undo the scale transform applied by the Windows compositor in order to + // Undoes the scale transform applied by the Windows compositor in order to // render at native scale and produce smooth results on high DPI screens. void ApplyInverseDpiScalingTransform(); - // Hook up event handers for keyboard, mouse, size, DPI changed events on the + // Hooks up event handers for keyboard, mouse, size, DPI changed events on the // underlying CoreWindow. void SetEventHandlers(); - // Notify current |WindowBindingHandlerDelegate| of DPI Changed events. + // Notifies current |WindowBindingHandlerDelegate| of DPI Changed events. void OnDpiChanged( winrt::Windows::Graphics::Display::DisplayInformation const& args, winrt::Windows::Foundation::IInspectable const&); - // Notify current |WindowBindingHandlerDelegate| of pointer pressed events. + // Notifies current |WindowBindingHandlerDelegate| of pointer pressed events. void OnPointerPressed(winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args); - // Notify current |WindowBindingHandlerDelegate| of pointer released events. + // Notifies current |WindowBindingHandlerDelegate| of pointer released events. void OnPointerReleased( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args); - // Notify current |WindowBindingHandlerDelegate| of pointer pressed events. + // Notifies current |WindowBindingHandlerDelegate| of pointer pressed events. void OnBoundsChanged( winrt::Windows::UI::ViewManagement::ApplicationView const& appView, winrt::Windows::Foundation::IInspectable const&); - // Notify current |WindowBindingHandlerDelegate| of pointer moved events. + // Notifies current |WindowBindingHandlerDelegate| of pointer moved events. void OnPointerMoved(winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args); - // Notify current |WindowBindingHandlerDelegate| of mouse wheel events. + // Notifies current |WindowBindingHandlerDelegate| of mouse wheel events. void OnPointerWheelChanged( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args); - // Notify current |WindowBindingHandlerDelegate| of key up events. + // Notifies current |WindowBindingHandlerDelegate| of key up events. void OnKeyUp(winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::KeyEventArgs const& args); - // Notify current |WindowBindingHandlerDelegate| of key down events. + // Notifies current |WindowBindingHandlerDelegate| of key down events. void OnKeyDown(winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::KeyEventArgs const& args); - // Notify current |WindowBindingHandlerDelegate| of character received events. + // Notifies current |WindowBindingHandlerDelegate| of character received + // events. void OnCharacterReceived( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::CharacterReceivedEventArgs const& args); - // Notify current |WindowBindingHandlerDelegate| of gamepad right stick events - // as emulated mouse move events. + // Notifies current |WindowBindingHandlerDelegate| of gamepad right stick + // events as emulated mouse move events. void OnGamePadLeftStickMoved(double x, double y); - // Notify current |WindowBindingHandlerDelegate| of gamepad right stick move - // events delivered as emulated mouse move events. + // Notifies current |WindowBindingHandlerDelegate| of gamepad right stick + // events delivered as scroll events. void OnGamePadRightStickMoved(double x, double y); - // Notify current |WindowBindingHandlerDelegate| of left gamepad move events + // Notifies current |WindowBindingHandlerDelegate| of left gamepad move events // delivered as emulated mouse button events. void OnGamePadButtonPressed( winrt::Windows::Gaming::Input::GamepadButtons buttons); - // Notify current |WindowBindingHandlerDelegate| of left gamepad move events + // Notifies current |WindowBindingHandlerDelegate| of left gamepad move events // delivered as emulated mouse button events. void OnGamePadButtonReleased( winrt::Windows::Gaming::Input::GamepadButtons buttons); @@ -148,40 +149,40 @@ class FlutterWindowWinUWP : public WindowBindingHandler { // mouse events. void StartGamepadCursorThread(); - // consigure callbacks to notify when gamepad hardware events are received. + // consigure callbacks to Notifies when gamepad hardware events are received. void ConfigureGamePad(); // Test is current context is running on an xbox device and perform device // specific initialization. void ConfigureXboxSpecific(); - // Helper to convert from logical point to physical X value. + // Converts from logical point to physical X value. double GetPosX(winrt::Windows::UI::Core::PointerEventArgs const& args); - // Helper to convert from logical point to physical Y value. + // Converts from logical point to physical Y value. double GetPosY(winrt::Windows::UI::Core::PointerEventArgs const& args); - // Helper to convert from logical point to physical Y value. + // Token representing current worker thread. winrt::Windows::Foundation::IAsyncAction worker_loop_{nullptr}; - // Member variable holding the backing CoreWindow. nullptr if not set. + // Backing CoreWindow. nullptr if not set. winrt::Windows::UI::Core::CoreWindow window_{nullptr}; - // Member variable containing a pointer to a FlutterWindowsView that can be + // Pointer to a FlutterWindowsView that can be // used to update engine windowing and input state. WindowBindingHandlerDelegate* binding_handler_delegate_; - // Member variable holding the current active compositor. nullptr if not set. + // Current active compositor. nullptr if not set. winrt::Windows::UI::Composition::Compositor compositor_{nullptr}; - // Member variable holding the current CompositionTarget for binding the + // Current CompositionTarget for binding the // rendering context to the CoreWindow. nullptr if not set. winrt::Windows::UI::Composition::CompositionTarget target_{nullptr}; - // Member variable holding the composition tree root object. + // Composition tree root object. winrt::Windows::UI::Composition::ContainerVisual visual_tree_root_{nullptr}; - // Member variable holding the composition visual representing the emulated + // Composition visual representing the emulated // cursor visual. winrt::Windows::UI::Composition::Visual cursor_visual_{nullptr}; @@ -193,21 +194,28 @@ class FlutterWindowWinUWP : public WindowBindingHandler { // gamepad. std::unique_ptr game_pad_{nullptr}; - // Member variable tracking if there is currently a gamepad thread running. + // A gamepad thread running is running or not. bool game_controller_thread_running_ = false; - // Member variable tracking if the current context is executing on an XBOX + // Is current context is executing on an XBOX // device. bool running_on_xbox_ = false; - // Member variable storing the current X overscan compensation factor. + // Current X overscan compensation factor. float xbox_overscan_x_offset_ = 0.0f; - // Member variable storing the current Y overscan compensation factor. + // Current Y overscan compensation factor. float xbox_overscan_y_offset_ = 0.0f; - // Member variable storing the most recent display information. - winrt::Windows::Graphics::Display::DisplayInformation current_display_info_; + // Most recent display information. + winrt::Windows::Graphics::Display::DisplayInformation current_display_info_{ + nullptr}; + + // Multipler used to map controller velocity to an appropriate scroll input. + const double kControllerScrollMultiplier = 3; + + // Multiplier used to scale gamepad input to mouse equivalent response. + const int kCursorScale = 30; }; } // namespace flutter diff --git a/shell/platform/windows/key_event_handler.cc b/shell/platform/windows/key_event_handler.cc index a4587a364e30b..0723cf575cdfc 100644 --- a/shell/platform/windows/key_event_handler.cc +++ b/shell/platform/windows/key_event_handler.cc @@ -45,6 +45,8 @@ const int kNumLock = 1 << 12; const int kScrollLock = 1 << 13; namespace { +// TODO(clarkezone) need to add support for get keystate +// https://github.com/flutter/flutter/issues/70202 #ifndef WINUWP /// Calls GetKeyState() an all modifier keys and packs the result in an int, /// with the re-defined values declared above for compatibility with the Flutter diff --git a/shell/platform/windows/public/flutter_windows.h b/shell/platform/windows/public/flutter_windows.h index 6f4a9b853ae7d..f574e12de2c87 100644 --- a/shell/platform/windows/public/flutter_windows.h +++ b/shell/platform/windows/public/flutter_windows.h @@ -9,14 +9,14 @@ #include #include -#ifdef WINUWP -#include -#endif - #include "flutter_export.h" #include "flutter_messenger.h" #include "flutter_plugin_registrar.h" +#ifdef WINUWP +#include +#endif + #if defined(__cplusplus) extern "C" { #endif From d16603b44a264f54c5b3497fc83f5c4fe017b71d Mon Sep 17 00:00:00 2001 From: James Clarke Date: Thu, 21 Jan 2021 18:11:01 -0800 Subject: [PATCH 13/17] More CR feedback --- shell/platform/windows/BUILD.gn | 84 ++++++++----------- .../include/flutter/dart_project.h | 3 +- 2 files changed, 36 insertions(+), 51 deletions(-) diff --git a/shell/platform/windows/BUILD.gn b/shell/platform/windows/BUILD.gn index 92f53ecfa9035..86c614585c7e3 100644 --- a/shell/platform/windows/BUILD.gn +++ b/shell/platform/windows/BUILD.gn @@ -13,10 +13,6 @@ config("relative_angle_headers") { include_dirs = [ "//third_party/angle/include" ] } -config("usecorewindow") { - defines = [ "USECOREWINDOW" ] -} - # Any files that are built by clients (client_wrapper code, library headers for # implementations using this shared code, etc.) include the public headers # assuming they are in the include path. This configuration should be added to @@ -111,12 +107,14 @@ source_set("flutter_windows_source") { configs += [ "//flutter/shell/platform/common/cpp:desktop_library_implementation", "//third_party/angle:gl_prototypes", - ":usecorewindow", ] public_configs = [ ":relative_angle_headers" ] - defines = [ "FLUTTER_ENGINE_NO_PROTOTYPES" ] + defines = [ + "FLUTTER_ENGINE_NO_PROTOTYPES", + "USECOREWINDOW", + ] deps = [ ":flutter_windows_headers", @@ -160,43 +158,31 @@ test_fixtures("flutter_windows_fixtures") { fixtures = [] } -if (target_os == "winuwp") { - executable("flutter_windows_unittests") { - testonly = true +executable("flutter_windows_unittests") { + testonly = true + if (target_os == "winuwp") { libs = [ "windowsapp.lib" ] - - sources = [ - # "flutter_project_bundle_unittests.cc", //TODO failing due to switches test failing. Blocked on https://github.com/flutter/flutter/issues/74153 - # "flutter_windows_engine_unittests.cc", //TODO failing to send / receive platform message get plugins working first. Blocked on https://github.com/flutter/flutter/issues/74155 - "string_conversion_unittests.cc", - "system_utils_unittests.cc", - "testing/engine_embedder_api_modifier.h", - ] - - public_configs = [ "//flutter:config" ] - - deps = [ - ":flutter_windows_fixtures", - ":flutter_windows_headers", - ":flutter_windows_source", - "//flutter/shell/platform/common/cpp:common_cpp", - "//flutter/shell/platform/embedder:embedder_as_internal_library", - "//flutter/shell/platform/embedder:embedder_test_utils", - "//flutter/testing", - "//third_party/rapidjson", - ] } -} else { - executable("flutter_windows_unittests") { - testonly = true - sources = [ + # Common Windows test sources. + sources = [ + # "flutter_project_bundle_unittests.cc", //TODO failing due to switches test failing. Blocked on https://github.com/flutter/flutter/issues/74153 + # "flutter_windows_engine_unittests.cc", //TODO failing to send / receive platform message get plugins working first. Blocked on https://github.com/flutter/flutter/issues/74155 + "string_conversion_unittests.cc", + "system_utils_unittests.cc", + "testing/engine_embedder_api_modifier.h", + ] + + # Target-specific sources. + if (target_os == "winuwp") { + # TODO(clarkezone) add UWP tests + # https://github.com/flutter/flutter/issues/70197 + } else { + sources += [ + # TODO move first two tests to common once above TODO's unblocked. "flutter_project_bundle_unittests.cc", "flutter_windows_engine_unittests.cc", - "string_conversion_unittests.cc", - "system_utils_unittests.cc", - "testing/engine_embedder_api_modifier.h", "testing/mock_win32_window.cc", "testing/mock_win32_window.h", "testing/win32_flutter_window_test.cc", @@ -206,20 +192,20 @@ if (target_os == "winuwp") { "win32_window_proc_delegate_manager_unittests.cc", "win32_window_unittests.cc", ] + } - public_configs = [ "//flutter:config" ] + public_configs = [ "//flutter:config" ] - deps = [ - ":flutter_windows_fixtures", - ":flutter_windows_headers", - ":flutter_windows_source", - "//flutter/shell/platform/common/cpp:common_cpp", - "//flutter/shell/platform/embedder:embedder_as_internal_library", - "//flutter/shell/platform/embedder:embedder_test_utils", - "//flutter/testing", - "//third_party/rapidjson", - ] - } + deps = [ + ":flutter_windows_fixtures", + ":flutter_windows_headers", + ":flutter_windows_source", + "//flutter/shell/platform/common/cpp:common_cpp", + "//flutter/shell/platform/embedder:embedder_as_internal_library", + "//flutter/shell/platform/embedder:embedder_test_utils", + "//flutter/testing", + "//third_party/rapidjson", + ] } shared_library("flutter_windows_glfw") { diff --git a/shell/platform/windows/client_wrapper/include/flutter/dart_project.h b/shell/platform/windows/client_wrapper/include/flutter/dart_project.h index 13d883d420051..e0ff9d7f23547 100644 --- a/shell/platform/windows/client_wrapper/include/flutter/dart_project.h +++ b/shell/platform/windows/client_wrapper/include/flutter/dart_project.h @@ -20,8 +20,7 @@ class DartProject { // - flutter_assets (as built by the Flutter tool) // - app.so, for an AOT build (as built by the Flutter tool) // - // The path can either be absolute, or relative to the directory containing - // the running executable. + // The path must be absolute. explicit DartProject(const std::wstring& assetspath, const std::wstring& icupath, const std::wstring& aotpath) { From 58728c26468da7927f41c3c8882e0e47516a2aa4 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Thu, 21 Jan 2021 18:46:55 -0800 Subject: [PATCH 14/17] Fix UWP build post ToT merge --- shell/platform/windows/flutter_window_winuwp.cc | 2 ++ shell/platform/windows/flutter_window_winuwp.h | 3 +++ shell/platform/windows/task_runner_winuwp.cc | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/shell/platform/windows/flutter_window_winuwp.cc b/shell/platform/windows/flutter_window_winuwp.cc index 8ca60b02735e0..1a09b0c6298b0 100644 --- a/shell/platform/windows/flutter_window_winuwp.cc +++ b/shell/platform/windows/flutter_window_winuwp.cc @@ -70,6 +70,8 @@ void FlutterWindowWinUWP::UpdateFlutterCursor(const std::string& cursor_name) { // https://github.com/flutter/flutter/issues/70199 } +void FlutterWindowWinUWP::OnWindowResized() {} + float FlutterWindowWinUWP::GetDpiScale() { auto disp = winrt::Windows::Graphics::Display::DisplayInformation:: GetForCurrentView(); diff --git a/shell/platform/windows/flutter_window_winuwp.h b/shell/platform/windows/flutter_window_winuwp.h index 38eed355547f2..b290b64a3d8e4 100644 --- a/shell/platform/windows/flutter_window_winuwp.h +++ b/shell/platform/windows/flutter_window_winuwp.h @@ -57,6 +57,9 @@ class FlutterWindowWinUWP : public WindowBindingHandler { // |WindowBindingHandler| void UpdateFlutterCursor(const std::string& cursor_name) override; + // |WindowBindingHandler| + void OnWindowResized() override; + private: // Returns a bounds structure containing width and height information // for the backing CoreWindow in either view or physical pixels depending on diff --git a/shell/platform/windows/task_runner_winuwp.cc b/shell/platform/windows/task_runner_winuwp.cc index 8bfc4c9cbd2cc..d6c5c6bc70d93 100644 --- a/shell/platform/windows/task_runner_winuwp.cc +++ b/shell/platform/windows/task_runner_winuwp.cc @@ -45,7 +45,7 @@ void TaskRunnerWinUwp::PostTask(TaskClosure task) { // TODO: Handle the target time. See PostFlutterTask() dispatcher_.RunAsync(winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, - [task]() { task() }); + [task]() { task(); }); } } // namespace flutter From 8c5b93465aee61a61685f67045e2327b85a81a10 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Thu, 21 Jan 2021 19:02:09 -0800 Subject: [PATCH 15/17] Remove gamepad implementation (to be re-added in a seperate PR) --- ci/licenses_golden/licenses_flutter | 2 - shell/platform/windows/BUILD.gn | 2 - .../platform/windows/flutter_window_winuwp.cc | 153 ------------ .../platform/windows/flutter_window_winuwp.h | 40 ---- shell/platform/windows/game_pad_winuwp.cc | 223 ------------------ shell/platform/windows/game_pad_winuwp.h | 85 ------- 6 files changed, 505 deletions(-) delete mode 100644 shell/platform/windows/game_pad_winuwp.cc delete mode 100644 shell/platform/windows/game_pad_winuwp.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 329252d44a20c..e428c598b2f5d 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1465,8 +1465,6 @@ FILE: ../../../flutter/shell/platform/windows/flutter_windows_view.cc FILE: ../../../flutter/shell/platform/windows/flutter_windows_view.h FILE: ../../../flutter/shell/platform/windows/flutter_windows_win32.cc FILE: ../../../flutter/shell/platform/windows/flutter_windows_winuwp.cc -FILE: ../../../flutter/shell/platform/windows/game_pad_winuwp.cc -FILE: ../../../flutter/shell/platform/windows/game_pad_winuwp.h FILE: ../../../flutter/shell/platform/windows/key_event_handler.cc FILE: ../../../flutter/shell/platform/windows/key_event_handler.h FILE: ../../../flutter/shell/platform/windows/keyboard_hook_handler.h diff --git a/shell/platform/windows/BUILD.gn b/shell/platform/windows/BUILD.gn index dd2b854457420..57372e0c8467f 100644 --- a/shell/platform/windows/BUILD.gn +++ b/shell/platform/windows/BUILD.gn @@ -81,8 +81,6 @@ source_set("flutter_windows_source") { "flutter_window_winuwp.cc", "flutter_window_winuwp.h", "flutter_windows_winuwp.cc", - "game_pad_winuwp.cc", - "game_pad_winuwp.h", "platform_handler_winuwp.cc", "platform_handler_winuwp.h", "system_utils_winuwp.cc", diff --git a/shell/platform/windows/flutter_window_winuwp.cc b/shell/platform/windows/flutter_window_winuwp.cc index 1a09b0c6298b0..1f0ebb8d82441 100644 --- a/shell/platform/windows/flutter_window_winuwp.cc +++ b/shell/platform/windows/flutter_window_winuwp.cc @@ -13,7 +13,6 @@ FlutterWindowWinUWP::FlutterWindowWinUWP( window_ = cw; SetEventHandlers(); - ConfigureGamePad(); ConfigureXboxSpecific(); current_display_info_ = winrt::Windows::Graphics::Display:: @@ -31,10 +30,6 @@ WindowsRenderTarget FlutterWindowWinUWP::GetRenderTarget() { cursor_visual_ = CreateCursorVisual(); - if (game_controller_thread_running_) { - visual_tree_root_.Children().InsertAtTop(cursor_visual_); - } - render_target_ = compositor_.CreateSpriteVisual(); if (running_on_xbox_) { render_target_.Offset( @@ -154,59 +149,6 @@ void FlutterWindowWinUWP::SetEventHandlers() { display.DpiChanged({this, &FlutterWindowWinUWP::OnDpiChanged}); } -void FlutterWindowWinUWP::StartGamepadCursorThread() { - if (worker_loop_ != nullptr && - worker_loop_.Status() == - winrt::Windows::Foundation::AsyncStatus::Started) { - return; - } - - winrt::Windows::UI::Core::CoreDispatcher dispatcher = window_.Dispatcher(); - - auto workItemHandler = winrt::Windows::System::Threading::WorkItemHandler( - [this, dispatcher](winrt::Windows::Foundation::IAsyncAction action) { - while (action.Status() == - winrt::Windows::Foundation::AsyncStatus::Started) { - dispatcher.RunAsync( - winrt::Windows::UI::Core::CoreDispatcherPriority::Normal, - [this, dispatcher]() { game_pad_->Process(); }); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - }); - - worker_loop_ = winrt::Windows::System::Threading::ThreadPool::RunAsync( - workItemHandler, winrt::Windows::System::Threading::WorkItemPriority::Low, - winrt::Windows::System::Threading::WorkItemOptions::TimeSliced); -} - -void FlutterWindowWinUWP::ConfigureGamePad() { - DualAxisCallback leftStick = [=](double x, double y) { - OnGamePadLeftStickMoved(x, y); - }; - - DualAxisCallback rightStick = [=](double x, double y) { - OnGamePadRightStickMoved(x, y); - }; - - ButtonCallback pressedcallback = - [=](winrt::Windows::Gaming::Input::GamepadButtons buttons) { - OnGamePadButtonPressed(buttons); - }; - - ButtonCallback releasedcallback = - [=](winrt::Windows::Gaming::Input::GamepadButtons buttons) { - OnGamePadButtonReleased(buttons); - }; - GamepadAddedRemovedCallback changed = [=]() { - OnGamePadControllersChanged(); - }; - - game_pad_ = std::make_unique(leftStick, rightStick, nullptr, - nullptr, pressedcallback, - releasedcallback, changed); - game_pad_->Initialize(); -} - void FlutterWindowWinUWP::ConfigureXboxSpecific() { running_on_xbox_ = winrt::Windows::System::Profile::AnalyticsInfo::VersionInfo() @@ -350,101 +292,6 @@ void FlutterWindowWinUWP::OnCharacterReceived( } } -void FlutterWindowWinUWP::OnGamePadLeftStickMoved(double x, double y) { - float new_x = - cursor_visual_.Offset().x + (kCursorScale * static_cast(x)); - - float new_y = - cursor_visual_.Offset().y + (kCursorScale * -static_cast(y)); - - WindowBoundsWinUWP logical_bounds = GetBounds(current_display_info_, false); - - if (new_x > 0 && new_y > 0 && new_x < logical_bounds.width && - new_y < logical_bounds.height) { - cursor_visual_.Offset({new_x, new_y, 0}); - if (!running_on_xbox_) { - const double inverse_dpi_scale = GetDpiScale(); - binding_handler_delegate_->OnPointerMove( - cursor_visual_.Offset().x * inverse_dpi_scale, - cursor_visual_.Offset().y * inverse_dpi_scale); - } else { - binding_handler_delegate_->OnPointerMove(cursor_visual_.Offset().x, - cursor_visual_.Offset().y); - } - } -} - -void FlutterWindowWinUWP::OnGamePadRightStickMoved(double x, double y) { - if (!running_on_xbox_) { - const double inverse_dpi_scale = GetDpiScale(); - - binding_handler_delegate_->OnScroll( - cursor_visual_.Offset().x * inverse_dpi_scale, - cursor_visual_.Offset().y * inverse_dpi_scale, - x * kControllerScrollMultiplier, y * kControllerScrollMultiplier, 1); - } else { - binding_handler_delegate_->OnScroll( - cursor_visual_.Offset().x, cursor_visual_.Offset().y, - x * kControllerScrollMultiplier, y * kControllerScrollMultiplier, 1); - } -} - -void FlutterWindowWinUWP::OnGamePadButtonPressed( - winrt::Windows::Gaming::Input::GamepadButtons buttons) { - if ((buttons & winrt::Windows::Gaming::Input::GamepadButtons::A) == - winrt::Windows::Gaming::Input::GamepadButtons::A) { - if (!running_on_xbox_) { - const double inverse_dpi_scale = GetDpiScale(); - binding_handler_delegate_->OnPointerDown( - cursor_visual_.Offset().x * inverse_dpi_scale, - cursor_visual_.Offset().y * inverse_dpi_scale, - FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); - } else { - binding_handler_delegate_->OnPointerDown( - cursor_visual_.Offset().x, cursor_visual_.Offset().y, - FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); - } - } -} - -void FlutterWindowWinUWP::OnGamePadButtonReleased( - winrt::Windows::Gaming::Input::GamepadButtons buttons) { - if ((buttons & winrt::Windows::Gaming::Input::GamepadButtons::A) == - winrt::Windows::Gaming::Input::GamepadButtons::A) { - if (!running_on_xbox_) { - const double inverse_dpi_scale = GetDpiScale(); - - binding_handler_delegate_->OnPointerUp( - cursor_visual_.Offset().x * inverse_dpi_scale, - cursor_visual_.Offset().y * inverse_dpi_scale, - FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); - } else { - binding_handler_delegate_->OnPointerUp( - cursor_visual_.Offset().x, cursor_visual_.Offset().y, - FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); - } - } -} - -void FlutterWindowWinUWP::OnGamePadControllersChanged() { - // TODO lock here - if (game_pad_->HasController()) { - if (!game_controller_thread_running_) { - if (cursor_visual_ != nullptr) { - visual_tree_root_.Children().InsertAtTop(cursor_visual_); - } - StartGamepadCursorThread(); - game_controller_thread_running_ = true; - } else { - if (cursor_visual_ != nullptr) { - visual_tree_root_.Children().Remove(cursor_visual_); - } - game_controller_thread_running_ = false; - // TODO stop game thread - } - } -} - winrt::Windows::UI::Composition::Visual FlutterWindowWinUWP::CreateCursorVisual() { auto container = compositor_.CreateContainerVisual(); diff --git a/shell/platform/windows/flutter_window_winuwp.h b/shell/platform/windows/flutter_window_winuwp.h index b290b64a3d8e4..802f6b15c177d 100644 --- a/shell/platform/windows/flutter_window_winuwp.h +++ b/shell/platform/windows/flutter_window_winuwp.h @@ -6,13 +6,11 @@ #define FLUTTER_SHELL_PLATFORM_WINDOWS_UWP_FLUTTER_WINDOW_H_ #include "flutter/shell/platform/windows/flutter_windows_view.h" -#include "flutter/shell/platform/windows/game_pad_winuwp.h" #include "flutter/shell/platform/windows/public/flutter_windows.h" #include "flutter/shell/platform/windows/window_binding_handler.h" #include "flutter/shell/platform/embedder/embedder.h" -#include #include #include #include @@ -123,38 +121,10 @@ class FlutterWindowWinUWP : public WindowBindingHandler { winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::CharacterReceivedEventArgs const& args); - // Notifies current |WindowBindingHandlerDelegate| of gamepad right stick - // events as emulated mouse move events. - void OnGamePadLeftStickMoved(double x, double y); - - // Notifies current |WindowBindingHandlerDelegate| of gamepad right stick - // events delivered as scroll events. - void OnGamePadRightStickMoved(double x, double y); - - // Notifies current |WindowBindingHandlerDelegate| of left gamepad move events - // delivered as emulated mouse button events. - void OnGamePadButtonPressed( - winrt::Windows::Gaming::Input::GamepadButtons buttons); - - // Notifies current |WindowBindingHandlerDelegate| of left gamepad move events - // delivered as emulated mouse button events. - void OnGamePadButtonReleased( - winrt::Windows::Gaming::Input::GamepadButtons buttons); - - // Show and hide the emulated mouse cursor when a gamepad arrives / departs - void OnGamePadControllersChanged(); - // Creates a visual representing the emulated cursor and add to the visual // tree winrt::Windows::UI::Composition::Visual CreateCursorVisual(); - // Starts a low priority polling thread to translate gamepad input to emulated - // mouse events. - void StartGamepadCursorThread(); - - // consigure callbacks to Notifies when gamepad hardware events are received. - void ConfigureGamePad(); - // Test is current context is running on an xbox device and perform device // specific initialization. void ConfigureXboxSpecific(); @@ -193,13 +163,6 @@ class FlutterWindowWinUWP : public WindowBindingHandler { // SwapChain to the CoreWindow. winrt::Windows::UI::Composition::SpriteVisual render_target_{nullptr}; - // Object responsible for handling the low level interactions with the - // gamepad. - std::unique_ptr game_pad_{nullptr}; - - // A gamepad thread running is running or not. - bool game_controller_thread_running_ = false; - // Is current context is executing on an XBOX // device. bool running_on_xbox_ = false; @@ -216,9 +179,6 @@ class FlutterWindowWinUWP : public WindowBindingHandler { // Multipler used to map controller velocity to an appropriate scroll input. const double kControllerScrollMultiplier = 3; - - // Multiplier used to scale gamepad input to mouse equivalent response. - const int kCursorScale = 30; }; } // namespace flutter diff --git a/shell/platform/windows/game_pad_winuwp.cc b/shell/platform/windows/game_pad_winuwp.cc deleted file mode 100644 index 2f0da512ffcae..0000000000000 --- a/shell/platform/windows/game_pad_winuwp.cc +++ /dev/null @@ -1,223 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/shell/platform/windows/game_pad_winuwp.h" - -namespace flutter { - -GamePadWinUWP::GamePadWinUWP(DualAxisCallback leftstick, - DualAxisCallback rightstick, - SingleAxisCallback lefttrigger, - SingleAxisCallback righttrigger, - ButtonCallback pressedcb, - ButtonCallback releasedcb, - GamepadAddedRemovedCallback changedcb) - : pressed_buttons_(winrt::Windows::Gaming::Input::GamepadButtons::None), - left_stick_x_value_(0), - left_stick_y_value_(0), - right_stick_x_value_(0), - right_stick_y_value_(0), - left_trigger_value_(0), - right_trigger_value_(0) { - left_stick_callback_ = leftstick; - right_stick_callback_ = rightstick; - - left_trigger_callback_ = lefttrigger; - right_trigger_callback_ = righttrigger; - - button_pressed_callback_ = pressedcb; - button_released_callback_ = releasedcb; - - arrival_departure_callback_ = changedcb; -} - -void GamePadWinUWP::Initialize() { - RefreshCachedGamepads(); - - winrt::Windows::Gaming::Input::Gamepad::GamepadAdded( - {this, &GamePadWinUWP::OnGamepadAdded}); - winrt::Windows::Gaming::Input::Gamepad::GamepadRemoved( - {this, &GamePadWinUWP::OnGamepadRemoved}); - - current_game_pad_ = GetLastGamepad(); - current_gamepad_needs_refresh_ = false; -} - -bool GamePadWinUWP::HasController() { - return current_game_pad_ != nullptr; -} - -void GamePadWinUWP::OnGamepadAdded( - winrt::Windows::Foundation::IInspectable const& th, - winrt::Windows::Gaming::Input::Gamepad const& args) { - enumerated_game_pads_.push_back(args); - auto most_recent = GetLastGamepad(); - if (current_game_pad_ != most_recent) { - current_game_pad_ = most_recent; - } - if (this->arrival_departure_callback_ != nullptr) { - arrival_departure_callback_(); - } -} - -void GamePadWinUWP::OnGamepadRemoved( - winrt::Windows::Foundation::IInspectable const&, - winrt::Windows::Gaming::Input::Gamepad const& /*args*/) { - RefreshCachedGamepads(); -} - -void GamePadWinUWP::RefreshCachedGamepads() { - enumerated_game_pads_.clear(); - auto gamepads = winrt::Windows::Gaming::Input::Gamepad::Gamepads(); - for (auto gamepad : gamepads) { - enumerated_game_pads_.push_back(gamepad); - } -} - -const winrt::Windows::Gaming::Input::Gamepad* GamePadWinUWP::GetLastGamepad() { - winrt::Windows::Gaming::Input::Gamepad* gamepad = nullptr; - - if (enumerated_game_pads_.size() > 0) { - gamepad = &enumerated_game_pads_.back(); - } - - return gamepad; -} - -bool isValid(double value) { - if (value > 0.1 || value < -0.1) { - return true; - } - return false; -} - -void GamePadWinUWP::Process() { - if (current_gamepad_needs_refresh_) { - auto mostRecentGamepad = GetLastGamepad(); - if (current_game_pad_ != mostRecentGamepad) { - current_game_pad_ = mostRecentGamepad; - } - current_gamepad_needs_refresh_ = false; - } - - if (current_game_pad_ == nullptr) { - return; - } - - last_reading_ = current_game_pad_->GetCurrentReading(); - - int exitComboPressed = 0; - - namespace gi = winrt::Windows::Gaming::Input; - - GamePadButtonPressedInternal(last_reading_.Buttons); - - if (last_reading_.LeftThumbstickX != left_stick_x_value_) { - left_stick_x_value_ = last_reading_.LeftThumbstickX; - } - - if (last_reading_.LeftThumbstickY != left_stick_y_value_) { - left_stick_y_value_ = last_reading_.LeftThumbstickY; - } - - if (isValid(left_stick_x_value_) || isValid(left_stick_y_value_)) { - RaiseLeftStickMoved(left_stick_x_value_, left_stick_y_value_); - } - - if (last_reading_.RightThumbstickX != right_stick_x_value_) { - right_stick_x_value_ = last_reading_.RightThumbstickX; - } - - if (last_reading_.RightThumbstickY != right_stick_y_value_) { - right_stick_y_value_ = last_reading_.RightThumbstickY; - } - - if (isValid(right_stick_x_value_) || isValid(right_stick_y_value_)) { - RaiseRightStickMoved(right_stick_x_value_, right_stick_y_value_); - } - - if (last_reading_.LeftTrigger != 0 && - last_reading_.LeftTrigger != left_trigger_value_) { - left_trigger_value_ = last_reading_.LeftTrigger; - RaiseLeftTriggerMoved(left_trigger_value_); - } - - if (last_reading_.RightTrigger != 0 && - last_reading_.RightTrigger != right_trigger_value_) { - right_trigger_value_ = last_reading_.RightTrigger; - RaiseRightTriggerMoved(right_trigger_value_); - } -} - -void GamePadWinUWP::GamePadButtonPressedInternal( - winrt::Windows::Gaming::Input::GamepadButtons state) { - namespace wgi = winrt::Windows::Gaming::Input; - - static const wgi::GamepadButtons AllButtons[] = { - wgi::GamepadButtons::A, wgi::GamepadButtons::B, - wgi::GamepadButtons::DPadDown, wgi::GamepadButtons::DPadLeft, - wgi::GamepadButtons::DPadRight, wgi::GamepadButtons::DPadUp}; - - for (const auto e : AllButtons) { - // if button is pressed - if ((e & state) == e) { - // if we have not sent a pressed already - if ((pressed_buttons_ & e) != e) { - // send pressed callback - if (button_pressed_callback_ != nullptr) { - button_pressed_callback_(e); - } - - // set the bit - pressed_buttons_ |= e; - } - } - - // if button is not pressed - if ((e & state) != e) { - // if we have sent a pressed already - if ((pressed_buttons_ & e) == e) { - // send callback - if (button_released_callback_ != nullptr) { - button_released_callback_(e); - } - - // set the pressed bit - pressed_buttons_ &= ~e; - } - } - } -} - -void GamePadWinUWP::RaiseGameGamePadButtonPressed( - winrt::Windows::Gaming::Input::GamepadButtons b) {} - -void GamePadWinUWP::RaiseGameGamePadButtonReleased( - winrt::Windows::Gaming::Input::GamepadButtons b) {} - -void GamePadWinUWP::RaiseLeftStickMoved(double x, double y) { - if (left_stick_callback_ != nullptr) { - left_stick_callback_(x, y); - } -} - -void GamePadWinUWP::RaiseRightStickMoved(double x, double y) { - if (right_stick_callback_ != nullptr) { - right_stick_callback_(x, y); - } -} - -void GamePadWinUWP::RaiseLeftTriggerMoved(double value) { - if (left_trigger_callback_ != nullptr) { - left_trigger_callback_(value); - } -} - -void GamePadWinUWP::RaiseRightTriggerMoved(double value) { - if (right_trigger_callback_ != nullptr) { - right_trigger_callback_(value); - } -} - -} // namespace flutter diff --git a/shell/platform/windows/game_pad_winuwp.h b/shell/platform/windows/game_pad_winuwp.h deleted file mode 100644 index b18f097df950e..0000000000000 --- a/shell/platform/windows/game_pad_winuwp.h +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_GAME_PAD_H_ -#define FLUTTER_SHELL_PLATFORM_WINDOWS_GAME_PAD_H_ - -#include -#include -#include - -namespace flutter { - -using SingleAxisCallback = std::function; -using DualAxisCallback = std::function; -using ButtonCallback = - std::function; -using GamepadAddedRemovedCallback = std::function; - -class GamePadWinUWP { - public: - GamePadWinUWP(DualAxisCallback, - DualAxisCallback, - SingleAxisCallback, - SingleAxisCallback, - ButtonCallback, - ButtonCallback, - GamepadAddedRemovedCallback); - - void Initialize(); - - void Process(); - - bool HasController(); - - private: - const winrt::Windows::Gaming::Input::Gamepad* GetLastGamepad(); - - void OnGamepadAdded(winrt::Windows::Foundation::IInspectable const& sender, - winrt::Windows::Gaming::Input::Gamepad const& args); - void OnGamepadRemoved(winrt::Windows::Foundation::IInspectable const& sender, - winrt::Windows::Gaming::Input::Gamepad const& args); - void RefreshCachedGamepads(); - - void GamePadButtonPressedInternal( - winrt::Windows::Gaming::Input::GamepadButtons b); - - void RaiseLeftStickMoved(double x, double y); - void RaiseRightStickMoved(double x, double y); - void RaiseLeftTriggerMoved(double value); - void RaiseRightTriggerMoved(double value); - - void RaiseGameGamePadButtonPressed( - winrt::Windows::Gaming::Input::GamepadButtons); - - void RaiseGameGamePadButtonReleased( - winrt::Windows::Gaming::Input::GamepadButtons); - - std::vector enumerated_game_pads_; - winrt::Windows::Gaming::Input::GamepadReading last_reading_; - const winrt::Windows::Gaming::Input::Gamepad* current_game_pad_; - - bool current_gamepad_needs_refresh_; - double left_trigger_value_; - double right_trigger_value_; - double left_stick_x_value_; - double left_stick_y_value_; - double right_stick_x_value_; - double right_stick_y_value_; - - DualAxisCallback left_stick_callback_; - DualAxisCallback right_stick_callback_; - SingleAxisCallback left_trigger_callback_; - SingleAxisCallback right_trigger_callback_; - - ButtonCallback button_pressed_callback_; - ButtonCallback button_released_callback_; - GamepadAddedRemovedCallback arrival_departure_callback_; - - winrt::Windows::Gaming::Input::GamepadButtons pressed_buttons_; -}; - -} // namespace flutter - -#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_GAME_PAD_H_ From 1cc6a43c624f0ffd674bed47613d21172b381b7f Mon Sep 17 00:00:00 2001 From: James Clarke Date: Tue, 26 Jan 2021 19:34:00 -0800 Subject: [PATCH 16/17] Final CR Feedback --- .../platform/windows/flutter_window_winuwp.cc | 44 +++++++++---------- .../platform/windows/flutter_window_winuwp.h | 15 ++----- .../windows/flutter_windows_winuwp.cc | 2 +- .../windows/win32_flutter_window_unittests.cc | 6 ++- .../windows/window_binding_handler_delegate.h | 8 ++-- 5 files changed, 35 insertions(+), 40 deletions(-) diff --git a/shell/platform/windows/flutter_window_winuwp.cc b/shell/platform/windows/flutter_window_winuwp.cc index da46508dd5059..8593b8580cd72 100644 --- a/shell/platform/windows/flutter_window_winuwp.cc +++ b/shell/platform/windows/flutter_window_winuwp.cc @@ -6,6 +6,9 @@ namespace flutter { +// Multipler used to map controller velocity to an appropriate scroll input. +static constexpr double kControllerScrollMultiplier = 3; + FlutterWindowWinUWP::FlutterWindowWinUWP( ABI::Windows::UI::Core::CoreWindow* window) { winrt::Windows::UI::Core::CoreWindow cw{nullptr}; @@ -40,7 +43,7 @@ WindowsRenderTarget FlutterWindowWinUWP::GetRenderTarget() { } visual_tree_root_.Children().InsertAtBottom(render_target_); - auto bounds = GetBounds(current_display_info_, true); + WindowBoundsWinUWP bounds = GetBounds(current_display_info_, true); render_target_.Size({bounds.width, bounds.height}); return WindowsRenderTarget(render_target_); @@ -55,7 +58,7 @@ void FlutterWindowWinUWP::ApplyInverseDpiScalingTransform() { } PhysicalWindowBounds FlutterWindowWinUWP::GetPhysicalWindowBounds() { - auto bounds = GetBounds(current_display_info_, true); + WindowBoundsWinUWP bounds = GetBounds(current_display_info_, true); return {static_cast(bounds.width), static_cast(bounds.height)}; } @@ -99,11 +102,7 @@ WindowBoundsWinUWP FlutterWindowWinUWP::GetBounds( float FlutterWindowWinUWP::GetDpiScale( winrt::Windows::Graphics::Display::DisplayInformation const& disp) { - float dpi = disp.LogicalDpi(); - auto raw_dpi = disp.RawDpiX(); - auto raw_width = disp.ScreenHeightInRawPixels(); - auto scale = disp.ResolutionScale(); - auto raw_per_view = disp.RawPixelsPerViewPixel(); + double raw_per_view = disp.RawPixelsPerViewPixel(); // TODO(clarkezone): ensure DPI handling is correct: // because XBOX has display scaling off, logicalDpi retuns 96 which is @@ -192,8 +191,8 @@ void FlutterWindowWinUWP::OnDpiChanged( void FlutterWindowWinUWP::OnPointerPressed( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args) { - auto x = GetPosX(args); - auto y = GetPosY(args); + double x = GetPosX(args); + double y = GetPosY(args); binding_handler_delegate_->OnPointerDown( x, y, FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); @@ -202,8 +201,8 @@ void FlutterWindowWinUWP::OnPointerPressed( void FlutterWindowWinUWP::OnPointerReleased( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args) { - auto x = GetPosX(args); - auto y = GetPosY(args); + double x = GetPosX(args); + double y = GetPosY(args); binding_handler_delegate_->OnPointerUp( x, y, FlutterPointerMouseButtons::kFlutterPointerButtonMousePrimary); @@ -212,8 +211,8 @@ void FlutterWindowWinUWP::OnPointerReleased( void FlutterWindowWinUWP::OnPointerMoved( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args) { - auto x = GetPosX(args); - auto y = GetPosY(args); + double x = GetPosX(args); + double y = GetPosY(args); binding_handler_delegate_->OnPointerMove(x, y); } @@ -221,9 +220,9 @@ void FlutterWindowWinUWP::OnPointerMoved( void FlutterWindowWinUWP::OnPointerWheelChanged( winrt::Windows::Foundation::IInspectable const&, winrt::Windows::UI::Core::PointerEventArgs const& args) { - auto x = GetPosX(args); - auto y = GetPosY(args); - auto delta = args.CurrentPoint().Properties().MouseWheelDelta(); + double x = GetPosX(args); + double y = GetPosY(args); + int delta = args.CurrentPoint().Properties().MouseWheelDelta(); binding_handler_delegate_->OnScroll(x, y, 0, -delta, 1); } @@ -262,7 +261,7 @@ void FlutterWindowWinUWP::OnKeyUp( winrt::Windows::UI::Core::KeyEventArgs const& args) { // TODO(clarkezone) complete keyboard handling including // system key (back), unicode handling, shortcut support, - // handling defered delivery + // handling defered delivery, remove the need for action value. // https://github.com/flutter/flutter/issues/70202 auto status = args.KeyStatus(); unsigned int scancode = status.ScanCode; @@ -277,7 +276,7 @@ void FlutterWindowWinUWP::OnKeyDown( winrt::Windows::UI::Core::KeyEventArgs const& args) { // TODO(clarkezone) complete keyboard handling including // system key (back), unicode handling, shortcut support - // handling defered delivery + // handling defered delivery, remove the need for action value. // https://github.com/flutter/flutter/issues/70202 auto status = args.KeyStatus(); unsigned int scancode = status.ScanCode; @@ -304,21 +303,22 @@ FlutterWindowWinUWP::CreateCursorVisual() { container.Offset( {window_.Bounds().Width / 2, window_.Bounds().Height / 2, 1.0}); - const float SIZE = 30; + // size of the simulated mouse cursor + const float size = 30; auto cursor_visual = compositor_.CreateShapeVisual(); - cursor_visual.Size({SIZE, SIZE}); + cursor_visual.Size({size, size}); // compensate for overscan in cursor visual cursor_visual.Offset({xbox_overscan_x_offset_, xbox_overscan_y_offset_, 1.0}); winrt::Windows::UI::Composition::CompositionEllipseGeometry circle = compositor_.CreateEllipseGeometry(); - circle.Radius({SIZE / 2, SIZE / 2}); + circle.Radius({size / 2, size / 2}); auto circleshape = compositor_.CreateSpriteShape(circle); circleshape.FillBrush( compositor_.CreateColorBrush(winrt::Windows::UI::Colors::Black())); - circleshape.Offset({SIZE / 2, SIZE / 2}); + circleshape.Offset({size / 2, size / 2}); cursor_visual.Shapes().Append(circleshape); diff --git a/shell/platform/windows/flutter_window_winuwp.h b/shell/platform/windows/flutter_window_winuwp.h index e70fbf1802e17..bc7218de6d3a4 100644 --- a/shell/platform/windows/flutter_window_winuwp.h +++ b/shell/platform/windows/flutter_window_winuwp.h @@ -5,24 +5,18 @@ #ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_UWP_FLUTTER_WINDOW_H_ #define FLUTTER_SHELL_PLATFORM_WINDOWS_UWP_FLUTTER_WINDOW_H_ -#include "flutter/shell/platform/windows/flutter_windows_view.h" -#include "flutter/shell/platform/windows/public/flutter_windows.h" -#include "flutter/shell/platform/windows/window_binding_handler.h" - -#include "flutter/shell/platform/embedder/embedder.h" - #include #include #include #include -#include -#include "winrt/Windows.System.Threading.h" -#include "winrt/Windows.UI.Core.h" #include #include #include +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/windows/flutter_windows_view.h" + namespace flutter { struct WindowBoundsWinUWP { @@ -179,9 +173,6 @@ class FlutterWindowWinUWP : public WindowBindingHandler { // Most recent display information. winrt::Windows::Graphics::Display::DisplayInformation current_display_info_{ nullptr}; - - // Multipler used to map controller velocity to an appropriate scroll input. - const double kControllerScrollMultiplier = 3; }; } // namespace flutter diff --git a/shell/platform/windows/flutter_windows_winuwp.cc b/shell/platform/windows/flutter_windows_winuwp.cc index 3d2df1a0d7d54..3b235f22ef344 100644 --- a/shell/platform/windows/flutter_windows_winuwp.cc +++ b/shell/platform/windows/flutter_windows_winuwp.cc @@ -15,9 +15,9 @@ #include #include -#include "flutter//shell/platform/windows/flutter_window_winuwp.h" // nogncheck #include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/plugin_registrar.h" #include "flutter/shell/platform/common/cpp/incoming_message_dispatcher.h" +#include "flutter/shell/platform/windows/flutter_window_winuwp.h" // nogncheck // Returns the engine corresponding to the given opaque API handle. static flutter::FlutterWindowsEngine* EngineFromHandle( diff --git a/shell/platform/windows/win32_flutter_window_unittests.cc b/shell/platform/windows/win32_flutter_window_unittests.cc index c53843e9a437e..dadaad0ef1f53 100644 --- a/shell/platform/windows/win32_flutter_window_unittests.cc +++ b/shell/platform/windows/win32_flutter_window_unittests.cc @@ -71,7 +71,8 @@ class SpyKeyEventHandler : public KeyboardHookHandler { void(FlutterWindowsView* window, const std::u16string& text)); MOCK_METHOD0(ComposeBeginHook, void()); MOCK_METHOD0(ComposeEndHook, void()); - MOCK_METHOD2(ComposeChangeHook, void(const std::u16string& text, int cursor_pos)); + MOCK_METHOD2(ComposeChangeHook, + void(const std::u16string& text, int cursor_pos)); private: std::unique_ptr real_implementation_; @@ -103,7 +104,8 @@ class SpyTextInputPlugin : public KeyboardHookHandler, void(FlutterWindowsView* window, const std::u16string& text)); MOCK_METHOD0(ComposeBeginHook, void()); MOCK_METHOD0(ComposeEndHook, void()); - MOCK_METHOD2(ComposeChangeHook, void(const std::u16string& text, int cursor_pos)); + MOCK_METHOD2(ComposeChangeHook, + void(const std::u16string& text, int cursor_pos)); virtual void OnCursorRectUpdated(const Rect& rect) {} diff --git a/shell/platform/windows/window_binding_handler_delegate.h b/shell/platform/windows/window_binding_handler_delegate.h index 8b8b1acc7669e..dd0038f0fc194 100644 --- a/shell/platform/windows/window_binding_handler_delegate.h +++ b/shell/platform/windows/window_binding_handler_delegate.h @@ -41,9 +41,11 @@ class WindowBindingHandlerDelegate { // Typically called by currently configured WindowBindingHandler virtual void OnText(const std::u16string&) = 0; - // Notifies delegate that backing window size has received key press. Should - // return true if the event was handled and should not be propagated. - // Typically called by currently configured WindowBindingHandler. + // TODO(clarkezone) refactor delegate to avoid needing win32 magic values in + // UWP implementation https://github.com/flutter/flutter/issues/70202 Notifies + // delegate that backing window size has received key press. Should return + // true if the event was handled and should not be propagated. Typically + // called by currently configured WindowBindingHandler. virtual bool OnKey(int key, int scancode, int action, From 4fca5322accda2e0af949d6deadd4ccfaea90c96 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Tue, 26 Jan 2021 19:49:07 -0800 Subject: [PATCH 17/17] Fix build --- shell/platform/windows/BUILD.gn | 1 - 1 file changed, 1 deletion(-) diff --git a/shell/platform/windows/BUILD.gn b/shell/platform/windows/BUILD.gn index e2d7b908b78fe..0411b8dafa7c0 100644 --- a/shell/platform/windows/BUILD.gn +++ b/shell/platform/windows/BUILD.gn @@ -194,7 +194,6 @@ executable("flutter_windows_unittests") { "flutter_windows_engine_unittests.cc", "flutter_windows_texture_registrar_unittests.cc", "key_event_handler_unittests.cc", - "string_conversion_unittests.cc", "testing/mock_win32_window.cc", "testing/mock_win32_window.h", "testing/mock_window_binding_handler.cc",