From ee29027ccaddbeed29cc09fc98f4cfb680cf24fa Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sun, 7 Jun 2020 06:17:27 -0700 Subject: [PATCH 01/15] Add flutter_windows_view and window_binding_handler Switch input handling infra to FlutterWindowsView win32_flutter_window implement WindowBindingHandler Strip unneeded functionality from win32flutterwindow Fulfill WindowBindingHandler interface in Win32FlutterWindow Add implementations for missing input handling in Win32FlutterWindow Cleanup dead code Correctly hook up rendering again Fix resizing clang-format Fix clipboard Cleanup Rename Add comments cleanup --- shell/platform/windows/BUILD.gn | 13 +- .../platform/windows/angle_surface_manager.cc | 6 +- .../platform/windows/angle_surface_manager.h | 8 +- shell/platform/windows/flutter_windows.cc | 34 +- .../platform/windows/flutter_windows_view.cc | 359 ++++++++++++++++++ shell/platform/windows/flutter_windows_view.h | 245 ++++++++++++ shell/platform/windows/key_event_handler.cc | 4 +- shell/platform/windows/key_event_handler.h | 6 +- .../platform/windows/keyboard_hook_handler.h | 6 +- shell/platform/windows/text_input_plugin.cc | 4 +- shell/platform/windows/text_input_plugin.h | 7 +- .../{dpi_utils.cc => win32_dpi_utils.cc} | 2 +- .../{dpi_utils.h => win32_dpi_utils.h} | 2 +- ...ttests.cc => win32_dpi_utils_unittests.cc} | 2 +- .../platform/windows/win32_flutter_window.cc | 314 ++------------- shell/platform/windows/win32_flutter_window.h | 120 ++---- .../windows/win32_flutter_window_unittests.cc | 2 +- ...m_handler.cc => win32_platform_handler.cc} | 110 +++--- ...orm_handler.h => win32_platform_handler.h} | 6 +- shell/platform/windows/win32_window.cc | 2 +- shell/platform/windows/win32_window.h | 40 +- .../platform/windows/window_binding_handler.h | 74 ++++ shell/platform/windows/window_state.h | 14 +- 23 files changed, 860 insertions(+), 520 deletions(-) create mode 100644 shell/platform/windows/flutter_windows_view.cc create mode 100644 shell/platform/windows/flutter_windows_view.h rename shell/platform/windows/{dpi_utils.cc => win32_dpi_utils.cc} (99%) rename shell/platform/windows/{dpi_utils.h => win32_dpi_utils.h} (95%) rename shell/platform/windows/{dpi_utils_unittests.cc => win32_dpi_utils_unittests.cc} (89%) rename shell/platform/windows/{platform_handler.cc => win32_platform_handler.cc} (74%) rename shell/platform/windows/{platform_handler.h => win32_platform_handler.h} (91%) create mode 100644 shell/platform/windows/window_binding_handler.h diff --git a/shell/platform/windows/BUILD.gn b/shell/platform/windows/BUILD.gn index 248d3ccdc24c7..c6f07181b21ef 100644 --- a/shell/platform/windows/BUILD.gn +++ b/shell/platform/windows/BUILD.gn @@ -41,20 +41,23 @@ source_set("flutter_windows_source") { sources = [ "angle_surface_manager.cc", "angle_surface_manager.h", - "dpi_utils.cc", - "dpi_utils.h", "flutter_windows.cc", + "flutter_windows_view.cc", + "flutter_windows_view.h", "key_event_handler.cc", "key_event_handler.h", "keyboard_hook_handler.h", - "platform_handler.cc", - "platform_handler.h", "string_conversion.cc", "string_conversion.h", "text_input_plugin.cc", "text_input_plugin.h", + "window_binding_handler.h", + "win32_dpi_utils.cc", + "win32_dpi_utils.h", "win32_flutter_window.cc", "win32_flutter_window.h", + "win32_platform_handler.cc", + "win32_platform_handler.h", "win32_task_runner.cc", "win32_task_runner.h", "win32_window.cc", @@ -110,12 +113,12 @@ executable("flutter_windows_unittests") { testonly = true sources = [ - "dpi_utils_unittests.cc", "string_conversion_unittests.cc", "testing/win32_flutter_window_test.cc", "testing/win32_flutter_window_test.h", "testing/win32_window_test.cc", "testing/win32_window_test.h", + "win32_dpi_utils_unittests.cc", "win32_flutter_window_unittests.cc", "win32_window_unittests.cc", ] diff --git a/shell/platform/windows/angle_surface_manager.cc b/shell/platform/windows/angle_surface_manager.cc index df520d37680b7..c6bdaafce2dca 100644 --- a/shell/platform/windows/angle_surface_manager.cc +++ b/shell/platform/windows/angle_surface_manager.cc @@ -169,8 +169,8 @@ void AngleSurfaceManager::CleanUp() { } } -EGLSurface AngleSurfaceManager::CreateSurface(HWND window) { - if (!window || !initialize_succeeded_) { +EGLSurface AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target) { + if (!render_target || !initialize_succeeded_) { return EGL_NO_SURFACE; } @@ -179,7 +179,7 @@ EGLSurface AngleSurfaceManager::CreateSurface(HWND window) { const EGLint surfaceAttributes[] = {EGL_NONE}; surface = eglCreateWindowSurface(egl_display_, egl_config_, - static_cast(window), + static_cast(render_target->GetWindowHandle()), surfaceAttributes); if (surface == EGL_NO_SURFACE) { std::cerr << "Surface creation failed." << std::endl; diff --git a/shell/platform/windows/angle_surface_manager.h b/shell/platform/windows/angle_surface_manager.h index 21c0648203a73..1230a53acb85c 100644 --- a/shell/platform/windows/angle_surface_manager.h +++ b/shell/platform/windows/angle_surface_manager.h @@ -15,6 +15,8 @@ // Windows platform specific includes #include +#include "window_binding_handler.h" + namespace flutter { // An manager for inializing ANGLE correctly and using it to create and @@ -29,9 +31,9 @@ class AngleSurfaceManager { AngleSurfaceManager& operator=(const AngleSurfaceManager&) = delete; // Creates and returns an EGLSurface wrapper and backing DirectX 11 SwapChain - // asociated with window, in the appropriate format for display in a - // HWND-backed window. - EGLSurface CreateSurface(HWND window); + // asociated with window, in the appropriate format for display. + // Target represents the visual entity to bind to. + EGLSurface CreateSurface(WindowsRenderTarget* render_target); // queries EGL for the dimensions of surface in physical // pixels returning width and height as out params. diff --git a/shell/platform/windows/flutter_windows.cc b/shell/platform/windows/flutter_windows.cc index 52319db72d52b..afb8288b7eded 100644 --- a/shell/platform/windows/flutter_windows.cc +++ b/shell/platform/windows/flutter_windows.cc @@ -19,13 +19,15 @@ #include "flutter/shell/platform/common/cpp/incoming_message_dispatcher.h" #include "flutter/shell/platform/common/cpp/path_utils.h" #include "flutter/shell/platform/embedder/embedder.h" -#include "flutter/shell/platform/windows/dpi_utils.h" +#include "flutter/shell/platform/windows/flutter_windows_view.h" #include "flutter/shell/platform/windows/key_event_handler.h" #include "flutter/shell/platform/windows/keyboard_hook_handler.h" -#include "flutter/shell/platform/windows/platform_handler.h" #include "flutter/shell/platform/windows/text_input_plugin.h" +#include "flutter/shell/platform/windows/win32_dpi_utils.h" #include "flutter/shell/platform/windows/win32_flutter_window.h" +#include "flutter/shell/platform/windows/win32_platform_handler.h" #include "flutter/shell/platform/windows/win32_task_runner.h" +#include "flutter/shell/platform/windows/window_binding_handler.h" #include "flutter/shell/platform/windows/window_state.h" static_assert(FLUTTER_ENGINE_VERSION == 1, ""); @@ -66,7 +68,7 @@ UniqueAotDataPtr LoadAotData(std::filesystem::path aot_data_path) { // Returns the state object for the engine, or null on failure to start the // engine. static std::unique_ptr RunFlutterEngine( - flutter::Win32FlutterWindow* window, + flutter::FlutterWindowsView* view, const FlutterDesktopEngineProperties& engine_properties) { auto state = std::make_unique(); @@ -79,22 +81,22 @@ static std::unique_ptr RunFlutterEngine( &engine_properties.switches[engine_properties.switches_count]); } - window->CreateRenderSurface(); + view->CreateRenderSurface(); // Provide the necessary callbacks for rendering within a win32 child window. FlutterRendererConfig config = {}; config.type = kOpenGL; config.open_gl.struct_size = sizeof(config.open_gl); config.open_gl.make_current = [](void* user_data) -> bool { - auto host = static_cast(user_data); + auto host = static_cast(user_data); return host->MakeCurrent(); }; config.open_gl.clear_current = [](void* user_data) -> bool { - auto host = static_cast(user_data); + auto host = static_cast(user_data); return host->ClearContext(); }; config.open_gl.present = [](void* user_data) -> bool { - auto host = static_cast(user_data); + auto host = static_cast(user_data); return host->SwapBuffers(); }; config.open_gl.fbo_callback = [](void* user_data) -> uint32_t { return 0; }; @@ -103,7 +105,7 @@ static std::unique_ptr RunFlutterEngine( return reinterpret_cast(eglGetProcAddress(what)); }; config.open_gl.make_resource_current = [](void* user_data) -> bool { - auto host = static_cast(user_data); + auto host = static_cast(user_data); return host->MakeResourceCurrent(); }; @@ -178,7 +180,7 @@ static std::unique_ptr RunFlutterEngine( args.platform_message_callback = [](const FlutterPlatformMessage* engine_message, void* user_data) -> void { - auto window = reinterpret_cast(user_data); + auto window = reinterpret_cast(user_data); return window->HandlePlatformMessage(engine_message); }; args.custom_task_runners = &custom_task_runners; @@ -188,7 +190,7 @@ static std::unique_ptr RunFlutterEngine( FLUTTER_API_SYMBOL(FlutterEngine) engine = nullptr; auto result = - FlutterEngineRun(FLUTTER_ENGINE_VERSION, &config, &args, window, &engine); + FlutterEngineRun(FLUTTER_ENGINE_VERSION, &config, &args, view, &engine); if (result != kSuccess || engine == nullptr) { std::cerr << "Failed to start Flutter engine: error " << result << std::endl; @@ -202,8 +204,12 @@ FlutterDesktopViewControllerRef FlutterDesktopCreateViewController( int width, int height, const FlutterDesktopEngineProperties& engine_properties) { + std::unique_ptr window_wrapper = + std::make_unique(width, height); + FlutterDesktopViewControllerRef state = - flutter::Win32FlutterWindow::CreateWin32FlutterWindow(width, height); + flutter::FlutterWindowsView::CreateFlutterWindowsView( + std::move(window_wrapper)); auto engine_state = RunFlutterEngine(state->view.get(), engine_properties); @@ -261,8 +267,8 @@ FlutterDesktopViewRef FlutterDesktopGetView( return controller->view_wrapper.get(); } -HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view) { - return view->window->GetWindowHandle(); +HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view_ref) { + return view_ref->view->GetRenderTarget()->GetWindowHandle(); } UINT FlutterDesktopGetDpiForHWND(HWND hwnd) { @@ -316,7 +322,7 @@ void FlutterDesktopRegistrarSetDestructionHandler( FlutterDesktopViewRef FlutterDesktopRegistrarGetView( FlutterDesktopPluginRegistrarRef registrar) { - return registrar->window; + return registrar->view; } bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger, diff --git a/shell/platform/windows/flutter_windows_view.cc b/shell/platform/windows/flutter_windows_view.cc new file mode 100644 index 0000000000000..7f93606d2c2ec --- /dev/null +++ b/shell/platform/windows/flutter_windows_view.cc @@ -0,0 +1,359 @@ +#include "flutter/shell/platform/windows/flutter_windows_view.h" + +#include + +namespace flutter { + +FlutterWindowsView::FlutterWindowsView() { + surface_manager = std::make_unique(); +} + +FlutterWindowsView::~FlutterWindowsView() { + DestroyRenderSurface(); + if (plugin_registrar_ && plugin_registrar_->destruction_handler) { + plugin_registrar_->destruction_handler(plugin_registrar_.get()); + } +} + +FlutterDesktopViewControllerRef FlutterWindowsView::CreateFlutterWindowsView( + std::unique_ptr windowbinding) { + auto state = std::make_unique(); + state->view = std::make_unique(); + + // FlutterWindowsView instance owns windowbinding + state->view->binding_handler_ = std::move(windowbinding); + + // a window wrapper for the state block, distinct from the + // window_wrapper handed to plugin_registrar. + state->view_wrapper = std::make_unique(); + + // Give the binding handler a pointer back to this | FlutterWindowsView | + state->view->binding_handler_->SetView(state->view.get()); + + // opaque pointer to FlutterWindowsView + state->view_wrapper->view = state->view.get(); + + state->view->render_target_ = std::make_unique( + state->view->binding_handler_->GetRenderTarget()); + + return state.release(); +} + +void FlutterWindowsView::SetState(FLUTTER_API_SYMBOL(FlutterEngine) eng) { + engine_ = eng; + + auto messenger = std::make_unique(); + message_dispatcher_ = + std::make_unique(messenger.get()); + messenger->engine = engine_; + messenger->dispatcher = message_dispatcher_.get(); + + window_wrapper_ = std::make_unique(); + window_wrapper_->view = this; + plugin_registrar_ = std::make_unique(); + plugin_registrar_->messenger = std::move(messenger); + plugin_registrar_->view = window_wrapper_.get(); + + internal_plugin_registrar_ = + std::make_unique(plugin_registrar_.get()); + + // Set up the keyboard handlers. + auto internal_plugin_messenger = internal_plugin_registrar_->messenger(); + keyboard_hook_handlers_.push_back( + std::make_unique(internal_plugin_messenger)); + keyboard_hook_handlers_.push_back( + std::make_unique(internal_plugin_messenger)); + platform_handler_ = std::make_unique( + internal_plugin_messenger, this); + + process_events_ = true; + + SendWindowMetrics(binding_handler_->GetPhysicalWidth(), + binding_handler_->GetPhysicalHeight(), + binding_handler_->GetDpiScale()); +} + +FlutterDesktopPluginRegistrarRef FlutterWindowsView::GetRegistrar() { + return plugin_registrar_.get(); +} + +// Converts a FlutterPlatformMessage to an equivalent FlutterDesktopMessage. +static FlutterDesktopMessage ConvertToDesktopMessage( + const FlutterPlatformMessage& engine_message) { + FlutterDesktopMessage message = {}; + message.struct_size = sizeof(message); + message.channel = engine_message.channel; + message.message = engine_message.message; + message.message_size = engine_message.message_size; + message.response_handle = engine_message.response_handle; + return message; +} + +// The Flutter Engine calls out to this function when new platform messages +// are available. +void FlutterWindowsView::HandlePlatformMessage( + const FlutterPlatformMessage* engine_message) { + if (engine_message->struct_size != sizeof(FlutterPlatformMessage)) { + std::cerr << "Invalid message size received. Expected: " + << sizeof(FlutterPlatformMessage) << " but received " + << engine_message->struct_size << std::endl; + return; + } + + auto message = ConvertToDesktopMessage(*engine_message); + + message_dispatcher_->HandleMessage( + message, [this] { this->process_events_ = false; }, + [this] { this->process_events_ = true; }); +} + +void FlutterWindowsView::OnWindowSizeChanged(size_t width, + size_t height) const { + if (process_events_) { + SendWindowMetrics(width, height, binding_handler_->GetDpiScale()); + } +} + +void FlutterWindowsView::OnPointerMove(double x, double y) { + if (process_events_) { + SendPointerMove(x, y); + } +} + +void FlutterWindowsView::OnPointerDown( + double x, + double y, + FlutterPointerMouseButtons flutter_button) { + if (process_events_) { + if (flutter_button != 0) { + uint64_t mouse_buttons = GetMouseState().buttons | flutter_button; + SetMouseButtons(mouse_buttons); + SendPointerDown(x, y); + } + } +} + +void FlutterWindowsView::OnPointerUp( + double x, + double y, + FlutterPointerMouseButtons flutter_button) { + if (process_events_) { + if (flutter_button != 0) { + uint64_t mouse_buttons = GetMouseState().buttons & ~flutter_button; + SetMouseButtons(mouse_buttons); + SendPointerUp(x, y); + } + } +} + +void FlutterWindowsView::OnPointerLeave() { + if (process_events_) { + SendPointerLeave(); + } +} + +void FlutterWindowsView::OnText(const std::u16string& text) { + if (process_events_) { + SendText(text); + } +} + +void FlutterWindowsView::OnKey(int key, + int scancode, + int action, + char32_t character) { + if (process_events_) { + SendKey(key, scancode, action, character); + } +} + +void FlutterWindowsView::OnScroll(double x, + double y, + double delta_x, + double delta_y, + int scroll_offset_multiplier) { + if (process_events_) { + SendScroll(x, y, delta_x, delta_y, scroll_offset_multiplier); + } +} + +void FlutterWindowsView::OnFontChange() { + if (engine_ == nullptr) { + return; + } + FlutterEngineReloadSystemFonts(engine_); +} + +// Sends new size information to FlutterEngine. +void FlutterWindowsView::SendWindowMetrics(size_t width, + size_t height, + double dpiScale) const { + if (engine_ == nullptr) { + return; + } + + FlutterWindowMetricsEvent event = {}; + event.struct_size = sizeof(event); + event.width = width; + event.height = height; + event.pixel_ratio = dpiScale; + auto result = FlutterEngineSendWindowMetricsEvent(engine_, &event); +} + +// Set's |event_data|'s phase to either kMove or kHover depending on the current +// primary mouse button state. +void FlutterWindowsView::SetEventPhaseFromCursorButtonState( + FlutterPointerEvent* event_data) const { + MouseState state = GetMouseState(); + // For details about this logic, see FlutterPointerPhase in the embedder.h + // file. + event_data->phase = state.buttons == 0 ? state.flutter_state_is_down + ? FlutterPointerPhase::kUp + : FlutterPointerPhase::kHover + : state.flutter_state_is_down + ? FlutterPointerPhase::kMove + : FlutterPointerPhase::kDown; +} + +void FlutterWindowsView::SendPointerMove(double x, double y) { + FlutterPointerEvent event = {}; + event.x = x; + event.y = y; + SetEventPhaseFromCursorButtonState(&event); + SendPointerEventWithData(event); +} + +void FlutterWindowsView::SendPointerDown(double x, double y) { + FlutterPointerEvent event = {}; + SetEventPhaseFromCursorButtonState(&event); + event.x = x; + event.y = y; + SendPointerEventWithData(event); + SetMouseFlutterStateDown(true); +} + +void FlutterWindowsView::SendPointerUp(double x, double y) { + FlutterPointerEvent event = {}; + SetEventPhaseFromCursorButtonState(&event); + event.x = x; + event.y = y; + SendPointerEventWithData(event); + if (event.phase == FlutterPointerPhase::kUp) { + SetMouseFlutterStateDown(false); + } +} + +void FlutterWindowsView::SendPointerLeave() { + FlutterPointerEvent event = {}; + event.phase = FlutterPointerPhase::kRemove; + SendPointerEventWithData(event); +} + +void FlutterWindowsView::SendText(const std::u16string& text) { + for (const auto& handler : keyboard_hook_handlers_) { + handler->TextHook(this, text); + } +} + +void FlutterWindowsView::SendKey(int key, + int scancode, + int action, + char32_t character) { + for (const auto& handler : keyboard_hook_handlers_) { + handler->KeyboardHook(this, key, scancode, action, character); + } +} + +void FlutterWindowsView::SendScroll(double x, + double y, + double delta_x, + double delta_y, + int scroll_offset_multiplier) { + FlutterPointerEvent event = {}; + SetEventPhaseFromCursorButtonState(&event); + event.signal_kind = FlutterPointerSignalKind::kFlutterPointerSignalKindScroll; + // TODO: See if this can be queried from the OS; this value is chosen + // arbitrarily to get something that feels reasonable. + + // scroll_offset_multiplier should be 20 for win32 and 1 for UWP + event.x = x; + event.y = y; + event.scroll_delta_x = delta_x * scroll_offset_multiplier; + event.scroll_delta_y = delta_y * scroll_offset_multiplier; + SendPointerEventWithData(event); +} + +void FlutterWindowsView::SendPointerEventWithData( + const FlutterPointerEvent& event_data) { + MouseState mouse_state = GetMouseState(); + // If sending anything other than an add, and the pointer isn't already added, + // synthesize an add to satisfy Flutter's expectations about events. + if (!mouse_state.flutter_state_is_added && + event_data.phase != FlutterPointerPhase::kAdd) { + FlutterPointerEvent event = {}; + event.phase = FlutterPointerPhase::kAdd; + event.x = event_data.x; + event.y = event_data.y; + event.buttons = 0; + SendPointerEventWithData(event); + } + // Don't double-add (e.g., if events are delivered out of order, so an add has + // already been synthesized). + if (mouse_state.flutter_state_is_added && + event_data.phase == FlutterPointerPhase::kAdd) { + return; + } + + FlutterPointerEvent event = event_data; + event.device_kind = kFlutterPointerDeviceKindMouse; + event.buttons = mouse_state.buttons; + + // Set metadata that's always the same regardless of the event. + event.struct_size = sizeof(event); + event.timestamp = + std::chrono::duration_cast( + std::chrono::high_resolution_clock::now().time_since_epoch()) + .count(); + + FlutterEngineSendPointerEvent(engine_, &event, 1); + + if (event_data.phase == FlutterPointerPhase::kAdd) { + SetMouseFlutterStateAdded(true); + } else if (event_data.phase == FlutterPointerPhase::kRemove) { + SetMouseFlutterStateAdded(false); + ResetMouseState(); + } +} + +bool FlutterWindowsView::MakeCurrent() { + return surface_manager->MakeCurrent(render_surface); +} + +bool FlutterWindowsView::MakeResourceCurrent() { + return surface_manager->MakeResourceCurrent(); +} + +bool FlutterWindowsView::ClearContext() { + return surface_manager->MakeCurrent(nullptr); +} + +bool FlutterWindowsView::SwapBuffers() { + return surface_manager->SwapBuffers(render_surface); +} + +void FlutterWindowsView::CreateRenderSurface() { + render_surface = surface_manager->CreateSurface(render_target_.get()); +} + +void FlutterWindowsView::DestroyRenderSurface() { + if (surface_manager) { + surface_manager->DestroySurface(render_surface); + } + render_surface = EGL_NO_SURFACE; +} + +WindowsRenderTarget* FlutterWindowsView::GetRenderTarget() { + return render_target_.get(); +} + +} // namespace flutter diff --git a/shell/platform/windows/flutter_windows_view.h b/shell/platform/windows/flutter_windows_view.h new file mode 100644 index 0000000000000..2b169ebccbc2b --- /dev/null +++ b/shell/platform/windows/flutter_windows_view.h @@ -0,0 +1,245 @@ +// 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_FLUTTER_WINDOWS_VIEW_H_ +#define FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOWS_VIEW_H_ + +#include + +#include +#include + +#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/embedder/embedder.h" +#include "flutter/shell/platform/windows/angle_surface_manager.h" +#include "flutter/shell/platform/windows/key_event_handler.h" +#include "flutter/shell/platform/windows/keyboard_hook_handler.h" +#include "flutter/shell/platform/windows/public/flutter_windows.h" +#include "flutter/shell/platform/windows/text_input_plugin.h" +#include "flutter/shell/platform/windows/win32_platform_handler.h" +#include "flutter/shell/platform/windows/window_binding_handler.h" +#include "flutter/shell/platform/windows/window_state.h" + +namespace flutter { + +// Struct holding the mouse state. The engine doesn't keep track of which mouse +// buttons have been pressed, so it's the embedding's responsibility. +struct MouseState { + // True if the last event sent to Flutter had at least one mouse button. + // pressed. + bool flutter_state_is_down = false; + + // True if kAdd has been sent to Flutter. Used to determine whether + // to send a kAdd event before sending an incoming mouse event, since Flutter + // expects pointers to be added before events are sent for them. + bool flutter_state_is_added = false; + + // The currently pressed buttons, as represented in FlutterPointerEvent. + uint64_t buttons = 0; +}; + +// An OS windowing neutral abstration for flutter +// view that works with win32 hwnds and Windows::UI::Composition visuals. +class FlutterWindowsView { + public: + FlutterWindowsView(); + + ~FlutterWindowsView(); + + // Factory for creating FlutterWindowsView requiring an implementator of FlutterWindowBindingHandler. + static FlutterDesktopViewControllerRef CreateFlutterWindowsView( + std::unique_ptr windowbinding); + + // Configures the window instance with an instance of a running Flutter engine + // returning a configured FlutterDesktopWindowControllerRef. + void SetState(FLUTTER_API_SYMBOL(FlutterEngine) state); + + // Returns the currently configured Plugin Registrar. + FlutterDesktopPluginRegistrarRef GetRegistrar(); + + // Callback passed to Flutter engine for notifying window of platform + // messages. + void HandlePlatformMessage(const FlutterPlatformMessage*); + + // Create rendering surface for Flutter engine to draw into. + void CreateRenderSurface(); + + // Destroy current rendering surface if one has been allocated. + void DestroyRenderSurface(); + + // Return the currently configured WindowsRenderTarget. + WindowsRenderTarget* GetRenderTarget(); + + // Callbacks for clearing context, settings context and swapping buffers. + bool ClearContext(); + bool MakeCurrent(); + bool MakeResourceCurrent(); + bool SwapBuffers(); + + // Notify view that backing window size has changed. + // Typically called by currently configured FlutterWindowBindingHandler + void OnWindowSizeChanged(size_t width, size_t height) const; + + // Notify view that backing window mouse has moved. + // Typically called by currently configured FlutterWindowBindingHandler + void OnPointerMove(double x, double y); + + // Notify view that backing window mouse pointer button has been pressed. + // Typically called by currently configured FlutterWindowBindingHandler + void OnPointerDown(double x, double y, FlutterPointerMouseButtons button); + + // Notify view that backing window mouse pointer button has been released. + // Typically called by currently configured FlutterWindowBindingHandler + void OnPointerUp(double x, double y, FlutterPointerMouseButtons button); + + // Notify view that backing window mouse pointer has left the window. + // Typically called by currently configured FlutterWindowBindingHandler + void OnPointerLeave(); + + // Notify view that backing window has received text. + // Typically called by currently configured FlutterWindowBindingHandler + void OnText(const std::u16string&); + + // Notify view that backing window size has received key press. + // Typically called by currently configured FlutterWindowBindingHandler + void OnKey(int key, int scancode, int action, char32_t character); + + // Notify view that backing window size has recevied scroll. + // Typically called by currently configured FlutterWindowBindingHandler + void OnScroll(double x, + double y, + double delta_x, + double delta_y, + int scroll_offset_multiplier); + + // Notify view that backing window size has had system font change. + // Typically called by currently configured FlutterWindowBindingHandler + void OnFontChange(); + + private: + + // Sends a window metrics update to the Flutter engine using current window + // dimensions in physical + void SendWindowMetrics(size_t width, size_t height, double dpiscale) const; + + // Reports a mouse movement to Flutter engine. + void SendPointerMove(double x, double y); + + // Reports mouse press to Flutter engine. + void SendPointerDown(double x, double y); + + // Reports mouse release to Flutter engine. + void SendPointerUp(double x, double y); + + // Reports mouse left the window client area. + // + // Win32 api doesn't have "mouse enter" event. Therefore, there is no + // SendPointerEnter method. A mouse enter event is tracked then the "move" + // event is called. + void SendPointerLeave(); + + // Reports a keyboard character to Flutter engine. + void SendText(const std::u16string&); + + // Reports a raw keyboard message to Flutter engine. + void SendKey(int key, int scancode, int action, char32_t character); + + // Reports scroll wheel events to Flutter engine. + void SendScroll(double x, + double y, + double delta_x, + double delta_y, + int scroll_offset_multiplier); + + // Set's |event_data|'s phase to either kMove or kHover depending on the + // current + // primary mouse button state. + void SetEventPhaseFromCursorButtonState( + FlutterPointerEvent* event_data) const; + + // Sends a pointer event to the Flutter engine based on givern data. Since + // all input messages are passed in physical pixel values, no translation is + // needed before passing on to engine. + void SendPointerEventWithData(const FlutterPointerEvent& event_data); + + // Gets the current mouse state. + MouseState GetMouseState() const { return mouse_state_; } + + // Resets the mouse state to its default values. + void ResetMouseState() { mouse_state_ = MouseState(); } + + // Updates the mouse state to whether the last event to Flutter had at least + // one mouse button pressed. + void SetMouseFlutterStateDown(bool is_down) { + mouse_state_.flutter_state_is_down = is_down; + } + + // Updates the mouse state to whether the last event to Flutter was a kAdd + // event. + void SetMouseFlutterStateAdded(bool is_added) { + mouse_state_.flutter_state_is_added = is_added; + } + + // Updates the currently pressed buttons. + void SetMouseButtons(uint64_t buttons) { mouse_state_.buttons = buttons; } + + std::unique_ptr surface_manager = nullptr; + EGLSurface render_surface = EGL_NO_SURFACE; + + // state of the mouse button. + bool pointer_is_down_ = false; + + // The handle to the Flutter engine instance. + FLUTTER_API_SYMBOL(FlutterEngine) engine_ = nullptr; + + // Whether or not to track mouse movements to send kHover events. + bool hover_tracking_is_enabled_ = false; + + // Whether or not the pointer has been added (or if tracking is enabled, has + // been added since it was last removed). + bool pointer_currently_added_ = false; + + // Set to true to be notified when the mouse leaves the window. + bool tracking_mouse_leave_ = false; + + // Keeps track of mouse state in relation to the window. + MouseState mouse_state_; + + // The window handle given to API clients. + std::unique_ptr window_wrapper_; + + // The plugin registrar handle given to API clients. + std::unique_ptr plugin_registrar_; + + // Message dispatch manager for messages from the Flutter engine. + std::unique_ptr message_dispatcher_; + + // The plugin registrar managing internal plugins. + std::unique_ptr internal_plugin_registrar_; + + // Handlers for keyboard events from Windows. + std::vector> + keyboard_hook_handlers_; + + // Handler for the flutter/platform channel. + std::unique_ptr platform_handler_; + + // should we forword input messages or not + bool process_events_ = false; + + // flag indicating if the message loop should be running. + bool messageloop_running_ = false; + + // Currently configured WindowsRenderTarget for view. + std::unique_ptr render_target_; + + // Currently configured FlutterWindowBindingHandler for view. + std::unique_ptr binding_handler_{ + nullptr}; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOWS_VIEW_H_ diff --git a/shell/platform/windows/key_event_handler.cc b/shell/platform/windows/key_event_handler.cc index 3747a9f5a05a0..9b562f8f0944e 100644 --- a/shell/platform/windows/key_event_handler.cc +++ b/shell/platform/windows/key_event_handler.cc @@ -92,10 +92,10 @@ KeyEventHandler::KeyEventHandler(flutter::BinaryMessenger* messenger) KeyEventHandler::~KeyEventHandler() = default; -void KeyEventHandler::TextHook(Win32FlutterWindow* window, +void KeyEventHandler::TextHook(FlutterWindowsView* view, const std::u16string& code_point) {} -void KeyEventHandler::KeyboardHook(Win32FlutterWindow* window, +void KeyEventHandler::KeyboardHook(FlutterWindowsView* view, int key, int scancode, int action, diff --git a/shell/platform/windows/key_event_handler.h b/shell/platform/windows/key_event_handler.h index 6e9a77f1d3514..9a1b2752288e9 100644 --- a/shell/platform/windows/key_event_handler.h +++ b/shell/platform/windows/key_event_handler.h @@ -16,7 +16,7 @@ namespace flutter { -class Win32FlutterWindow; +class FlutterWindowsView; // Implements a KeyboardHookHandler // @@ -28,14 +28,14 @@ class KeyEventHandler : public KeyboardHookHandler { virtual ~KeyEventHandler(); // |KeyboardHookHandler| - void KeyboardHook(Win32FlutterWindow* window, + void KeyboardHook(FlutterWindowsView* window, int key, int scancode, int action, char32_t character) override; // |KeyboardHookHandler| - void TextHook(Win32FlutterWindow* window, + void TextHook(FlutterWindowsView* window, const std::u16string& text) override; private: diff --git a/shell/platform/windows/keyboard_hook_handler.h b/shell/platform/windows/keyboard_hook_handler.h index aa574a545d64e..b36ad3a6d7d82 100644 --- a/shell/platform/windows/keyboard_hook_handler.h +++ b/shell/platform/windows/keyboard_hook_handler.h @@ -11,7 +11,7 @@ namespace flutter { -class Win32FlutterWindow; +class FlutterWindowsView; // Abstract class for handling keyboard input events. class KeyboardHookHandler { @@ -19,14 +19,14 @@ class KeyboardHookHandler { virtual ~KeyboardHookHandler() = default; // A function for hooking into keyboard input. - virtual void KeyboardHook(Win32FlutterWindow* window, + virtual void KeyboardHook(FlutterWindowsView* view, int key, int scancode, int action, char32_t character) = 0; // A function for hooking into Unicode text input. - virtual void TextHook(Win32FlutterWindow* window, + virtual void TextHook(FlutterWindowsView* view, const std::u16string& text) = 0; }; diff --git a/shell/platform/windows/text_input_plugin.cc b/shell/platform/windows/text_input_plugin.cc index 7f3127a286448..46849b0672d44 100644 --- a/shell/platform/windows/text_input_plugin.cc +++ b/shell/platform/windows/text_input_plugin.cc @@ -43,7 +43,7 @@ static constexpr char kInternalConsistencyError[] = namespace flutter { -void TextInputPlugin::TextHook(Win32FlutterWindow* window, +void TextInputPlugin::TextHook(FlutterWindowsView* view, const std::u16string& text) { if (active_model_ == nullptr) { return; @@ -52,7 +52,7 @@ void TextInputPlugin::TextHook(Win32FlutterWindow* window, SendStateUpdate(*active_model_); } -void TextInputPlugin::KeyboardHook(Win32FlutterWindow* window, +void TextInputPlugin::KeyboardHook(FlutterWindowsView* view, int key, int scancode, int action, diff --git a/shell/platform/windows/text_input_plugin.h b/shell/platform/windows/text_input_plugin.h index 5acdaf25de6f0..c0b2452ecd310 100644 --- a/shell/platform/windows/text_input_plugin.h +++ b/shell/platform/windows/text_input_plugin.h @@ -17,7 +17,7 @@ namespace flutter { -class Win32FlutterWindow; +class FlutterWindowsView; // Implements a text input plugin. // @@ -29,15 +29,14 @@ class TextInputPlugin : public KeyboardHookHandler { virtual ~TextInputPlugin(); // |KeyboardHookHandler| - void KeyboardHook(Win32FlutterWindow* window, + void KeyboardHook(FlutterWindowsView* view, int key, int scancode, int action, char32_t character) override; // |KeyboardHookHandler| - void TextHook(Win32FlutterWindow* window, - const std::u16string& text) override; + void TextHook(FlutterWindowsView* view, const std::u16string& text) override; private: // Sends the current state of the given model to the Flutter engine. diff --git a/shell/platform/windows/dpi_utils.cc b/shell/platform/windows/win32_dpi_utils.cc similarity index 99% rename from shell/platform/windows/dpi_utils.cc rename to shell/platform/windows/win32_dpi_utils.cc index 20b706ef2fa95..8fe994c463b18 100644 --- a/shell/platform/windows/dpi_utils.cc +++ b/shell/platform/windows/win32_dpi_utils.cc @@ -1,4 +1,4 @@ -#include "dpi_utils.h" +#include "win32_dpi_utils.h" namespace flutter { diff --git a/shell/platform/windows/dpi_utils.h b/shell/platform/windows/win32_dpi_utils.h similarity index 95% rename from shell/platform/windows/dpi_utils.h rename to shell/platform/windows/win32_dpi_utils.h index 1c14994b61235..1481aecb54ab9 100644 --- a/shell/platform/windows/dpi_utils.h +++ b/shell/platform/windows/win32_dpi_utils.h @@ -13,7 +13,7 @@ namespace flutter { /// backward compatible down to Windows Vista. If |hwnd| is nullptr, returns the /// DPI for the primary monitor. If Per-Monitor DPI awareness is not available, /// returns the system's DPI. -UINT GetDpiForHWND(HWND hwnd); +UINT GetDpiForHWND(::HWND hwnd); /// Returns the DPI of a given monitor. Defaults to 96 if the API is not /// available. diff --git a/shell/platform/windows/dpi_utils_unittests.cc b/shell/platform/windows/win32_dpi_utils_unittests.cc similarity index 89% rename from shell/platform/windows/dpi_utils_unittests.cc rename to shell/platform/windows/win32_dpi_utils_unittests.cc index d69da0588827b..90a580bb95318 100644 --- a/shell/platform/windows/dpi_utils_unittests.cc +++ b/shell/platform/windows/win32_dpi_utils_unittests.cc @@ -1,6 +1,6 @@ #include -#include "flutter/shell/platform/windows/dpi_utils.h" +#include "flutter/shell/platform/windows/win32_dpi_utils.h" #include "gtest/gtest.h" namespace flutter { diff --git a/shell/platform/windows/win32_flutter_window.cc b/shell/platform/windows/win32_flutter_window.cc index 4976a70b064d0..752720dbee0ca 100644 --- a/shell/platform/windows/win32_flutter_window.cc +++ b/shell/platform/windows/win32_flutter_window.cc @@ -8,76 +8,32 @@ namespace flutter { // constant for machines running at 100% scaling. constexpr int base_dpi = 96; -Win32FlutterWindow::Win32FlutterWindow(int width, int height) { - surface_manager = std::make_unique(); - Win32Window::InitializeChild("FLUTTERVIEW", width, height); -} +constexpr int kScrollOffsetMultiplier = 20; -Win32FlutterWindow::~Win32FlutterWindow() { - DestroyRenderSurface(); - if (plugin_registrar_ && plugin_registrar_->destruction_handler) { - plugin_registrar_->destruction_handler(plugin_registrar_.get()); - } +Win32FlutterWindow::Win32FlutterWindow(int width, int height) : view_(nullptr) { + Win32Window::InitializeChild("FLUTTERVIEW", width, height); } -FlutterDesktopViewControllerRef Win32FlutterWindow::CreateWin32FlutterWindow( - const int width, - const int height) { - auto state = std::make_unique(); - state->view = std::make_unique(width, height); +Win32FlutterWindow::~Win32FlutterWindow() {} - // a window wrapper for the state block, distinct from the - // window_wrapper handed to plugin_registrar. - state->view_wrapper = std::make_unique(); - state->view_wrapper->window = state->view.get(); - return state.release(); +void Win32FlutterWindow::SetView(FlutterWindowsView* window) { + view_ = window; } -void Win32FlutterWindow::SetState(FLUTTER_API_SYMBOL(FlutterEngine) eng) { - engine_ = eng; - - auto messenger = std::make_unique(); - message_dispatcher_ = - std::make_unique(messenger.get()); - messenger->engine = engine_; - messenger->dispatcher = message_dispatcher_.get(); - - window_wrapper_ = std::make_unique(); - window_wrapper_->window = this; - - plugin_registrar_ = std::make_unique(); - plugin_registrar_->messenger = std::move(messenger); - plugin_registrar_->window = window_wrapper_.get(); - - internal_plugin_registrar_ = - std::make_unique(plugin_registrar_.get()); - - // Set up the keyboard handlers. - auto internal_plugin_messenger = internal_plugin_registrar_->messenger(); - keyboard_hook_handlers_.push_back( - std::make_unique(internal_plugin_messenger)); - keyboard_hook_handlers_.push_back( - std::make_unique(internal_plugin_messenger)); - platform_handler_ = std::make_unique( - internal_plugin_messenger, this); +WindowsRenderTarget Win32FlutterWindow::GetRenderTarget() { + return WindowsRenderTarget::CreateForHWND(GetWindowHandle()); +} - process_events_ = true; +float Win32FlutterWindow::GetDpiScale() { + return static_cast(GetCurrentDPI()) / static_cast(base_dpi); } -FlutterDesktopPluginRegistrarRef Win32FlutterWindow::GetRegistrar() { - return plugin_registrar_.get(); +float Win32FlutterWindow::GetPhysicalWidth() { + return GetCurrentWidth(); } -// Converts a FlutterPlatformMessage to an equivalent FlutterDesktopMessage. -static FlutterDesktopMessage ConvertToDesktopMessage( - const FlutterPlatformMessage& engine_message) { - FlutterDesktopMessage message = {}; - message.struct_size = sizeof(message); - message.channel = engine_message.channel; - message.message = engine_message.message; - message.message_size = engine_message.message_size; - message.response_handle = engine_message.response_handle; - return message; +float Win32FlutterWindow::GetPhysicalHeight() { + return GetCurrentHeight(); } // Translates button codes from Win32 API to FlutterPointerMouseButtons. @@ -101,265 +57,61 @@ static uint64_t ConvertWinButtonToFlutterButton(UINT button) { return 0; } -// The Flutter Engine calls out to this function when new platform messages -// are available. -void Win32FlutterWindow::HandlePlatformMessage( - const FlutterPlatformMessage* engine_message) { - if (engine_message->struct_size != sizeof(FlutterPlatformMessage)) { - std::cerr << "Invalid message size received. Expected: " - << sizeof(FlutterPlatformMessage) << " but received " - << engine_message->struct_size << std::endl; - return; - } - - auto message = ConvertToDesktopMessage(*engine_message); - - message_dispatcher_->HandleMessage( - message, [this] { this->process_events_ = false; }, - [this] { this->process_events_ = true; }); -} - void Win32FlutterWindow::OnDpiScale(unsigned int dpi){}; // When DesktopWindow notifies that a WM_Size message has come in // lets FlutterEngine know about the new size. void Win32FlutterWindow::OnResize(unsigned int width, unsigned int height) { - SendWindowMetrics(); + if (view_ != nullptr) { + view_->OnWindowSizeChanged(width, height); + } } void Win32FlutterWindow::OnPointerMove(double x, double y) { - if (process_events_) { - SendPointerMove(x, y); - } + view_->OnPointerMove(x, y); } void Win32FlutterWindow::OnPointerDown(double x, double y, UINT button) { - if (process_events_) { - uint64_t flutter_button = ConvertWinButtonToFlutterButton(button); - if (flutter_button != 0) { - uint64_t mouse_buttons = GetMouseState().buttons | flutter_button; - SetMouseButtons(mouse_buttons); - SendPointerDown(x, y); - } + uint64_t flutter_button = ConvertWinButtonToFlutterButton(button); + if (flutter_button != 0) { + view_->OnPointerDown( + x, y, static_cast(flutter_button)); } } void Win32FlutterWindow::OnPointerUp(double x, double y, UINT button) { - if (process_events_) { - uint64_t flutter_button = ConvertWinButtonToFlutterButton(button); - if (flutter_button != 0) { - uint64_t mouse_buttons = GetMouseState().buttons & ~flutter_button; - SetMouseButtons(mouse_buttons); - SendPointerUp(x, y); - } + uint64_t flutter_button = ConvertWinButtonToFlutterButton(button); + if (flutter_button != 0) { + view_->OnPointerUp(x, y, + static_cast(flutter_button)); } } void Win32FlutterWindow::OnPointerLeave() { - if (process_events_) { - SendPointerLeave(); - } + view_->OnPointerLeave(); } void Win32FlutterWindow::OnText(const std::u16string& text) { - if (process_events_) { - SendText(text); - } + view_->OnText(text); } void Win32FlutterWindow::OnKey(int key, int scancode, int action, char32_t character) { - if (process_events_) { - SendKey(key, scancode, action, character); - } + view_->OnKey(key, scancode, action, character); } void Win32FlutterWindow::OnScroll(double delta_x, double delta_y) { - if (process_events_) { - SendScroll(delta_x, delta_y); - } -} - -void Win32FlutterWindow::OnFontChange() { - if (engine_ == nullptr) { - return; - } - FlutterEngineReloadSystemFonts(engine_); -} - -// Sends new size information to FlutterEngine. -void Win32FlutterWindow::SendWindowMetrics() { - if (engine_ == nullptr) { - return; - } - - FlutterWindowMetricsEvent event = {}; - event.struct_size = sizeof(event); - event.width = GetCurrentWidth(); - event.height = GetCurrentHeight(); - event.pixel_ratio = static_cast(GetCurrentDPI()) / base_dpi; - auto result = FlutterEngineSendWindowMetricsEvent(engine_, &event); -} - -// Updates |event_data| with the current location of the mouse cursor. -void Win32FlutterWindow::SetEventLocationFromCursorPosition( - FlutterPointerEvent* event_data) { POINT point; GetCursorPos(&point); ScreenToClient(GetWindowHandle(), &point); - - event_data->x = point.x; - event_data->y = point.y; -} - -// Set's |event_data|'s phase to either kMove or kHover depending on the current -// primary mouse button state. -void Win32FlutterWindow::SetEventPhaseFromCursorButtonState( - FlutterPointerEvent* event_data) { - MouseState state = GetMouseState(); - // For details about this logic, see FlutterPointerPhase in the embedder.h - // file. - event_data->phase = state.buttons == 0 ? state.flutter_state_is_down - ? FlutterPointerPhase::kUp - : FlutterPointerPhase::kHover - : state.flutter_state_is_down - ? FlutterPointerPhase::kMove - : FlutterPointerPhase::kDown; -} - -void Win32FlutterWindow::SendPointerMove(double x, double y) { - FlutterPointerEvent event = {}; - event.x = x; - event.y = y; - SetEventPhaseFromCursorButtonState(&event); - SendPointerEventWithData(event); + view_->OnScroll(point.x, point.y, delta_x, delta_y, kScrollOffsetMultiplier); } -void Win32FlutterWindow::SendPointerDown(double x, double y) { - FlutterPointerEvent event = {}; - SetEventPhaseFromCursorButtonState(&event); - event.x = x; - event.y = y; - SendPointerEventWithData(event); - SetMouseFlutterStateDown(true); -} - -void Win32FlutterWindow::SendPointerUp(double x, double y) { - FlutterPointerEvent event = {}; - SetEventPhaseFromCursorButtonState(&event); - event.x = x; - event.y = y; - SendPointerEventWithData(event); - if (event.phase == FlutterPointerPhase::kUp) { - SetMouseFlutterStateDown(false); - } -} - -void Win32FlutterWindow::SendPointerLeave() { - FlutterPointerEvent event = {}; - event.phase = FlutterPointerPhase::kRemove; - SendPointerEventWithData(event); -} - -void Win32FlutterWindow::SendText(const std::u16string& text) { - for (const auto& handler : keyboard_hook_handlers_) { - handler->TextHook(this, text); - } -} - -void Win32FlutterWindow::SendKey(int key, - int scancode, - int action, - char32_t character) { - for (const auto& handler : keyboard_hook_handlers_) { - handler->KeyboardHook(this, key, scancode, action, character); - } -} - -void Win32FlutterWindow::SendScroll(double delta_x, double delta_y) { - FlutterPointerEvent event = {}; - SetEventLocationFromCursorPosition(&event); - SetEventPhaseFromCursorButtonState(&event); - event.signal_kind = FlutterPointerSignalKind::kFlutterPointerSignalKindScroll; - // TODO: See if this can be queried from the OS; this value is chosen - // arbitrarily to get something that feels reasonable. - const int kScrollOffsetMultiplier = 20; - event.scroll_delta_x = delta_x * kScrollOffsetMultiplier; - event.scroll_delta_y = delta_y * kScrollOffsetMultiplier; - SendPointerEventWithData(event); -} - -void Win32FlutterWindow::SendPointerEventWithData( - const FlutterPointerEvent& event_data) { - MouseState mouse_state = GetMouseState(); - // If sending anything other than an add, and the pointer isn't already added, - // synthesize an add to satisfy Flutter's expectations about events. - if (!mouse_state.flutter_state_is_added && - event_data.phase != FlutterPointerPhase::kAdd) { - FlutterPointerEvent event = {}; - event.phase = FlutterPointerPhase::kAdd; - event.x = event_data.x; - event.y = event_data.y; - event.buttons = 0; - SendPointerEventWithData(event); - } - // Don't double-add (e.g., if events are delivered out of order, so an add has - // already been synthesized). - if (mouse_state.flutter_state_is_added && - event_data.phase == FlutterPointerPhase::kAdd) { - return; - } - - FlutterPointerEvent event = event_data; - event.device_kind = kFlutterPointerDeviceKindMouse; - event.buttons = mouse_state.buttons; - - // Set metadata that's always the same regardless of the event. - event.struct_size = sizeof(event); - event.timestamp = - std::chrono::duration_cast( - std::chrono::high_resolution_clock::now().time_since_epoch()) - .count(); - - FlutterEngineSendPointerEvent(engine_, &event, 1); - - if (event_data.phase == FlutterPointerPhase::kAdd) { - SetMouseFlutterStateAdded(true); - } else if (event_data.phase == FlutterPointerPhase::kRemove) { - SetMouseFlutterStateAdded(false); - ResetMouseState(); - } -} - -bool Win32FlutterWindow::MakeCurrent() { - return surface_manager->MakeCurrent(render_surface); -} - -bool Win32FlutterWindow::MakeResourceCurrent() { - return surface_manager->MakeResourceCurrent(); -} - -bool Win32FlutterWindow::ClearContext() { - return surface_manager->MakeCurrent(nullptr); -} - -bool Win32FlutterWindow::SwapBuffers() { - return surface_manager->SwapBuffers(render_surface); -} - -void Win32FlutterWindow::CreateRenderSurface() { - if (surface_manager && render_surface == EGL_NO_SURFACE) { - render_surface = surface_manager->CreateSurface(GetWindowHandle()); - } +void Win32FlutterWindow::OnFontChange() { + view_->OnFontChange(); } -void Win32FlutterWindow::DestroyRenderSurface() { - if (surface_manager) { - surface_manager->DestroySurface(render_surface); - } - render_surface = EGL_NO_SURFACE; -} } // namespace flutter diff --git a/shell/platform/windows/win32_flutter_window.h b/shell/platform/windows/win32_flutter_window.h index aff194a0e5ea4..d4fab2a997e3d 100644 --- a/shell/platform/windows/win32_flutter_window.h +++ b/shell/platform/windows/win32_flutter_window.h @@ -7,20 +7,15 @@ #include +#include #include #include -#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/embedder/embedder.h" -#include "flutter/shell/platform/windows/angle_surface_manager.h" -#include "flutter/shell/platform/windows/key_event_handler.h" -#include "flutter/shell/platform/windows/keyboard_hook_handler.h" -#include "flutter/shell/platform/windows/platform_handler.h" -#include "flutter/shell/platform/windows/public/flutter_windows.h" -#include "flutter/shell/platform/windows/text_input_plugin.h" + +#include "flutter/shell/platform/windows/flutter_windows_view.h" #include "flutter/shell/platform/windows/win32_window.h" -#include "flutter/shell/platform/windows/window_state.h" +#include "flutter/shell/platform/windows/window_binding_handler.h" namespace flutter { @@ -28,15 +23,16 @@ namespace flutter { // future, there will likely be a CoreWindow-based FlutterWindow as well. At // the point may make sense to dependency inject the native window rather than // inherit. -class Win32FlutterWindow : public Win32Window { +class Win32FlutterWindow : public Win32Window, + public FlutterWindowBindingHandler { public: // Create flutter Window for use as child window Win32FlutterWindow(int width, int height); virtual ~Win32FlutterWindow(); - static FlutterDesktopViewControllerRef CreateWin32FlutterWindow(int width, - int height); + // static FlutterDesktopViewControllerRef CreateWin32FlutterWindow(int width, + // int height); // |Win32Window| void OnDpiScale(unsigned int dpi) override; @@ -68,76 +64,22 @@ class Win32FlutterWindow : public Win32Window { // |Win32Window| void OnFontChange() override; - // Configures the window instance with an instance of a running Flutter engine - // returning a configured FlutterDesktopWindowControllerRef. - void SetState(FLUTTER_API_SYMBOL(FlutterEngine) state); - - // Returns the currently configured Plugin Registrar. - FlutterDesktopPluginRegistrarRef GetRegistrar(); - - // Callback passed to Flutter engine for notifying window of platform - // messages. - void HandlePlatformMessage(const FlutterPlatformMessage*); - - // Create a surface for Flutter engine to render into. - void CreateRenderSurface(); - - // Callbacks for clearing context, settings context and swapping buffers. - bool ClearContext(); - bool MakeCurrent(); - bool MakeResourceCurrent(); - bool SwapBuffers(); - - // Sends a window metrics update to the Flutter engine using current window - // dimensions in physical - void SendWindowMetrics(); - - private: - // Destroy current rendering surface if one has been allocated. - void DestroyRenderSurface(); - - // Reports a mouse movement to Flutter engine. - void SendPointerMove(double x, double y); - - // Reports mouse press to Flutter engine. - void SendPointerDown(double x, double y); - - // Reports mouse release to Flutter engine. - void SendPointerUp(double x, double y); + // |SetView| + void SetView(FlutterWindowsView* view) override; - // Reports mouse left the window client area. - // - // Win32 api doesn't have "mouse enter" event. Therefore, there is no - // SendPointerEnter method. A mouse enter event is tracked then the "move" - // event is called. - void SendPointerLeave(); + // |GetRenderTarget| + WindowsRenderTarget GetRenderTarget() override; - // Reports text input to Flutter engine. - void SendText(const std::u16string& text); + // |GetDpiScale| + float GetDpiScale() override; - // Reports a raw keyboard message to Flutter engine. - void SendKey(int key, int scancode, int action, char32_t character); + // |GetPhysicalWidth| + float GetPhysicalWidth() override; - // Reports scroll wheel events to Flutter engine. - void SendScroll(double delta_x, double delta_y); + // |GetPhysicalHeight| + float GetPhysicalHeight() override; - // Updates |event_data| with the current location of the mouse cursor. - void SetEventLocationFromCursorPosition(FlutterPointerEvent* event_data); - - // Set's |event_data|'s phase to either kMove or kHover depending on the - // current - // primary mouse button state. - void SetEventPhaseFromCursorButtonState(FlutterPointerEvent* event_data); - - // Sends a pointer event to the Flutter engine based on givern data. Since - // all input messages are passed in physical pixel values, no translation is - // needed before passing on to engine. - void SendPointerEventWithData(const FlutterPointerEvent& event_data); - - std::unique_ptr surface_manager = nullptr; - EGLSurface render_surface = EGL_NO_SURFACE; - - // state of the mouse button + // state of the mouse button bool pointer_is_down_ = false; // The handle to the Flutter engine instance. @@ -150,27 +92,9 @@ class Win32FlutterWindow : public Win32Window { // been added since it was last removed). bool pointer_currently_added_ = false; - // The window handle given to API clients. - std::unique_ptr window_wrapper_; - - // The plugin registrar handle given to API clients. - std::unique_ptr plugin_registrar_; - - // Message dispatch manager for messages from the Flutter engine. - std::unique_ptr message_dispatcher_; - - // The plugin registrar managing internal plugins. - std::unique_ptr internal_plugin_registrar_; - - // Handlers for keyboard events from Windows. - std::vector> - keyboard_hook_handlers_; - - // Handler for the flutter/platform channel. - std::unique_ptr platform_handler_; - - // should we forword input messages or not - bool process_events_ = false; + // A pointer to a FlutterWindowsView that can be used to update engine + // windowing and input state. + FlutterWindowsView* view_; }; } // namespace flutter diff --git a/shell/platform/windows/win32_flutter_window_unittests.cc b/shell/platform/windows/win32_flutter_window_unittests.cc index dece5a280f807..ea441fa6299a7 100644 --- a/shell/platform/windows/win32_flutter_window_unittests.cc +++ b/shell/platform/windows/win32_flutter_window_unittests.cc @@ -11,7 +11,7 @@ TEST(Win32FlutterWindowTest, CreateDestroy) { TEST(Win32FlutterWindowTest, CanFontChange) { Win32FlutterWindowTest window(800, 600); - HWND hwnd = window.GetWindowHandle(); + ::HWND hwnd = window.GetWindowHandle(); LRESULT result = SendMessage(hwnd, WM_FONTCHANGE, NULL, NULL); ASSERT_EQ(result, 0); ASSERT_TRUE(window.OnFontChangeWasCalled()); diff --git a/shell/platform/windows/platform_handler.cc b/shell/platform/windows/win32_platform_handler.cc similarity index 74% rename from shell/platform/windows/platform_handler.cc rename to shell/platform/windows/win32_platform_handler.cc index c4b83130a785b..d2a0454d91d63 100644 --- a/shell/platform/windows/platform_handler.cc +++ b/shell/platform/windows/win32_platform_handler.cc @@ -2,7 +2,7 @@ // 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/platform_handler.h" +#include "flutter/shell/platform/windows/win32_platform_handler.h" #include @@ -10,8 +10,8 @@ #include #include "flutter/shell/platform/common/cpp/json_method_codec.h" +#include "flutter/shell/platform/windows/flutter_windows_view.h" #include "flutter/shell/platform/windows/string_conversion.h" -#include "flutter/shell/platform/windows/win32_flutter_window.h" static constexpr char kChannelName[] = "flutter/platform"; @@ -116,7 +116,7 @@ class ScopedClipboard { // Attempts to open the clipboard for the given window, returning true if // successful. - bool Open(HWND window); + bool Open(::HWND window); // Returns true if there is string data available to get. bool HasString(); @@ -148,7 +148,7 @@ ScopedClipboard::~ScopedClipboard() { } } -bool ScopedClipboard::Open(HWND window) { +bool ScopedClipboard::Open(::HWND window) { opened_ = ::OpenClipboard(window); return opened_; } @@ -198,12 +198,12 @@ bool ScopedClipboard::SetString(const std::wstring string) { } // namespace PlatformHandler::PlatformHandler(flutter::BinaryMessenger* messenger, - Win32FlutterWindow* window) + FlutterWindowsView* view) : channel_(std::make_unique>( messenger, kChannelName, &flutter::JsonMethodCodec::GetInstance())), - window_(window) { + view_(view) { channel_->SetMethodCallHandler( [this]( const flutter::MethodCall& call, @@ -224,58 +224,58 @@ void PlatformHandler::HandleMethodCall( result->Error(kClipboardError, kUnknownClipboardFormatMessage); return; } - ScopedClipboard clipboard; - if (!clipboard.Open(window_->GetWindowHandle())) { - rapidjson::Document error_code; - error_code.SetInt(::GetLastError()); - result->Error(kClipboardError, "Unable to open clipboard", &error_code); - return; - } - if (!clipboard.HasString()) { - rapidjson::Document null; - result->Success(&null); - return; - } - std::optional clipboard_string = clipboard.GetString(); - if (!clipboard_string) { - rapidjson::Document error_code; - error_code.SetInt(::GetLastError()); - result->Error(kClipboardError, "Unable to get clipboard data", - &error_code); - return; - } + if (!clipboard.Open(view_->GetRenderTarget()->GetWindowHandle())) { + rapidjson::Document error_code; + error_code.SetInt(::GetLastError()); + result->Error(kClipboardError, "Unable to open clipboard", &error_code); + return; + } + if (!clipboard.HasString()) { + rapidjson::Document null; + result->Success(&null); + return; + } + std::optional clipboard_string = clipboard.GetString(); + if (!clipboard_string) { + rapidjson::Document error_code; + error_code.SetInt(::GetLastError()); + result->Error(kClipboardError, "Unable to get clipboard data", + &error_code); + return; + } - rapidjson::Document document; - document.SetObject(); - rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); - document.AddMember( - rapidjson::Value(kTextKey, allocator), - rapidjson::Value(Utf8FromUtf16(*clipboard_string), allocator), - allocator); - result->Success(&document); - } else if (method.compare(kSetClipboardDataMethod) == 0) { - const rapidjson::Value& document = *method_call.arguments(); - rapidjson::Value::ConstMemberIterator itr = document.FindMember(kTextKey); - if (itr == document.MemberEnd()) { - result->Error(kClipboardError, kUnknownClipboardFormatMessage); - return; - } + rapidjson::Document document; + document.SetObject(); + rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); + document.AddMember( + rapidjson::Value(kTextKey, allocator), + rapidjson::Value(Utf8FromUtf16(*clipboard_string), allocator), + allocator); + result->Success(&document); + } else if (method.compare(kSetClipboardDataMethod) == 0) { + const rapidjson::Value& document = *method_call.arguments(); + rapidjson::Value::ConstMemberIterator itr = document.FindMember(kTextKey); + if (itr == document.MemberEnd()) { + result->Error(kClipboardError, kUnknownClipboardFormatMessage); + return; + } - ScopedClipboard clipboard; - if (!clipboard.Open(window_->GetWindowHandle())) { - rapidjson::Document error_code; - error_code.SetInt(::GetLastError()); - result->Error(kClipboardError, "Unable to open clipboard", &error_code); - return; - } - if (!clipboard.SetString(Utf16FromUtf8(itr->value.GetString()))) { - rapidjson::Document error_code; - error_code.SetInt(::GetLastError()); - result->Error(kClipboardError, "Unable to set clipboard data", - &error_code); - return; - } + ScopedClipboard clipboard; + + if (!clipboard.Open(view_->GetRenderTarget()->GetWindowHandle())) { + rapidjson::Document error_code; + error_code.SetInt(::GetLastError()); + result->Error(kClipboardError, "Unable to open clipboard", &error_code); + return; + } + if (!clipboard.SetString(Utf16FromUtf8(itr->value.GetString()))) { + rapidjson::Document error_code; + error_code.SetInt(::GetLastError()); + result->Error(kClipboardError, "Unable to set clipboard data", + &error_code); + return; + } result->Success(); } else { result->NotImplemented(); diff --git a/shell/platform/windows/platform_handler.h b/shell/platform/windows/win32_platform_handler.h similarity index 91% rename from shell/platform/windows/platform_handler.h rename to shell/platform/windows/win32_platform_handler.h index 8cb09a80666a7..bcf939edd4174 100644 --- a/shell/platform/windows/platform_handler.h +++ b/shell/platform/windows/win32_platform_handler.h @@ -12,13 +12,13 @@ namespace flutter { -class Win32FlutterWindow; +class FlutterWindowsView; // Handler for internal system channels. class PlatformHandler { public: explicit PlatformHandler(flutter::BinaryMessenger* messenger, - Win32FlutterWindow* window); + FlutterWindowsView* view); private: // Called when a method is called on |channel_|; @@ -30,7 +30,7 @@ class PlatformHandler { std::unique_ptr> channel_; // A reference to the win32 window. - Win32FlutterWindow* window_; + FlutterWindowsView* view_; }; } // namespace flutter diff --git a/shell/platform/windows/win32_window.cc b/shell/platform/windows/win32_window.cc index e4cf979167b73..08da305aa9206 100644 --- a/shell/platform/windows/win32_window.cc +++ b/shell/platform/windows/win32_window.cc @@ -4,7 +4,7 @@ #include "flutter/shell/platform/windows/win32_window.h" -#include "dpi_utils.h" +#include "win32_dpi_utils.h" namespace flutter { diff --git a/shell/platform/windows/win32_window.h b/shell/platform/windows/win32_window.h index d4481d89e2a68..81c4a3905cb1d 100644 --- a/shell/platform/windows/win32_window.h +++ b/shell/platform/windows/win32_window.h @@ -15,7 +15,7 @@ namespace flutter { // Struct holding the mouse state. The engine doesn't keep track of which mouse // buttons have been pressed, so it's the embedding's responsibility. -struct MouseState { +struct MouseStateWin32 { // True if the last event sent to Flutter had at least one mouse button // pressed. bool flutter_state_is_down = false; @@ -44,7 +44,7 @@ class Win32Window { unsigned int width, unsigned int height); - HWND GetWindowHandle(); + ::HWND GetWindowHandle(); protected: // Converts a c string to a wide unicode string. @@ -59,7 +59,7 @@ class Win32Window { // non-client DPI scaling so that the non-client area automatically // responsponds to changes in DPI. All other messages are handled by // MessageHandler. - static LRESULT CALLBACK WndProc(HWND const window, + static LRESULT CALLBACK WndProc(::HWND const window, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept; @@ -68,7 +68,7 @@ class Win32Window { // size change and DPI. Delegates handling of these to member overloads that // inheriting classes can handle. LRESULT - MessageHandler(HWND window, + MessageHandler(::HWND window, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept; @@ -78,7 +78,7 @@ class Win32Window { // the window to the new suggested size. If |top_level| is not set, the // |lParam| will not contain a suggested size hence ignore it. LRESULT - HandleDpiChange(HWND hWnd, WPARAM wParam, LPARAM lParam, bool top_level); + HandleDpiChange(::HWND hWnd, WPARAM wParam, LPARAM lParam, bool top_level); // Called when the DPI changes either when a // user drags the window between monitors of differing DPI or when the user @@ -120,39 +120,18 @@ class Win32Window { UINT GetCurrentHeight(); - // Gets the current mouse state. - MouseState GetMouseState() { return mouse_state_; } - - // Resets the mouse state to its default values. - void ResetMouseState() { mouse_state_ = MouseState(); } - - // Updates the mouse state to whether the last event to Flutter had at least - // one mouse button pressed. - void SetMouseFlutterStateDown(bool is_down) { - mouse_state_.flutter_state_is_down = is_down; - } - - // Updates the mouse state to whether the last event to Flutter was a kAdd - // event. - void SetMouseFlutterStateAdded(bool is_added) { - mouse_state_.flutter_state_is_added = is_added; - } - - // Updates the currently pressed buttons. - void SetMouseButtons(uint64_t buttons) { mouse_state_.buttons = buttons; } - private: // Release OS resources asociated with window. void Destroy(); // Activates tracking for a "mouse leave" event. - void TrackMouseLeaveEvent(HWND hwnd); + void TrackMouseLeaveEvent(::HWND hwnd); // Stores new width and height and calls |OnResize| to notify inheritors void HandleResize(UINT width, UINT height); // Retrieves a class instance pointer for |window| - static Win32Window* GetThisFromHandle(HWND const window) noexcept; + static Win32Window* GetThisFromHandle(::HWND const window) noexcept; int current_dpi_ = 0; int current_width_ = 0; int current_height_ = 0; @@ -162,7 +141,7 @@ class Win32Window { const static long kWmDpiChangedBeforeParent = 0x02E2; // Member variable to hold window handle. - HWND window_handle_ = nullptr; + ::HWND window_handle_ = nullptr; // Member variable to hold the window title. std::wstring window_class_name_; @@ -170,9 +149,6 @@ class Win32Window { // Set to true to be notified when the mouse leaves the window. bool tracking_mouse_leave_ = false; - // Keeps track of mouse state in relation to the window. - MouseState mouse_state_; - // Keeps track of the last key code produced by a WM_KEYDOWN or WM_SYSKEYDOWN // message. int keycode_for_char_message_ = 0; diff --git a/shell/platform/windows/window_binding_handler.h b/shell/platform/windows/window_binding_handler.h new file mode 100644 index 0000000000000..05d9f4b21711f --- /dev/null +++ b/shell/platform/windows/window_binding_handler.h @@ -0,0 +1,74 @@ +// 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_WINDOW_BINDING_HANDLER_H_ +#define FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOW_BINDING_HANDLER_H_ + +#include +#include + +#include + +#include "flutter/shell/platform/windows/public/flutter_windows.h" + +namespace flutter { + +class FlutterWindowsView; + +// Represents the type of a WindowsRenderTarget +enum WindowsRenderTargetType { HWND /*, Visual*/}; + +struct WindowsRenderTarget { + +// Creates a new HWND backed render target from window + static WindowsRenderTarget CreateForHWND(::HWND window) { + WindowsRenderTarget wrt; + wrt.type_ = WindowsRenderTargetType::HWND; + wrt.render_target_ = window; + return wrt; + } + + // Returns the type of instance + WindowsRenderTargetType GetType() { return type_; } + +// Returns the physical window for HWND backed instances + ::HWND GetWindowHandle() { return std::get<::HWND>(render_target_); } + + private: +// prevent external construction + WindowsRenderTarget() : render_target_(static_cast<::HWND>(0)) {} + + // type of instance + WindowsRenderTargetType type_; + + // win32 WindowsRenderTarget instances will by HWND backed, in the future + // UWP instances will be backed by a SpriteVisual + std::variant + render_target_; +}; + +// Abstract class for binding Windows OS Windows to Flutter views. +class FlutterWindowBindingHandler { + public: + virtual ~FlutterWindowBindingHandler() = default; + + // Caller provides a view for implementor to use to communicate state changes. + virtual void SetView(FlutterWindowsView* view) = 0; + + // Implementor returns a valid WindowsRenderTarget representing the backing window. + virtual WindowsRenderTarget GetRenderTarget() = 0; + + // Implementor returns the scale factor for the backing window. + virtual float GetDpiScale() = 0; + + // Implementor returns the width of the backing window in physical pixels. + virtual float GetPhysicalWidth() = 0; + + // Implementor returns the height of the backing window in physical pixels. + virtual float GetPhysicalHeight() = 0; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOW_BINDING_HANDLER_H_ diff --git a/shell/platform/windows/window_state.h b/shell/platform/windows/window_state.h index 61721fa1f21b9..a3e36fa718230 100644 --- a/shell/platform/windows/window_state.h +++ b/shell/platform/windows/window_state.h @@ -10,19 +10,19 @@ #include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/windows/key_event_handler.h" #include "flutter/shell/platform/windows/keyboard_hook_handler.h" -#include "flutter/shell/platform/windows/platform_handler.h" #include "flutter/shell/platform/windows/text_input_plugin.h" +#include "flutter/shell/platform/windows/win32_platform_handler.h" #include "flutter/shell/platform/windows/win32_task_runner.h" namespace flutter { -struct Win32FlutterWindow; +struct FlutterWindowsView; } // Struct for storing state within an instance of the windows native (HWND or // CoreWindow) Window. struct FlutterDesktopViewControllerState { - // The win32 window that owns this state object. - std::unique_ptr view; + // The view that owns this state object. + std::unique_ptr view; // The state associate with the engine backing the view. std::unique_ptr engine_state; @@ -35,8 +35,8 @@ struct FlutterDesktopViewControllerState { // controller so that it can be provided to plugins without giving them access // to all of the controller-based functionality. struct FlutterDesktopView { - // The window that (indirectly) owns this state object. - flutter::Win32FlutterWindow* window; + // The view that (indirectly) owns this state object. + flutter::FlutterWindowsView* view; }; struct AotDataDeleter { @@ -65,7 +65,7 @@ struct FlutterDesktopPluginRegistrar { std::unique_ptr messenger; // The handle for the window associated with this registrar. - FlutterDesktopView* window; + FlutterDesktopView* view; // Callback to be called on registrar destruction. FlutterDesktopOnRegistrarDestroyed destruction_handler; From b031ff0abe085128ad21c7fa0405b8a53e15dcfe Mon Sep 17 00:00:00 2001 From: James Clarke Date: Fri, 19 Jun 2020 05:13:59 -0700 Subject: [PATCH 02/15] clang-format --- .../platform/windows/angle_surface_manager.cc | 8 +- shell/platform/windows/flutter_windows_view.h | 4 +- shell/platform/windows/win32_flutter_window.h | 2 +- .../windows/win32_platform_handler.cc | 94 +++++++++---------- .../platform/windows/window_binding_handler.h | 12 +-- 5 files changed, 61 insertions(+), 59 deletions(-) diff --git a/shell/platform/windows/angle_surface_manager.cc b/shell/platform/windows/angle_surface_manager.cc index c6bdaafce2dca..e141d30994447 100644 --- a/shell/platform/windows/angle_surface_manager.cc +++ b/shell/platform/windows/angle_surface_manager.cc @@ -169,7 +169,8 @@ void AngleSurfaceManager::CleanUp() { } } -EGLSurface AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target) { +EGLSurface AngleSurfaceManager::CreateSurface( + WindowsRenderTarget* render_target) { if (!render_target || !initialize_succeeded_) { return EGL_NO_SURFACE; } @@ -178,9 +179,10 @@ EGLSurface AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target const EGLint surfaceAttributes[] = {EGL_NONE}; - surface = eglCreateWindowSurface(egl_display_, egl_config_, + surface = eglCreateWindowSurface( + egl_display_, egl_config_, static_cast(render_target->GetWindowHandle()), - surfaceAttributes); + surfaceAttributes); if (surface == EGL_NO_SURFACE) { std::cerr << "Surface creation failed." << std::endl; } diff --git a/shell/platform/windows/flutter_windows_view.h b/shell/platform/windows/flutter_windows_view.h index 2b169ebccbc2b..028c3b5bbdae3 100644 --- a/shell/platform/windows/flutter_windows_view.h +++ b/shell/platform/windows/flutter_windows_view.h @@ -48,7 +48,8 @@ class FlutterWindowsView { ~FlutterWindowsView(); - // Factory for creating FlutterWindowsView requiring an implementator of FlutterWindowBindingHandler. + // Factory for creating FlutterWindowsView requiring an implementator of + // FlutterWindowBindingHandler. static FlutterDesktopViewControllerRef CreateFlutterWindowsView( std::unique_ptr windowbinding); @@ -119,7 +120,6 @@ class FlutterWindowsView { void OnFontChange(); private: - // Sends a window metrics update to the Flutter engine using current window // dimensions in physical void SendWindowMetrics(size_t width, size_t height, double dpiscale) const; diff --git a/shell/platform/windows/win32_flutter_window.h b/shell/platform/windows/win32_flutter_window.h index d4fab2a997e3d..e46444564da9d 100644 --- a/shell/platform/windows/win32_flutter_window.h +++ b/shell/platform/windows/win32_flutter_window.h @@ -79,7 +79,7 @@ class Win32FlutterWindow : public Win32Window, // |GetPhysicalHeight| float GetPhysicalHeight() override; - // state of the mouse button + // state of the mouse button bool pointer_is_down_ = false; // The handle to the Flutter engine instance. diff --git a/shell/platform/windows/win32_platform_handler.cc b/shell/platform/windows/win32_platform_handler.cc index d2a0454d91d63..7b67351914dc8 100644 --- a/shell/platform/windows/win32_platform_handler.cc +++ b/shell/platform/windows/win32_platform_handler.cc @@ -226,56 +226,56 @@ void PlatformHandler::HandleMethodCall( } ScopedClipboard clipboard; if (!clipboard.Open(view_->GetRenderTarget()->GetWindowHandle())) { - rapidjson::Document error_code; - error_code.SetInt(::GetLastError()); - result->Error(kClipboardError, "Unable to open clipboard", &error_code); - return; - } - if (!clipboard.HasString()) { - rapidjson::Document null; - result->Success(&null); - return; - } - std::optional clipboard_string = clipboard.GetString(); - if (!clipboard_string) { - rapidjson::Document error_code; - error_code.SetInt(::GetLastError()); - result->Error(kClipboardError, "Unable to get clipboard data", - &error_code); - return; - } + rapidjson::Document error_code; + error_code.SetInt(::GetLastError()); + result->Error(kClipboardError, "Unable to open clipboard", &error_code); + return; + } + if (!clipboard.HasString()) { + rapidjson::Document null; + result->Success(&null); + return; + } + std::optional clipboard_string = clipboard.GetString(); + if (!clipboard_string) { + rapidjson::Document error_code; + error_code.SetInt(::GetLastError()); + result->Error(kClipboardError, "Unable to get clipboard data", + &error_code); + return; + } - rapidjson::Document document; - document.SetObject(); - rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); - document.AddMember( - rapidjson::Value(kTextKey, allocator), - rapidjson::Value(Utf8FromUtf16(*clipboard_string), allocator), - allocator); - result->Success(&document); - } else if (method.compare(kSetClipboardDataMethod) == 0) { - const rapidjson::Value& document = *method_call.arguments(); - rapidjson::Value::ConstMemberIterator itr = document.FindMember(kTextKey); - if (itr == document.MemberEnd()) { - result->Error(kClipboardError, kUnknownClipboardFormatMessage); - return; - } + rapidjson::Document document; + document.SetObject(); + rapidjson::Document::AllocatorType& allocator = document.GetAllocator(); + document.AddMember( + rapidjson::Value(kTextKey, allocator), + rapidjson::Value(Utf8FromUtf16(*clipboard_string), allocator), + allocator); + result->Success(&document); + } else if (method.compare(kSetClipboardDataMethod) == 0) { + const rapidjson::Value& document = *method_call.arguments(); + rapidjson::Value::ConstMemberIterator itr = document.FindMember(kTextKey); + if (itr == document.MemberEnd()) { + result->Error(kClipboardError, kUnknownClipboardFormatMessage); + return; + } - ScopedClipboard clipboard; + ScopedClipboard clipboard; - if (!clipboard.Open(view_->GetRenderTarget()->GetWindowHandle())) { - rapidjson::Document error_code; - error_code.SetInt(::GetLastError()); - result->Error(kClipboardError, "Unable to open clipboard", &error_code); - return; - } - if (!clipboard.SetString(Utf16FromUtf8(itr->value.GetString()))) { - rapidjson::Document error_code; - error_code.SetInt(::GetLastError()); - result->Error(kClipboardError, "Unable to set clipboard data", - &error_code); - return; - } + if (!clipboard.Open(view_->GetRenderTarget()->GetWindowHandle())) { + rapidjson::Document error_code; + error_code.SetInt(::GetLastError()); + result->Error(kClipboardError, "Unable to open clipboard", &error_code); + return; + } + if (!clipboard.SetString(Utf16FromUtf8(itr->value.GetString()))) { + rapidjson::Document error_code; + error_code.SetInt(::GetLastError()); + result->Error(kClipboardError, "Unable to set clipboard data", + &error_code); + return; + } result->Success(); } else { result->NotImplemented(); diff --git a/shell/platform/windows/window_binding_handler.h b/shell/platform/windows/window_binding_handler.h index 05d9f4b21711f..2993aa6f80232 100644 --- a/shell/platform/windows/window_binding_handler.h +++ b/shell/platform/windows/window_binding_handler.h @@ -17,11 +17,10 @@ namespace flutter { class FlutterWindowsView; // Represents the type of a WindowsRenderTarget -enum WindowsRenderTargetType { HWND /*, Visual*/}; +enum WindowsRenderTargetType { HWND /*, Visual*/ }; struct WindowsRenderTarget { - -// Creates a new HWND backed render target from window + // Creates a new HWND backed render target from window static WindowsRenderTarget CreateForHWND(::HWND window) { WindowsRenderTarget wrt; wrt.type_ = WindowsRenderTargetType::HWND; @@ -32,11 +31,11 @@ struct WindowsRenderTarget { // Returns the type of instance WindowsRenderTargetType GetType() { return type_; } -// Returns the physical window for HWND backed instances + // Returns the physical window for HWND backed instances ::HWND GetWindowHandle() { return std::get<::HWND>(render_target_); } private: -// prevent external construction + // prevent external construction WindowsRenderTarget() : render_target_(static_cast<::HWND>(0)) {} // type of instance @@ -56,7 +55,8 @@ class FlutterWindowBindingHandler { // Caller provides a view for implementor to use to communicate state changes. virtual void SetView(FlutterWindowsView* view) = 0; - // Implementor returns a valid WindowsRenderTarget representing the backing window. + // Implementor returns a valid WindowsRenderTarget representing the backing + // window. virtual WindowsRenderTarget GetRenderTarget() = 0; // Implementor returns the scale factor for the backing window. From b15c01119a63562416bd2a2d460d80acca290071 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Wed, 24 Jun 2020 21:26:01 -0700 Subject: [PATCH 03/15] CR Feedback --- .../platform/windows/angle_surface_manager.cc | 2 +- shell/platform/windows/flutter_windows.cc | 2 +- .../platform/windows/win32_flutter_window.cc | 2 +- .../windows/win32_platform_handler.cc | 4 +- .../platform/windows/window_binding_handler.h | 46 ++++--------------- shell/platform/windows/window_state.h | 2 +- 6 files changed, 16 insertions(+), 42 deletions(-) diff --git a/shell/platform/windows/angle_surface_manager.cc b/shell/platform/windows/angle_surface_manager.cc index e141d30994447..1ddc7278e0b51 100644 --- a/shell/platform/windows/angle_surface_manager.cc +++ b/shell/platform/windows/angle_surface_manager.cc @@ -181,7 +181,7 @@ EGLSurface AngleSurfaceManager::CreateSurface( surface = eglCreateWindowSurface( egl_display_, egl_config_, - static_cast(render_target->GetWindowHandle()), + static_cast(std::get<::HWND>(*render_target)), surfaceAttributes); if (surface == EGL_NO_SURFACE) { std::cerr << "Surface creation failed." << std::endl; diff --git a/shell/platform/windows/flutter_windows.cc b/shell/platform/windows/flutter_windows.cc index afb8288b7eded..c0000d4b7dec7 100644 --- a/shell/platform/windows/flutter_windows.cc +++ b/shell/platform/windows/flutter_windows.cc @@ -268,7 +268,7 @@ FlutterDesktopViewRef FlutterDesktopGetView( } HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view_ref) { - return view_ref->view->GetRenderTarget()->GetWindowHandle(); + return std::get<::HWND>(*view_ref->view->GetRenderTarget()); } UINT FlutterDesktopGetDpiForHWND(HWND hwnd) { diff --git a/shell/platform/windows/win32_flutter_window.cc b/shell/platform/windows/win32_flutter_window.cc index 752720dbee0ca..820455f484698 100644 --- a/shell/platform/windows/win32_flutter_window.cc +++ b/shell/platform/windows/win32_flutter_window.cc @@ -21,7 +21,7 @@ void Win32FlutterWindow::SetView(FlutterWindowsView* window) { } WindowsRenderTarget Win32FlutterWindow::GetRenderTarget() { - return WindowsRenderTarget::CreateForHWND(GetWindowHandle()); + return WindowsRenderTarget(GetWindowHandle()); } float Win32FlutterWindow::GetDpiScale() { diff --git a/shell/platform/windows/win32_platform_handler.cc b/shell/platform/windows/win32_platform_handler.cc index 7b67351914dc8..aa32a9d6f15a2 100644 --- a/shell/platform/windows/win32_platform_handler.cc +++ b/shell/platform/windows/win32_platform_handler.cc @@ -225,7 +225,7 @@ void PlatformHandler::HandleMethodCall( return; } ScopedClipboard clipboard; - if (!clipboard.Open(view_->GetRenderTarget()->GetWindowHandle())) { + if (!clipboard.Open(std::get<::HWND>(*view_->GetRenderTarget()))) { rapidjson::Document error_code; error_code.SetInt(::GetLastError()); result->Error(kClipboardError, "Unable to open clipboard", &error_code); @@ -263,7 +263,7 @@ void PlatformHandler::HandleMethodCall( ScopedClipboard clipboard; - if (!clipboard.Open(view_->GetRenderTarget()->GetWindowHandle())) { + if (!clipboard.Open(std::get<::HWND>(*view_->GetRenderTarget()))) { rapidjson::Document error_code; error_code.SetInt(::GetLastError()); result->Error(kClipboardError, "Unable to open clipboard", &error_code); diff --git a/shell/platform/windows/window_binding_handler.h b/shell/platform/windows/window_binding_handler.h index 2993aa6f80232..d87f7d7e3f69a 100644 --- a/shell/platform/windows/window_binding_handler.h +++ b/shell/platform/windows/window_binding_handler.h @@ -16,56 +16,30 @@ namespace flutter { class FlutterWindowsView; -// Represents the type of a WindowsRenderTarget -enum WindowsRenderTargetType { HWND /*, Visual*/ }; +using WindowsRenderTarget = std::variant< + /*winrt::Windows::UI::Composition::SpriteVisual, */ ::HWND>; -struct WindowsRenderTarget { - // Creates a new HWND backed render target from window - static WindowsRenderTarget CreateForHWND(::HWND window) { - WindowsRenderTarget wrt; - wrt.type_ = WindowsRenderTargetType::HWND; - wrt.render_target_ = window; - return wrt; - } - - // Returns the type of instance - WindowsRenderTargetType GetType() { return type_; } - - // Returns the physical window for HWND backed instances - ::HWND GetWindowHandle() { return std::get<::HWND>(render_target_); } - - private: - // prevent external construction - WindowsRenderTarget() : render_target_(static_cast<::HWND>(0)) {} - - // type of instance - WindowsRenderTargetType type_; - - // win32 WindowsRenderTarget instances will by HWND backed, in the future - // UWP instances will be backed by a SpriteVisual - std::variant - render_target_; -}; - -// Abstract class for binding Windows OS Windows to Flutter views. +// Abstract class for binding Windows platform windows to Flutter views. class FlutterWindowBindingHandler { public: virtual ~FlutterWindowBindingHandler() = default; - // Caller provides a view for implementor to use to communicate state changes. + // Sets the view used to communicate state changes from Window to view such + // as key presses, mouse position updates etc. virtual void SetView(FlutterWindowsView* view) = 0; - // Implementor returns a valid WindowsRenderTarget representing the backing + // Returns a valid WindowsRenderTarget representing the backing // window. + virtual WindowsRenderTarget GetRenderTarget() = 0; - // Implementor returns the scale factor for the backing window. + // Returns the scale factor for the backing window. virtual float GetDpiScale() = 0; - // Implementor returns the width of the backing window in physical pixels. + // Returns the width of the backing window in physical pixels. virtual float GetPhysicalWidth() = 0; - // Implementor returns the height of the backing window in physical pixels. + // Returns the height of the backing window in physical pixels. virtual float GetPhysicalHeight() = 0; }; diff --git a/shell/platform/windows/window_state.h b/shell/platform/windows/window_state.h index a3e36fa718230..d1eceb866f507 100644 --- a/shell/platform/windows/window_state.h +++ b/shell/platform/windows/window_state.h @@ -64,7 +64,7 @@ struct FlutterDesktopPluginRegistrar { // The plugin messenger handle given to API clients. std::unique_ptr messenger; - // The handle for the window associated with this registrar. + // The handle for the view associated with this registrar. FlutterDesktopView* view; // Callback to be called on registrar destruction. From 7c449ba109869b1d74696f0a24dd7ff331c987fb Mon Sep 17 00:00:00 2001 From: James Clarke Date: Wed, 24 Jun 2020 22:00:33 -0700 Subject: [PATCH 04/15] clang-format; gn format --- shell/platform/windows/BUILD.gn | 2 +- shell/platform/windows/window_binding_handler.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/windows/BUILD.gn b/shell/platform/windows/BUILD.gn index c6f07181b21ef..75d2955808aba 100644 --- a/shell/platform/windows/BUILD.gn +++ b/shell/platform/windows/BUILD.gn @@ -51,7 +51,6 @@ source_set("flutter_windows_source") { "string_conversion.h", "text_input_plugin.cc", "text_input_plugin.h", - "window_binding_handler.h", "win32_dpi_utils.cc", "win32_dpi_utils.h", "win32_flutter_window.cc", @@ -62,6 +61,7 @@ source_set("flutter_windows_source") { "win32_task_runner.h", "win32_window.cc", "win32_window.h", + "window_binding_handler.h", "window_state.h", ] diff --git a/shell/platform/windows/window_binding_handler.h b/shell/platform/windows/window_binding_handler.h index d87f7d7e3f69a..af267e052fe47 100644 --- a/shell/platform/windows/window_binding_handler.h +++ b/shell/platform/windows/window_binding_handler.h @@ -30,7 +30,7 @@ class FlutterWindowBindingHandler { // Returns a valid WindowsRenderTarget representing the backing // window. - + virtual WindowsRenderTarget GetRenderTarget() = 0; // Returns the scale factor for the backing window. From 712861e0935b5926b6a3fead9cf5622845b31854 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sat, 27 Jun 2020 09:32:33 -0700 Subject: [PATCH 05/15] Fix licensing --- ci/licenses_golden/licenses_flutter | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index eb2713c557b90..4a2f60a5c790a 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1289,29 +1289,32 @@ FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/flu FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/plugin_registrar_windows.h FILE: ../../../flutter/shell/platform/windows/client_wrapper/plugin_registrar_windows_unittests.cc -FILE: ../../../flutter/shell/platform/windows/dpi_utils.cc -FILE: ../../../flutter/shell/platform/windows/dpi_utils.h -FILE: ../../../flutter/shell/platform/windows/dpi_utils_unittests.cc FILE: ../../../flutter/shell/platform/windows/flutter_windows.cc +FILE: ../../../flutter/shell/platform/windows/flutter_windows_view.cc +FILE: ../../../flutter/shell/platform/windows/flutter_windows_view.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 -FILE: ../../../flutter/shell/platform/windows/platform_handler.cc -FILE: ../../../flutter/shell/platform/windows/platform_handler.h FILE: ../../../flutter/shell/platform/windows/public/flutter_windows.h FILE: ../../../flutter/shell/platform/windows/string_conversion.cc FILE: ../../../flutter/shell/platform/windows/string_conversion.h FILE: ../../../flutter/shell/platform/windows/string_conversion_unittests.cc 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 +FILE: ../../../flutter/shell/platform/windows/win32_dpi_utils.h +FILE: ../../../flutter/shell/platform/windows/win32_dpi_utils_unittests.cc FILE: ../../../flutter/shell/platform/windows/win32_flutter_window.cc FILE: ../../../flutter/shell/platform/windows/win32_flutter_window.h FILE: ../../../flutter/shell/platform/windows/win32_flutter_window_unittests.cc +FILE: ../../../flutter/shell/platform/windows/win32_platform_handler.cc +FILE: ../../../flutter/shell/platform/windows/win32_platform_handler.h FILE: ../../../flutter/shell/platform/windows/win32_task_runner.cc FILE: ../../../flutter/shell/platform/windows/win32_task_runner.h FILE: ../../../flutter/shell/platform/windows/win32_window.cc FILE: ../../../flutter/shell/platform/windows/win32_window.h FILE: ../../../flutter/shell/platform/windows/win32_window_unittests.cc +FILE: ../../../flutter/shell/platform/windows/window_bindiing_handler.h FILE: ../../../flutter/shell/platform/windows/window_state.h FILE: ../../../flutter/shell/profiling/sampling_profiler.cc FILE: ../../../flutter/shell/profiling/sampling_profiler.h From 3b48ca672a851013bfe1d74b9d8f6ae43d7dabf1 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sat, 27 Jun 2020 09:49:37 -0700 Subject: [PATCH 06/15] CR feedback --- ci/licenses_golden/licenses_flutter | 2 +- shell/platform/windows/flutter_windows_view.cc | 4 ---- shell/platform/windows/win32_flutter_window.cc | 2 ++ shell/platform/windows/win32_flutter_window.h | 3 --- shell/platform/windows/win32_window.h | 16 ---------------- 5 files changed, 3 insertions(+), 24 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 4a2f60a5c790a..8e5eeca79b535 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1314,7 +1314,7 @@ FILE: ../../../flutter/shell/platform/windows/win32_task_runner.h FILE: ../../../flutter/shell/platform/windows/win32_window.cc FILE: ../../../flutter/shell/platform/windows/win32_window.h FILE: ../../../flutter/shell/platform/windows/win32_window_unittests.cc -FILE: ../../../flutter/shell/platform/windows/window_bindiing_handler.h +FILE: ../../../flutter/shell/platform/windows/window_binding_handler.h FILE: ../../../flutter/shell/platform/windows/window_state.h FILE: ../../../flutter/shell/profiling/sampling_profiler.cc FILE: ../../../flutter/shell/profiling/sampling_profiler.h diff --git a/shell/platform/windows/flutter_windows_view.cc b/shell/platform/windows/flutter_windows_view.cc index 7f93606d2c2ec..778470cb455da 100644 --- a/shell/platform/windows/flutter_windows_view.cc +++ b/shell/platform/windows/flutter_windows_view.cc @@ -272,10 +272,6 @@ void FlutterWindowsView::SendScroll(double x, FlutterPointerEvent event = {}; SetEventPhaseFromCursorButtonState(&event); event.signal_kind = FlutterPointerSignalKind::kFlutterPointerSignalKindScroll; - // TODO: See if this can be queried from the OS; this value is chosen - // arbitrarily to get something that feels reasonable. - - // scroll_offset_multiplier should be 20 for win32 and 1 for UWP event.x = x; event.y = y; event.scroll_delta_x = delta_x * scroll_offset_multiplier; diff --git a/shell/platform/windows/win32_flutter_window.cc b/shell/platform/windows/win32_flutter_window.cc index 820455f484698..a24f8786c7059 100644 --- a/shell/platform/windows/win32_flutter_window.cc +++ b/shell/platform/windows/win32_flutter_window.cc @@ -8,6 +8,8 @@ namespace flutter { // constant for machines running at 100% scaling. constexpr int base_dpi = 96; +// TODO: See if this can be queried from the OS; this value is chosen +// arbitrarily to get something that feels reasonable. constexpr int kScrollOffsetMultiplier = 20; Win32FlutterWindow::Win32FlutterWindow(int width, int height) : view_(nullptr) { diff --git a/shell/platform/windows/win32_flutter_window.h b/shell/platform/windows/win32_flutter_window.h index e46444564da9d..259df039b68e8 100644 --- a/shell/platform/windows/win32_flutter_window.h +++ b/shell/platform/windows/win32_flutter_window.h @@ -31,9 +31,6 @@ class Win32FlutterWindow : public Win32Window, virtual ~Win32FlutterWindow(); - // static FlutterDesktopViewControllerRef CreateWin32FlutterWindow(int width, - // int height); - // |Win32Window| void OnDpiScale(unsigned int dpi) override; diff --git a/shell/platform/windows/win32_window.h b/shell/platform/windows/win32_window.h index 81c4a3905cb1d..f2e144866c16a 100644 --- a/shell/platform/windows/win32_window.h +++ b/shell/platform/windows/win32_window.h @@ -13,22 +13,6 @@ namespace flutter { -// Struct holding the mouse state. The engine doesn't keep track of which mouse -// buttons have been pressed, so it's the embedding's responsibility. -struct MouseStateWin32 { - // True if the last event sent to Flutter had at least one mouse button - // pressed. - bool flutter_state_is_down = false; - - // True if kAdd has been sent to Flutter. Used to determine whether - // to send a kAdd event before sending an incoming mouse event, since Flutter - // expects pointers to be added before events are sent for them. - bool flutter_state_is_added = false; - - // The currently pressed buttons, as represented in FlutterPointerEvent. - uint64_t buttons = 0; -}; - // A class abstraction for a high DPI aware Win32 Window. Intended to be // inherited from by classes that wish to specialize with custom // rendering and input handling. From 167f8085cdbf07d86994a5f3f160594e19835540 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sat, 27 Jun 2020 10:15:02 -0700 Subject: [PATCH 07/15] CR feedback --- .../platform/windows/flutter_windows_view.cc | 20 ++++----- shell/platform/windows/flutter_windows_view.h | 41 +++++++++---------- 2 files changed, 28 insertions(+), 33 deletions(-) diff --git a/shell/platform/windows/flutter_windows_view.cc b/shell/platform/windows/flutter_windows_view.cc index 778470cb455da..74898f06e286b 100644 --- a/shell/platform/windows/flutter_windows_view.cc +++ b/shell/platform/windows/flutter_windows_view.cc @@ -126,7 +126,7 @@ void FlutterWindowsView::OnPointerDown( FlutterPointerMouseButtons flutter_button) { if (process_events_) { if (flutter_button != 0) { - uint64_t mouse_buttons = GetMouseState().buttons | flutter_button; + uint64_t mouse_buttons = mouse_state_.buttons | flutter_button; SetMouseButtons(mouse_buttons); SendPointerDown(x, y); } @@ -139,7 +139,7 @@ void FlutterWindowsView::OnPointerUp( FlutterPointerMouseButtons flutter_button) { if (process_events_) { if (flutter_button != 0) { - uint64_t mouse_buttons = GetMouseState().buttons & ~flutter_button; + uint64_t mouse_buttons = mouse_state_.buttons & ~flutter_button; SetMouseButtons(mouse_buttons); SendPointerUp(x, y); } @@ -204,14 +204,13 @@ void FlutterWindowsView::SendWindowMetrics(size_t width, // primary mouse button state. void FlutterWindowsView::SetEventPhaseFromCursorButtonState( FlutterPointerEvent* event_data) const { - MouseState state = GetMouseState(); // For details about this logic, see FlutterPointerPhase in the embedder.h // file. - event_data->phase = state.buttons == 0 ? state.flutter_state_is_down - ? FlutterPointerPhase::kUp + event_data->phase = + mouse_state_.buttons == 0 + ? mouse_state_.flutter_state_is_down ? FlutterPointerPhase::kUp : FlutterPointerPhase::kHover - : state.flutter_state_is_down - ? FlutterPointerPhase::kMove + : mouse_state_.flutter_state_is_down ? FlutterPointerPhase::kMove : FlutterPointerPhase::kDown; } @@ -281,10 +280,9 @@ void FlutterWindowsView::SendScroll(double x, void FlutterWindowsView::SendPointerEventWithData( const FlutterPointerEvent& event_data) { - MouseState mouse_state = GetMouseState(); // If sending anything other than an add, and the pointer isn't already added, // synthesize an add to satisfy Flutter's expectations about events. - if (!mouse_state.flutter_state_is_added && + if (!mouse_state_.flutter_state_is_added && event_data.phase != FlutterPointerPhase::kAdd) { FlutterPointerEvent event = {}; event.phase = FlutterPointerPhase::kAdd; @@ -295,14 +293,14 @@ void FlutterWindowsView::SendPointerEventWithData( } // Don't double-add (e.g., if events are delivered out of order, so an add has // already been synthesized). - if (mouse_state.flutter_state_is_added && + if (mouse_state_.flutter_state_is_added && event_data.phase == FlutterPointerPhase::kAdd) { return; } FlutterPointerEvent event = event_data; event.device_kind = kFlutterPointerDeviceKindMouse; - event.buttons = mouse_state.buttons; + event.buttons = mouse_state_.buttons; // Set metadata that's always the same regardless of the event. event.struct_size = sizeof(event); diff --git a/shell/platform/windows/flutter_windows_view.h b/shell/platform/windows/flutter_windows_view.h index 028c3b5bbdae3..76074981d5e33 100644 --- a/shell/platform/windows/flutter_windows_view.h +++ b/shell/platform/windows/flutter_windows_view.h @@ -40,7 +40,7 @@ struct MouseState { uint64_t buttons = 0; }; -// An OS windowing neutral abstration for flutter +// An OS-windowing neutral abstration for flutter // view that works with win32 hwnds and Windows::UI::Composition visuals. class FlutterWindowsView { public: @@ -51,10 +51,10 @@ class FlutterWindowsView { // Factory for creating FlutterWindowsView requiring an implementator of // FlutterWindowBindingHandler. static FlutterDesktopViewControllerRef CreateFlutterWindowsView( - std::unique_ptr windowbinding); + std::unique_ptr window_binding); - // Configures the window instance with an instance of a running Flutter engine - // returning a configured FlutterDesktopWindowControllerRef. + // Configures the window instance with an instance of a running Flutter + // engine. void SetState(FLUTTER_API_SYMBOL(FlutterEngine) state); // Returns the currently configured Plugin Registrar. @@ -64,10 +64,11 @@ class FlutterWindowsView { // messages. void HandlePlatformMessage(const FlutterPlatformMessage*); - // Create rendering surface for Flutter engine to draw into. + // Creates rendering surface for Flutter engine to draw into. + // Should be called before calling FlutterEngineRun using this view. void CreateRenderSurface(); - // Destroy current rendering surface if one has been allocated. + // Destroys current rendering surface if one has been allocated. void DestroyRenderSurface(); // Return the currently configured WindowsRenderTarget. @@ -79,35 +80,35 @@ class FlutterWindowsView { bool MakeResourceCurrent(); bool SwapBuffers(); - // Notify view that backing window size has changed. + // Notifies view that backing window size has changed. // Typically called by currently configured FlutterWindowBindingHandler void OnWindowSizeChanged(size_t width, size_t height) const; - // Notify view that backing window mouse has moved. + // Notifies view that backing window mouse has moved. // Typically called by currently configured FlutterWindowBindingHandler void OnPointerMove(double x, double y); - // Notify view that backing window mouse pointer button has been pressed. + // Notifies view that backing window mouse pointer button has been pressed. // Typically called by currently configured FlutterWindowBindingHandler void OnPointerDown(double x, double y, FlutterPointerMouseButtons button); - // Notify view that backing window mouse pointer button has been released. + // Notifies view that backing window mouse pointer button has been released. // Typically called by currently configured FlutterWindowBindingHandler void OnPointerUp(double x, double y, FlutterPointerMouseButtons button); - // Notify view that backing window mouse pointer has left the window. + // Notifies view that backing window mouse pointer has left the window. // Typically called by currently configured FlutterWindowBindingHandler void OnPointerLeave(); - // Notify view that backing window has received text. + // Notifies view that backing window has received text. // Typically called by currently configured FlutterWindowBindingHandler void OnText(const std::u16string&); - // Notify view that backing window size has received key press. + // Notifies view that backing window size has received key press. // Typically called by currently configured FlutterWindowBindingHandler void OnKey(int key, int scancode, int action, char32_t character); - // Notify view that backing window size has recevied scroll. + // Notifies view that backing window size has recevied scroll. // Typically called by currently configured FlutterWindowBindingHandler void OnScroll(double x, double y, @@ -115,7 +116,7 @@ class FlutterWindowsView { double delta_y, int scroll_offset_multiplier); - // Notify view that backing window size has had system font change. + // Notifies view that backing window size has had system font change. // Typically called by currently configured FlutterWindowBindingHandler void OnFontChange(); @@ -153,20 +154,16 @@ class FlutterWindowsView { double delta_y, int scroll_offset_multiplier); - // Set's |event_data|'s phase to either kMove or kHover depending on the - // current - // primary mouse button state. + // Sets |event_data|'s phase to either kMove or kHover depending on the + // current primary mouse button state. void SetEventPhaseFromCursorButtonState( FlutterPointerEvent* event_data) const; - // Sends a pointer event to the Flutter engine based on givern data. Since + // Sends a pointer event to the Flutter engine based on given data. Since // all input messages are passed in physical pixel values, no translation is // needed before passing on to engine. void SendPointerEventWithData(const FlutterPointerEvent& event_data); - // Gets the current mouse state. - MouseState GetMouseState() const { return mouse_state_; } - // Resets the mouse state to its default values. void ResetMouseState() { mouse_state_ = MouseState(); } From 7f5491ddc77c0e241487ef3073ed798155ea903b Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sat, 27 Jun 2020 11:10:04 -0700 Subject: [PATCH 08/15] CR feedback --- .../platform/windows/angle_surface_manager.cc | 38 ++++++++++--------- .../platform/windows/angle_surface_manager.h | 22 ++++++----- .../platform/windows/flutter_windows_view.cc | 17 ++++----- shell/platform/windows/flutter_windows_view.h | 27 ++++--------- 4 files changed, 49 insertions(+), 55 deletions(-) diff --git a/shell/platform/windows/angle_surface_manager.cc b/shell/platform/windows/angle_surface_manager.cc index 1ddc7278e0b51..66aad4d4aa24c 100644 --- a/shell/platform/windows/angle_surface_manager.cc +++ b/shell/platform/windows/angle_surface_manager.cc @@ -169,10 +169,9 @@ void AngleSurfaceManager::CleanUp() { } } -EGLSurface AngleSurfaceManager::CreateSurface( - WindowsRenderTarget* render_target) { +bool AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target) { if (!render_target || !initialize_succeeded_) { - return EGL_NO_SURFACE; + return false; } EGLSurface surface = EGL_NO_SURFACE; @@ -187,30 +186,35 @@ EGLSurface AngleSurfaceManager::CreateSurface( std::cerr << "Surface creation failed." << std::endl; } - return surface; + render_surface_ = surface; + return true; } -void AngleSurfaceManager::GetSurfaceDimensions(const EGLSurface surface, - EGLint* width, - EGLint* height) { - if (surface == EGL_NO_SURFACE || !initialize_succeeded_) { +void AngleSurfaceManager::GetSurfaceDimensions(EGLint* width, EGLint* height) { + if (render_surface_ == EGL_NO_SURFACE || !initialize_succeeded_) { width = 0; height = 0; return; } - eglQuerySurface(egl_display_, surface, EGL_WIDTH, width); - eglQuerySurface(egl_display_, surface, EGL_HEIGHT, height); + eglQuerySurface(egl_display_, render_surface_, EGL_WIDTH, width); + eglQuerySurface(egl_display_, render_surface_, EGL_HEIGHT, height); } -void AngleSurfaceManager::DestroySurface(const EGLSurface surface) { - if (egl_display_ != EGL_NO_DISPLAY && surface != EGL_NO_SURFACE) { - eglDestroySurface(egl_display_, surface); +void AngleSurfaceManager::DestroySurface() { + if (egl_display_ != EGL_NO_DISPLAY && render_surface_ != EGL_NO_SURFACE) { + eglDestroySurface(egl_display_, render_surface_); } + render_surface_ = EGL_NO_SURFACE; +} + +bool AngleSurfaceManager::MakeCurrent() { + return (eglMakeCurrent(egl_display_, render_surface_, render_surface_, + egl_context_) == EGL_TRUE); } -bool AngleSurfaceManager::MakeCurrent(const EGLSurface surface) { - return (eglMakeCurrent(egl_display_, surface, surface, egl_context_) == +bool AngleSurfaceManager::ClearContext() { + return (eglMakeCurrent(egl_display_, nullptr, nullptr, egl_context_) == EGL_TRUE); } @@ -219,8 +223,8 @@ bool AngleSurfaceManager::MakeResourceCurrent() { egl_resource_context_) == EGL_TRUE); } -EGLBoolean AngleSurfaceManager::SwapBuffers(const EGLSurface surface) { - return (eglSwapBuffers(egl_display_, surface)); +EGLBoolean AngleSurfaceManager::SwapBuffers() { + return (eglSwapBuffers(egl_display_, render_surface_)); } } // namespace flutter diff --git a/shell/platform/windows/angle_surface_manager.h b/shell/platform/windows/angle_surface_manager.h index 1230a53acb85c..a6a5fc213c3d4 100644 --- a/shell/platform/windows/angle_surface_manager.h +++ b/shell/platform/windows/angle_surface_manager.h @@ -19,7 +19,7 @@ namespace flutter { -// An manager for inializing ANGLE correctly and using it to create and +// A manager for inializing ANGLE correctly and using it to create and // destroy surfaces class AngleSurfaceManager { public: @@ -30,23 +30,24 @@ class AngleSurfaceManager { AngleSurfaceManager(const AngleSurfaceManager&) = delete; AngleSurfaceManager& operator=(const AngleSurfaceManager&) = delete; - // Creates and returns an EGLSurface wrapper and backing DirectX 11 SwapChain + // Creates an EGLSurface wrapper and backing DirectX 11 SwapChain // asociated with window, in the appropriate format for display. // Target represents the visual entity to bind to. - EGLSurface CreateSurface(WindowsRenderTarget* render_target); + bool CreateSurface(WindowsRenderTarget* render_target); // queries EGL for the dimensions of surface in physical // pixels returning width and height as out params. - void GetSurfaceDimensions(const EGLSurface surface, - EGLint* width, - EGLint* height); + void GetSurfaceDimensions(EGLint* width, EGLint* height); // Releases the pass-in EGLSurface wrapping and backing resources if not null. - void DestroySurface(const EGLSurface surface); + void DestroySurface(); // Binds egl_context_ to the current rendering thread and to the draw and read // surfaces returning a boolean result reflecting success. - bool MakeCurrent(const EGLSurface surface); + bool MakeCurrent(); + + // Clears current egl_context_ + bool ClearContext(); // Binds egl_resource_context_ to the current rendering thread and to the draw // and read surfaces returning a boolean result reflecting success. @@ -54,7 +55,7 @@ class AngleSurfaceManager { // Swaps the front and back buffers of the DX11 swapchain backing surface if // not null. - EGLBoolean SwapBuffers(const EGLSurface surface); + EGLBoolean SwapBuffers(); private: bool Initialize(); @@ -77,6 +78,9 @@ class AngleSurfaceManager { // State representing success or failure of display initialization used when // creating surfaces. bool initialize_succeeded_; + + // Current render_surface that engine will draw into. + EGLSurface render_surface_ = EGL_NO_SURFACE; }; } // namespace flutter diff --git a/shell/platform/windows/flutter_windows_view.cc b/shell/platform/windows/flutter_windows_view.cc index 74898f06e286b..a2e7d35268233 100644 --- a/shell/platform/windows/flutter_windows_view.cc +++ b/shell/platform/windows/flutter_windows_view.cc @@ -5,7 +5,7 @@ namespace flutter { FlutterWindowsView::FlutterWindowsView() { - surface_manager = std::make_unique(); + surface_manager_ = std::make_unique(); } FlutterWindowsView::~FlutterWindowsView() { @@ -320,30 +320,29 @@ void FlutterWindowsView::SendPointerEventWithData( } bool FlutterWindowsView::MakeCurrent() { - return surface_manager->MakeCurrent(render_surface); + return surface_manager_->MakeCurrent(); } bool FlutterWindowsView::MakeResourceCurrent() { - return surface_manager->MakeResourceCurrent(); + return surface_manager_->MakeResourceCurrent(); } bool FlutterWindowsView::ClearContext() { - return surface_manager->MakeCurrent(nullptr); + return surface_manager_->ClearContext(); } bool FlutterWindowsView::SwapBuffers() { - return surface_manager->SwapBuffers(render_surface); + return surface_manager_->SwapBuffers(); } void FlutterWindowsView::CreateRenderSurface() { - render_surface = surface_manager->CreateSurface(render_target_.get()); + surface_manager_->CreateSurface(render_target_.get()); } void FlutterWindowsView::DestroyRenderSurface() { - if (surface_manager) { - surface_manager->DestroySurface(render_surface); + if (surface_manager_) { + surface_manager_->DestroySurface(); } - render_surface = EGL_NO_SURFACE; } WindowsRenderTarget* FlutterWindowsView::GetRenderTarget() { diff --git a/shell/platform/windows/flutter_windows_view.h b/shell/platform/windows/flutter_windows_view.h index 76074981d5e33..8cb4ccaf3b454 100644 --- a/shell/platform/windows/flutter_windows_view.h +++ b/shell/platform/windows/flutter_windows_view.h @@ -182,25 +182,18 @@ class FlutterWindowsView { // Updates the currently pressed buttons. void SetMouseButtons(uint64_t buttons) { mouse_state_.buttons = buttons; } - std::unique_ptr surface_manager = nullptr; - EGLSurface render_surface = EGL_NO_SURFACE; + // Currently configured WindowsRenderTarget for this view used by + // surface_manager for creation of render surfaces and bound to the physical + // os window. + std::unique_ptr render_target_; - // state of the mouse button. - bool pointer_is_down_ = false; + // An object used for intializing Angle and creating / destroying render + // surfaces. Surface creation functionality requires a valid render_target. + std::unique_ptr surface_manager_ = nullptr; // The handle to the Flutter engine instance. FLUTTER_API_SYMBOL(FlutterEngine) engine_ = nullptr; - // Whether or not to track mouse movements to send kHover events. - bool hover_tracking_is_enabled_ = false; - - // Whether or not the pointer has been added (or if tracking is enabled, has - // been added since it was last removed). - bool pointer_currently_added_ = false; - - // Set to true to be notified when the mouse leaves the window. - bool tracking_mouse_leave_ = false; - // Keeps track of mouse state in relation to the window. MouseState mouse_state_; @@ -226,12 +219,6 @@ class FlutterWindowsView { // should we forword input messages or not bool process_events_ = false; - // flag indicating if the message loop should be running. - bool messageloop_running_ = false; - - // Currently configured WindowsRenderTarget for view. - std::unique_ptr render_target_; - // Currently configured FlutterWindowBindingHandler for view. std::unique_ptr binding_handler_{ nullptr}; From b186c03e66748f031942f839375f5dc370b32580 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sat, 27 Jun 2020 11:22:24 -0700 Subject: [PATCH 09/15] Git rid of unnecessar :: prefixes --- .../platform/windows/angle_surface_manager.cc | 2 +- shell/platform/windows/flutter_windows.cc | 2 +- shell/platform/windows/flutter_windows_view.h | 3 +-- shell/platform/windows/win32_dpi_utils.h | 2 +- shell/platform/windows/win32_flutter_window.h | 23 ++++--------------- .../windows/win32_flutter_window_unittests.cc | 2 +- .../windows/win32_platform_handler.cc | 8 +++---- shell/platform/windows/win32_window.h | 12 +++++----- .../platform/windows/window_binding_handler.h | 2 +- 9 files changed, 21 insertions(+), 35 deletions(-) diff --git a/shell/platform/windows/angle_surface_manager.cc b/shell/platform/windows/angle_surface_manager.cc index 66aad4d4aa24c..cc046281e8114 100644 --- a/shell/platform/windows/angle_surface_manager.cc +++ b/shell/platform/windows/angle_surface_manager.cc @@ -180,7 +180,7 @@ bool AngleSurfaceManager::CreateSurface(WindowsRenderTarget* render_target) { surface = eglCreateWindowSurface( egl_display_, egl_config_, - static_cast(std::get<::HWND>(*render_target)), + static_cast(std::get(*render_target)), surfaceAttributes); if (surface == EGL_NO_SURFACE) { std::cerr << "Surface creation failed." << std::endl; diff --git a/shell/platform/windows/flutter_windows.cc b/shell/platform/windows/flutter_windows.cc index c0000d4b7dec7..e3fd71bf0cf60 100644 --- a/shell/platform/windows/flutter_windows.cc +++ b/shell/platform/windows/flutter_windows.cc @@ -268,7 +268,7 @@ FlutterDesktopViewRef FlutterDesktopGetView( } HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view_ref) { - return std::get<::HWND>(*view_ref->view->GetRenderTarget()); + return std::get(*view_ref->view->GetRenderTarget()); } UINT FlutterDesktopGetDpiForHWND(HWND hwnd) { diff --git a/shell/platform/windows/flutter_windows_view.h b/shell/platform/windows/flutter_windows_view.h index 8cb4ccaf3b454..6d06d9b69b0cb 100644 --- a/shell/platform/windows/flutter_windows_view.h +++ b/shell/platform/windows/flutter_windows_view.h @@ -220,8 +220,7 @@ class FlutterWindowsView { bool process_events_ = false; // Currently configured FlutterWindowBindingHandler for view. - std::unique_ptr binding_handler_{ - nullptr}; + std::unique_ptr binding_handler_; }; } // namespace flutter diff --git a/shell/platform/windows/win32_dpi_utils.h b/shell/platform/windows/win32_dpi_utils.h index 1481aecb54ab9..1c14994b61235 100644 --- a/shell/platform/windows/win32_dpi_utils.h +++ b/shell/platform/windows/win32_dpi_utils.h @@ -13,7 +13,7 @@ namespace flutter { /// backward compatible down to Windows Vista. If |hwnd| is nullptr, returns the /// DPI for the primary monitor. If Per-Monitor DPI awareness is not available, /// returns the system's DPI. -UINT GetDpiForHWND(::HWND hwnd); +UINT GetDpiForHWND(HWND hwnd); /// Returns the DPI of a given monitor. Defaults to 96 if the API is not /// available. diff --git a/shell/platform/windows/win32_flutter_window.h b/shell/platform/windows/win32_flutter_window.h index 259df039b68e8..d9a637131a2c7 100644 --- a/shell/platform/windows/win32_flutter_window.h +++ b/shell/platform/windows/win32_flutter_window.h @@ -61,34 +61,21 @@ class Win32FlutterWindow : public Win32Window, // |Win32Window| void OnFontChange() override; - // |SetView| + // |FlutterWindowBindingHandler| void SetView(FlutterWindowsView* view) override; - // |GetRenderTarget| + // |FlutterWindowBindingHandler| WindowsRenderTarget GetRenderTarget() override; - // |GetDpiScale| + // |FlutterWindowBindingHandler| float GetDpiScale() override; - // |GetPhysicalWidth| + // |FlutterWindowBindingHandler| float GetPhysicalWidth() override; - // |GetPhysicalHeight| + // |FlutterWindowBindingHandler| float GetPhysicalHeight() override; - // state of the mouse button - bool pointer_is_down_ = false; - - // The handle to the Flutter engine instance. - FLUTTER_API_SYMBOL(FlutterEngine) engine_ = nullptr; - - // Whether or not to track mouse movements to send kHover events. - bool hover_tracking_is_enabled_ = false; - - // Whether or not the pointer has been added (or if tracking is enabled, has - // been added since it was last removed). - bool pointer_currently_added_ = false; - // A pointer to a FlutterWindowsView that can be used to update engine // windowing and input state. FlutterWindowsView* view_; diff --git a/shell/platform/windows/win32_flutter_window_unittests.cc b/shell/platform/windows/win32_flutter_window_unittests.cc index ea441fa6299a7..dece5a280f807 100644 --- a/shell/platform/windows/win32_flutter_window_unittests.cc +++ b/shell/platform/windows/win32_flutter_window_unittests.cc @@ -11,7 +11,7 @@ TEST(Win32FlutterWindowTest, CreateDestroy) { TEST(Win32FlutterWindowTest, CanFontChange) { Win32FlutterWindowTest window(800, 600); - ::HWND hwnd = window.GetWindowHandle(); + HWND hwnd = window.GetWindowHandle(); LRESULT result = SendMessage(hwnd, WM_FONTCHANGE, NULL, NULL); ASSERT_EQ(result, 0); ASSERT_TRUE(window.OnFontChangeWasCalled()); diff --git a/shell/platform/windows/win32_platform_handler.cc b/shell/platform/windows/win32_platform_handler.cc index aa32a9d6f15a2..a9efc31f9a2d7 100644 --- a/shell/platform/windows/win32_platform_handler.cc +++ b/shell/platform/windows/win32_platform_handler.cc @@ -116,7 +116,7 @@ class ScopedClipboard { // Attempts to open the clipboard for the given window, returning true if // successful. - bool Open(::HWND window); + bool Open(HWND window); // Returns true if there is string data available to get. bool HasString(); @@ -148,7 +148,7 @@ ScopedClipboard::~ScopedClipboard() { } } -bool ScopedClipboard::Open(::HWND window) { +bool ScopedClipboard::Open(HWND window) { opened_ = ::OpenClipboard(window); return opened_; } @@ -225,7 +225,7 @@ void PlatformHandler::HandleMethodCall( return; } ScopedClipboard clipboard; - if (!clipboard.Open(std::get<::HWND>(*view_->GetRenderTarget()))) { + if (!clipboard.Open(std::get(*view_->GetRenderTarget()))) { rapidjson::Document error_code; error_code.SetInt(::GetLastError()); result->Error(kClipboardError, "Unable to open clipboard", &error_code); @@ -263,7 +263,7 @@ void PlatformHandler::HandleMethodCall( ScopedClipboard clipboard; - if (!clipboard.Open(std::get<::HWND>(*view_->GetRenderTarget()))) { + if (!clipboard.Open(std::get(*view_->GetRenderTarget()))) { rapidjson::Document error_code; error_code.SetInt(::GetLastError()); result->Error(kClipboardError, "Unable to open clipboard", &error_code); diff --git a/shell/platform/windows/win32_window.h b/shell/platform/windows/win32_window.h index f2e144866c16a..811cacb86542b 100644 --- a/shell/platform/windows/win32_window.h +++ b/shell/platform/windows/win32_window.h @@ -43,7 +43,7 @@ class Win32Window { // non-client DPI scaling so that the non-client area automatically // responsponds to changes in DPI. All other messages are handled by // MessageHandler. - static LRESULT CALLBACK WndProc(::HWND const window, + static LRESULT CALLBACK WndProc(HWND const window, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept; @@ -52,7 +52,7 @@ class Win32Window { // size change and DPI. Delegates handling of these to member overloads that // inheriting classes can handle. LRESULT - MessageHandler(::HWND window, + MessageHandler(HWND window, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept; @@ -62,7 +62,7 @@ class Win32Window { // the window to the new suggested size. If |top_level| is not set, the // |lParam| will not contain a suggested size hence ignore it. LRESULT - HandleDpiChange(::HWND hWnd, WPARAM wParam, LPARAM lParam, bool top_level); + HandleDpiChange(HWND hWnd, WPARAM wParam, LPARAM lParam, bool top_level); // Called when the DPI changes either when a // user drags the window between monitors of differing DPI or when the user @@ -109,13 +109,13 @@ class Win32Window { void Destroy(); // Activates tracking for a "mouse leave" event. - void TrackMouseLeaveEvent(::HWND hwnd); + void TrackMouseLeaveEvent(HWND hwnd); // Stores new width and height and calls |OnResize| to notify inheritors void HandleResize(UINT width, UINT height); // Retrieves a class instance pointer for |window| - static Win32Window* GetThisFromHandle(::HWND const window) noexcept; + static Win32Window* GetThisFromHandle(HWND const window) noexcept; int current_dpi_ = 0; int current_width_ = 0; int current_height_ = 0; @@ -125,7 +125,7 @@ class Win32Window { const static long kWmDpiChangedBeforeParent = 0x02E2; // Member variable to hold window handle. - ::HWND window_handle_ = nullptr; + HWND window_handle_ = nullptr; // Member variable to hold the window title. std::wstring window_class_name_; diff --git a/shell/platform/windows/window_binding_handler.h b/shell/platform/windows/window_binding_handler.h index af267e052fe47..01d0bf7742f23 100644 --- a/shell/platform/windows/window_binding_handler.h +++ b/shell/platform/windows/window_binding_handler.h @@ -17,7 +17,7 @@ namespace flutter { class FlutterWindowsView; using WindowsRenderTarget = std::variant< - /*winrt::Windows::UI::Composition::SpriteVisual, */ ::HWND>; + /*winrt::Windows::UI::Composition::SpriteVisual, */ HWND>; // Abstract class for binding Windows platform windows to Flutter views. class FlutterWindowBindingHandler { From c39253109695f1e536daf6a0719781faef786240 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sat, 27 Jun 2020 12:04:35 -0700 Subject: [PATCH 10/15] Extract WindowBindingHandlerDelegate as an interface --- shell/platform/windows/BUILD.gn | 1 + shell/platform/windows/flutter_windows.cc | 2 +- .../platform/windows/flutter_windows_view.cc | 2 +- shell/platform/windows/flutter_windows_view.h | 60 +++++++++--------- .../platform/windows/win32_flutter_window.cc | 30 ++++----- shell/platform/windows/win32_flutter_window.h | 7 +-- .../platform/windows/window_binding_handler.h | 10 +-- .../windows/window_binding_handler_delegate.h | 61 +++++++++++++++++++ 8 files changed, 117 insertions(+), 56 deletions(-) create mode 100644 shell/platform/windows/window_binding_handler_delegate.h diff --git a/shell/platform/windows/BUILD.gn b/shell/platform/windows/BUILD.gn index 75d2955808aba..a5760a2522e6c 100644 --- a/shell/platform/windows/BUILD.gn +++ b/shell/platform/windows/BUILD.gn @@ -62,6 +62,7 @@ source_set("flutter_windows_source") { "win32_window.cc", "win32_window.h", "window_binding_handler.h", + "window_binding_handler_delegate.h", "window_state.h", ] diff --git a/shell/platform/windows/flutter_windows.cc b/shell/platform/windows/flutter_windows.cc index e3fd71bf0cf60..b3dec79eb20cd 100644 --- a/shell/platform/windows/flutter_windows.cc +++ b/shell/platform/windows/flutter_windows.cc @@ -204,7 +204,7 @@ FlutterDesktopViewControllerRef FlutterDesktopCreateViewController( int width, int height, const FlutterDesktopEngineProperties& engine_properties) { - std::unique_ptr window_wrapper = + std::unique_ptr window_wrapper = std::make_unique(width, height); FlutterDesktopViewControllerRef state = diff --git a/shell/platform/windows/flutter_windows_view.cc b/shell/platform/windows/flutter_windows_view.cc index a2e7d35268233..b3f52b6f7fde8 100644 --- a/shell/platform/windows/flutter_windows_view.cc +++ b/shell/platform/windows/flutter_windows_view.cc @@ -16,7 +16,7 @@ FlutterWindowsView::~FlutterWindowsView() { } FlutterDesktopViewControllerRef FlutterWindowsView::CreateFlutterWindowsView( - std::unique_ptr windowbinding) { + std::unique_ptr windowbinding) { auto state = std::make_unique(); state->view = std::make_unique(); diff --git a/shell/platform/windows/flutter_windows_view.h b/shell/platform/windows/flutter_windows_view.h index 6d06d9b69b0cb..b160196e90ebd 100644 --- a/shell/platform/windows/flutter_windows_view.h +++ b/shell/platform/windows/flutter_windows_view.h @@ -20,6 +20,7 @@ #include "flutter/shell/platform/windows/text_input_plugin.h" #include "flutter/shell/platform/windows/win32_platform_handler.h" #include "flutter/shell/platform/windows/window_binding_handler.h" +#include "flutter/shell/platform/windows/window_binding_handler_delegate.h" #include "flutter/shell/platform/windows/window_state.h" namespace flutter { @@ -42,16 +43,16 @@ struct MouseState { // An OS-windowing neutral abstration for flutter // view that works with win32 hwnds and Windows::UI::Composition visuals. -class FlutterWindowsView { +class FlutterWindowsView : public WindowBindingHandlerDelegate { public: FlutterWindowsView(); ~FlutterWindowsView(); // Factory for creating FlutterWindowsView requiring an implementator of - // FlutterWindowBindingHandler. + // WindowBindingHandler. static FlutterDesktopViewControllerRef CreateFlutterWindowsView( - std::unique_ptr window_binding); + std::unique_ptr window_binding); // Configures the window instance with an instance of a running Flutter // engine. @@ -80,45 +81,40 @@ class FlutterWindowsView { bool MakeResourceCurrent(); bool SwapBuffers(); - // Notifies view that backing window size has changed. - // Typically called by currently configured FlutterWindowBindingHandler - void OnWindowSizeChanged(size_t width, size_t height) const; + // |WindowBindingHandlerDelegate| + void OnWindowSizeChanged(size_t width, size_t height) const override; - // Notifies view that backing window mouse has moved. - // Typically called by currently configured FlutterWindowBindingHandler - void OnPointerMove(double x, double y); + // |WindowBindingHandlerDelegate| + void OnPointerMove(double x, double y) override; - // Notifies view that backing window mouse pointer button has been pressed. - // Typically called by currently configured FlutterWindowBindingHandler - void OnPointerDown(double x, double y, FlutterPointerMouseButtons button); + // |WindowBindingHandlerDelegate| + void OnPointerDown(double x, + double y, + FlutterPointerMouseButtons button) override; - // Notifies view that backing window mouse pointer button has been released. - // Typically called by currently configured FlutterWindowBindingHandler - void OnPointerUp(double x, double y, FlutterPointerMouseButtons button); + // |WindowBindingHandlerDelegate| + void OnPointerUp(double x, + double y, + FlutterPointerMouseButtons button) override; - // Notifies view that backing window mouse pointer has left the window. - // Typically called by currently configured FlutterWindowBindingHandler - void OnPointerLeave(); + // |WindowBindingHandlerDelegate| + void OnPointerLeave() override; - // Notifies view that backing window has received text. - // Typically called by currently configured FlutterWindowBindingHandler - void OnText(const std::u16string&); + // |WindowBindingHandlerDelegate| + void OnText(const std::u16string&) override; - // Notifies view that backing window size has received key press. - // Typically called by currently configured FlutterWindowBindingHandler - void OnKey(int key, int scancode, int action, char32_t character); + // |WindowBindingHandlerDelegate| + void OnKey(int key, int scancode, int action, char32_t character) override; - // Notifies view that backing window size has recevied scroll. - // Typically called by currently configured FlutterWindowBindingHandler + // |WindowBindingHandlerDelegate| void OnScroll(double x, double y, double delta_x, double delta_y, - int scroll_offset_multiplier); + int scroll_offset_multiplier) override; - // Notifies view that backing window size has had system font change. - // Typically called by currently configured FlutterWindowBindingHandler - void OnFontChange(); + // |WindowBindingHandlerDelegate| + void OnFontChange() override; private: // Sends a window metrics update to the Flutter engine using current window @@ -219,8 +215,8 @@ class FlutterWindowsView { // should we forword input messages or not bool process_events_ = false; - // Currently configured FlutterWindowBindingHandler for view. - std::unique_ptr binding_handler_; + // Currently configured WindowBindingHandler for view. + std::unique_ptr binding_handler_; }; } // namespace flutter diff --git a/shell/platform/windows/win32_flutter_window.cc b/shell/platform/windows/win32_flutter_window.cc index a24f8786c7059..24a5458288c43 100644 --- a/shell/platform/windows/win32_flutter_window.cc +++ b/shell/platform/windows/win32_flutter_window.cc @@ -12,14 +12,15 @@ constexpr int base_dpi = 96; // arbitrarily to get something that feels reasonable. constexpr int kScrollOffsetMultiplier = 20; -Win32FlutterWindow::Win32FlutterWindow(int width, int height) : view_(nullptr) { +Win32FlutterWindow::Win32FlutterWindow(int width, int height) + : binding_handler_delegate_(nullptr) { Win32Window::InitializeChild("FLUTTERVIEW", width, height); } Win32FlutterWindow::~Win32FlutterWindow() {} -void Win32FlutterWindow::SetView(FlutterWindowsView* window) { - view_ = window; +void Win32FlutterWindow::SetView(WindowBindingHandlerDelegate* window) { + binding_handler_delegate_ = window; } WindowsRenderTarget Win32FlutterWindow::GetRenderTarget() { @@ -64,19 +65,19 @@ void Win32FlutterWindow::OnDpiScale(unsigned int dpi){}; // When DesktopWindow notifies that a WM_Size message has come in // lets FlutterEngine know about the new size. void Win32FlutterWindow::OnResize(unsigned int width, unsigned int height) { - if (view_ != nullptr) { - view_->OnWindowSizeChanged(width, height); + if (binding_handler_delegate_ != nullptr) { + binding_handler_delegate_->OnWindowSizeChanged(width, height); } } void Win32FlutterWindow::OnPointerMove(double x, double y) { - view_->OnPointerMove(x, y); + binding_handler_delegate_->OnPointerMove(x, y); } void Win32FlutterWindow::OnPointerDown(double x, double y, UINT button) { uint64_t flutter_button = ConvertWinButtonToFlutterButton(button); if (flutter_button != 0) { - view_->OnPointerDown( + binding_handler_delegate_->OnPointerDown( x, y, static_cast(flutter_button)); } } @@ -84,24 +85,24 @@ void Win32FlutterWindow::OnPointerDown(double x, double y, UINT button) { void Win32FlutterWindow::OnPointerUp(double x, double y, UINT button) { uint64_t flutter_button = ConvertWinButtonToFlutterButton(button); if (flutter_button != 0) { - view_->OnPointerUp(x, y, - static_cast(flutter_button)); + binding_handler_delegate_->OnPointerUp( + x, y, static_cast(flutter_button)); } } void Win32FlutterWindow::OnPointerLeave() { - view_->OnPointerLeave(); + binding_handler_delegate_->OnPointerLeave(); } void Win32FlutterWindow::OnText(const std::u16string& text) { - view_->OnText(text); + binding_handler_delegate_->OnText(text); } void Win32FlutterWindow::OnKey(int key, int scancode, int action, char32_t character) { - view_->OnKey(key, scancode, action, character); + binding_handler_delegate_->OnKey(key, scancode, action, character); } void Win32FlutterWindow::OnScroll(double delta_x, double delta_y) { @@ -109,11 +110,12 @@ void Win32FlutterWindow::OnScroll(double delta_x, double delta_y) { GetCursorPos(&point); ScreenToClient(GetWindowHandle(), &point); - view_->OnScroll(point.x, point.y, delta_x, delta_y, kScrollOffsetMultiplier); + binding_handler_delegate_->OnScroll(point.x, point.y, delta_x, delta_y, + kScrollOffsetMultiplier); } void Win32FlutterWindow::OnFontChange() { - view_->OnFontChange(); + binding_handler_delegate_->OnFontChange(); } } // namespace flutter diff --git a/shell/platform/windows/win32_flutter_window.h b/shell/platform/windows/win32_flutter_window.h index d9a637131a2c7..28b20a912dba2 100644 --- a/shell/platform/windows/win32_flutter_window.h +++ b/shell/platform/windows/win32_flutter_window.h @@ -23,8 +23,7 @@ namespace flutter { // future, there will likely be a CoreWindow-based FlutterWindow as well. At // the point may make sense to dependency inject the native window rather than // inherit. -class Win32FlutterWindow : public Win32Window, - public FlutterWindowBindingHandler { +class Win32FlutterWindow : public Win32Window, public WindowBindingHandler { public: // Create flutter Window for use as child window Win32FlutterWindow(int width, int height); @@ -62,7 +61,7 @@ class Win32FlutterWindow : public Win32Window, void OnFontChange() override; // |FlutterWindowBindingHandler| - void SetView(FlutterWindowsView* view) override; + void SetView(WindowBindingHandlerDelegate* view) override; // |FlutterWindowBindingHandler| WindowsRenderTarget GetRenderTarget() override; @@ -78,7 +77,7 @@ class Win32FlutterWindow : public Win32Window, // A pointer to a FlutterWindowsView that can be used to update engine // windowing and input state. - FlutterWindowsView* view_; + WindowBindingHandlerDelegate* binding_handler_delegate_; }; } // namespace flutter diff --git a/shell/platform/windows/window_binding_handler.h b/shell/platform/windows/window_binding_handler.h index 01d0bf7742f23..34f541f91eff8 100644 --- a/shell/platform/windows/window_binding_handler.h +++ b/shell/platform/windows/window_binding_handler.h @@ -5,12 +5,14 @@ #ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOW_BINDING_HANDLER_H_ #define FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOW_BINDING_HANDLER_H_ +#include "flutter/shell/platform/windows/public/flutter_windows.h" + #include #include #include -#include "flutter/shell/platform/windows/public/flutter_windows.h" +#include "flutter/shell/platform/windows/window_binding_handler_delegate.h" namespace flutter { @@ -20,13 +22,13 @@ using WindowsRenderTarget = std::variant< /*winrt::Windows::UI::Composition::SpriteVisual, */ HWND>; // Abstract class for binding Windows platform windows to Flutter views. -class FlutterWindowBindingHandler { +class WindowBindingHandler { public: - virtual ~FlutterWindowBindingHandler() = default; + virtual ~WindowBindingHandler() = default; // Sets the view used to communicate state changes from Window to view such // as key presses, mouse position updates etc. - virtual void SetView(FlutterWindowsView* view) = 0; + virtual void SetView(WindowBindingHandlerDelegate* view) = 0; // Returns a valid WindowsRenderTarget representing the backing // window. diff --git a/shell/platform/windows/window_binding_handler_delegate.h b/shell/platform/windows/window_binding_handler_delegate.h new file mode 100644 index 0000000000000..b95f1fbd55fe5 --- /dev/null +++ b/shell/platform/windows/window_binding_handler_delegate.h @@ -0,0 +1,61 @@ +// 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_WINDOW_BINDING_HANDLER_DELEGATE_H_ +#define FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOW_BINDING_HANDLER_DELEGATE_H_ + +#include "flutter/shell/platform/embedder/embedder.h" + +namespace flutter { + +class WindowBindingHandlerDelegate { + public: + // Notifies view that backing window size has changed. + // Typically called by currently configured WindowBindingHandler + virtual void OnWindowSizeChanged(size_t width, size_t height) const = 0; + + // Notifies view that backing window mouse has moved. + // Typically called by currently configured WindowBindingHandler + virtual void OnPointerMove(double x, double y) = 0; + + // Notifies view that backing window mouse pointer button has been pressed. + // Typically called by currently configured WindowBindingHandler + virtual void OnPointerDown(double x, + double y, + FlutterPointerMouseButtons button) = 0; + + // Notifies view that backing window mouse pointer button has been released. + // Typically called by currently configured WindowBindingHandler + virtual void OnPointerUp(double x, + double y, + FlutterPointerMouseButtons button) = 0; + + // Notifies view that backing window mouse pointer has left the window. + // Typically called by currently configured WindowBindingHandler + virtual void OnPointerLeave() = 0; + + // Notifies view that backing window has received text. + // Typically called by currently configured WindowBindingHandler + virtual void OnText(const std::u16string&) = 0; + + // Notifies view that backing window size has received key press. + // Typically called by currently configured WindowBindingHandler + virtual void OnKey(int key, int scancode, int action, char32_t character) = 0; + + // Notifies view that backing window size has recevied scroll. + // Typically called by currently configured WindowBindingHandler + virtual void OnScroll(double x, + double y, + double delta_x, + double delta_y, + int scroll_offset_multiplier) = 0; + + // Notifies view that backing window size has had system font change. + // Typically called by currently configured WindowBindingHandler + virtual void OnFontChange() = 0; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOW_BINDING_HANDLER_DELEGATE_H_ From 5213a7c544cfded1a6635503f0f33bcdd5ae0fd9 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sat, 27 Jun 2020 12:06:08 -0700 Subject: [PATCH 11/15] Missing file --- ci/licenses_golden/licenses_flutter | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 8e5eeca79b535..7279ff4c720ff 100755 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1315,6 +1315,7 @@ FILE: ../../../flutter/shell/platform/windows/win32_window.cc FILE: ../../../flutter/shell/platform/windows/win32_window.h FILE: ../../../flutter/shell/platform/windows/win32_window_unittests.cc FILE: ../../../flutter/shell/platform/windows/window_binding_handler.h +FILE: ../../../flutter/shell/platform/windows/window_binding_handler_delegate.h FILE: ../../../flutter/shell/platform/windows/window_state.h FILE: ../../../flutter/shell/profiling/sampling_profiler.cc FILE: ../../../flutter/shell/profiling/sampling_profiler.h From 906908a3cb96e7b81244fa45878385237b1a1bb4 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sat, 27 Jun 2020 12:21:40 -0700 Subject: [PATCH 12/15] Extract physical window bounds as a struct --- shell/platform/windows/flutter_windows_view.cc | 5 +++-- shell/platform/windows/win32_flutter_window.cc | 8 ++------ shell/platform/windows/win32_flutter_window.h | 5 +---- shell/platform/windows/window_binding_handler.h | 13 ++++++++----- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/shell/platform/windows/flutter_windows_view.cc b/shell/platform/windows/flutter_windows_view.cc index b3f52b6f7fde8..b922aa4aef06d 100644 --- a/shell/platform/windows/flutter_windows_view.cc +++ b/shell/platform/windows/flutter_windows_view.cc @@ -68,8 +68,9 @@ void FlutterWindowsView::SetState(FLUTTER_API_SYMBOL(FlutterEngine) eng) { process_events_ = true; - SendWindowMetrics(binding_handler_->GetPhysicalWidth(), - binding_handler_->GetPhysicalHeight(), + PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds(); + + SendWindowMetrics(bounds.width, bounds.height, binding_handler_->GetDpiScale()); } diff --git a/shell/platform/windows/win32_flutter_window.cc b/shell/platform/windows/win32_flutter_window.cc index 24a5458288c43..a05e5ebfa3c23 100644 --- a/shell/platform/windows/win32_flutter_window.cc +++ b/shell/platform/windows/win32_flutter_window.cc @@ -31,12 +31,8 @@ float Win32FlutterWindow::GetDpiScale() { return static_cast(GetCurrentDPI()) / static_cast(base_dpi); } -float Win32FlutterWindow::GetPhysicalWidth() { - return GetCurrentWidth(); -} - -float Win32FlutterWindow::GetPhysicalHeight() { - return GetCurrentHeight(); +PhysicalWindowBounds Win32FlutterWindow::GetPhysicalWindowBounds() { + return {GetCurrentWidth(), GetCurrentHeight()}; } // Translates button codes from Win32 API to FlutterPointerMouseButtons. diff --git a/shell/platform/windows/win32_flutter_window.h b/shell/platform/windows/win32_flutter_window.h index 28b20a912dba2..150a6edd485fb 100644 --- a/shell/platform/windows/win32_flutter_window.h +++ b/shell/platform/windows/win32_flutter_window.h @@ -70,10 +70,7 @@ class Win32FlutterWindow : public Win32Window, public WindowBindingHandler { float GetDpiScale() override; // |FlutterWindowBindingHandler| - float GetPhysicalWidth() override; - - // |FlutterWindowBindingHandler| - float GetPhysicalHeight() override; + PhysicalWindowBounds GetPhysicalWindowBounds() override; // A pointer to a FlutterWindowsView that can be used to update engine // windowing and input state. diff --git a/shell/platform/windows/window_binding_handler.h b/shell/platform/windows/window_binding_handler.h index 34f541f91eff8..71d8648917811 100644 --- a/shell/platform/windows/window_binding_handler.h +++ b/shell/platform/windows/window_binding_handler.h @@ -18,6 +18,12 @@ namespace flutter { class FlutterWindowsView; +// Structure containing physical bounds of a Window +struct PhysicalWindowBounds { + size_t width; + size_t height; +}; + using WindowsRenderTarget = std::variant< /*winrt::Windows::UI::Composition::SpriteVisual, */ HWND>; @@ -38,11 +44,8 @@ class WindowBindingHandler { // Returns the scale factor for the backing window. virtual float GetDpiScale() = 0; - // Returns the width of the backing window in physical pixels. - virtual float GetPhysicalWidth() = 0; - - // Returns the height of the backing window in physical pixels. - virtual float GetPhysicalHeight() = 0; + // Returns the bounds of the backing window in physical pixels. + virtual PhysicalWindowBounds GetPhysicalWindowBounds() = 0; }; } // namespace flutter From f5422b9e1e3d4b93458d4fcdec5bb8bd46983228 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sat, 4 Jul 2020 13:28:53 -0700 Subject: [PATCH 13/15] CR Feedback --- shell/platform/windows/flutter_windows_view.h | 34 +++++++++---------- shell/platform/windows/win32_window.h | 2 +- .../platform/windows/window_binding_handler.h | 3 +- .../windows/window_binding_handler_delegate.h | 18 +++++----- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/shell/platform/windows/flutter_windows_view.h b/shell/platform/windows/flutter_windows_view.h index b160196e90ebd..828932aed1913 100644 --- a/shell/platform/windows/flutter_windows_view.h +++ b/shell/platform/windows/flutter_windows_view.h @@ -25,22 +25,6 @@ namespace flutter { -// Struct holding the mouse state. The engine doesn't keep track of which mouse -// buttons have been pressed, so it's the embedding's responsibility. -struct MouseState { - // True if the last event sent to Flutter had at least one mouse button. - // pressed. - bool flutter_state_is_down = false; - - // True if kAdd has been sent to Flutter. Used to determine whether - // to send a kAdd event before sending an incoming mouse event, since Flutter - // expects pointers to be added before events are sent for them. - bool flutter_state_is_added = false; - - // The currently pressed buttons, as represented in FlutterPointerEvent. - uint64_t buttons = 0; -}; - // An OS-windowing neutral abstration for flutter // view that works with win32 hwnds and Windows::UI::Composition visuals. class FlutterWindowsView : public WindowBindingHandlerDelegate { @@ -117,6 +101,22 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate { void OnFontChange() override; private: + // Struct holding the mouse state. The engine doesn't keep track of which + // mouse buttons have been pressed, so it's the embedding's responsibility. + struct MouseState { + // True if the last event sent to Flutter had at least one mouse button. + // pressed. + bool flutter_state_is_down = false; + + // True if kAdd has been sent to Flutter. Used to determine whether + // to send a kAdd event before sending an incoming mouse event, since + // Flutter expects pointers to be added before events are sent for them. + bool flutter_state_is_added = false; + + // The currently pressed buttons, as represented in FlutterPointerEvent. + uint64_t buttons = 0; + }; + // Sends a window metrics update to the Flutter engine using current window // dimensions in physical void SendWindowMetrics(size_t width, size_t height, double dpiscale) const; @@ -185,7 +185,7 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate { // An object used for intializing Angle and creating / destroying render // surfaces. Surface creation functionality requires a valid render_target. - std::unique_ptr surface_manager_ = nullptr; + std::unique_ptr surface_manager_; // The handle to the Flutter engine instance. FLUTTER_API_SYMBOL(FlutterEngine) engine_ = nullptr; diff --git a/shell/platform/windows/win32_window.h b/shell/platform/windows/win32_window.h index 811cacb86542b..91da3f333794c 100644 --- a/shell/platform/windows/win32_window.h +++ b/shell/platform/windows/win32_window.h @@ -28,7 +28,7 @@ class Win32Window { unsigned int width, unsigned int height); - ::HWND GetWindowHandle(); + HWND GetWindowHandle(); protected: // Converts a c string to a wide unicode string. diff --git a/shell/platform/windows/window_binding_handler.h b/shell/platform/windows/window_binding_handler.h index 71d8648917811..698330a49b20d 100644 --- a/shell/platform/windows/window_binding_handler.h +++ b/shell/platform/windows/window_binding_handler.h @@ -32,13 +32,12 @@ class WindowBindingHandler { public: virtual ~WindowBindingHandler() = default; - // Sets the view used to communicate state changes from Window to view such + // Sets the delegate used to communicate state changes from window to view such // as key presses, mouse position updates etc. virtual void SetView(WindowBindingHandlerDelegate* view) = 0; // Returns a valid WindowsRenderTarget representing the backing // window. - virtual WindowsRenderTarget GetRenderTarget() = 0; // Returns the scale factor for the backing window. diff --git a/shell/platform/windows/window_binding_handler_delegate.h b/shell/platform/windows/window_binding_handler_delegate.h index b95f1fbd55fe5..2384a2860129f 100644 --- a/shell/platform/windows/window_binding_handler_delegate.h +++ b/shell/platform/windows/window_binding_handler_delegate.h @@ -11,39 +11,39 @@ namespace flutter { class WindowBindingHandlerDelegate { public: - // Notifies view that backing window size has changed. + // Notifies delegate that backing window size has changed. // Typically called by currently configured WindowBindingHandler virtual void OnWindowSizeChanged(size_t width, size_t height) const = 0; - // Notifies view that backing window mouse has moved. + // Notifies delegate that backing window mouse has moved. // Typically called by currently configured WindowBindingHandler virtual void OnPointerMove(double x, double y) = 0; - // Notifies view that backing window mouse pointer button has been pressed. + // Notifies delegate that backing window mouse pointer button has been pressed. // Typically called by currently configured WindowBindingHandler virtual void OnPointerDown(double x, double y, FlutterPointerMouseButtons button) = 0; - // Notifies view that backing window mouse pointer button has been released. + // Notifies delegate that backing window mouse pointer button has been released. // Typically called by currently configured WindowBindingHandler virtual void OnPointerUp(double x, double y, FlutterPointerMouseButtons button) = 0; - // Notifies view that backing window mouse pointer has left the window. + // Notifies delegate that backing window mouse pointer has left the window. // Typically called by currently configured WindowBindingHandler virtual void OnPointerLeave() = 0; - // Notifies view that backing window has received text. + // Notifies delegate that backing window has received text. // Typically called by currently configured WindowBindingHandler virtual void OnText(const std::u16string&) = 0; - // Notifies view that backing window size has received key press. + // Notifies delegate that backing window size has received key press. // Typically called by currently configured WindowBindingHandler virtual void OnKey(int key, int scancode, int action, char32_t character) = 0; - // Notifies view that backing window size has recevied scroll. + // Notifies delegate that backing window size has recevied scroll. // Typically called by currently configured WindowBindingHandler virtual void OnScroll(double x, double y, @@ -51,7 +51,7 @@ class WindowBindingHandlerDelegate { double delta_y, int scroll_offset_multiplier) = 0; - // Notifies view that backing window size has had system font change. + // Notifies delegate that backing window size has had system font change. // Typically called by currently configured WindowBindingHandler virtual void OnFontChange() = 0; }; From 80662082e0e96a2a6a3246307a0383020f6bc85d Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sat, 4 Jul 2020 15:41:35 -0700 Subject: [PATCH 14/15] CR feedback --- .../platform/windows/flutter_windows_view.cc | 22 ++----------------- shell/platform/windows/flutter_windows_view.h | 6 ++--- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/shell/platform/windows/flutter_windows_view.cc b/shell/platform/windows/flutter_windows_view.cc index b922aa4aef06d..31aca5b060fb7 100644 --- a/shell/platform/windows/flutter_windows_view.cc +++ b/shell/platform/windows/flutter_windows_view.cc @@ -66,8 +66,6 @@ void FlutterWindowsView::SetState(FLUTTER_API_SYMBOL(FlutterEngine) eng) { platform_handler_ = std::make_unique( internal_plugin_messenger, this); - process_events_ = true; - PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds(); SendWindowMetrics(bounds.width, bounds.height, @@ -104,68 +102,54 @@ void FlutterWindowsView::HandlePlatformMessage( auto message = ConvertToDesktopMessage(*engine_message); message_dispatcher_->HandleMessage( - message, [this] { this->process_events_ = false; }, - [this] { this->process_events_ = true; }); + message, [this] { }, + [this] { }); } void FlutterWindowsView::OnWindowSizeChanged(size_t width, size_t height) const { - if (process_events_) { SendWindowMetrics(width, height, binding_handler_->GetDpiScale()); - } } void FlutterWindowsView::OnPointerMove(double x, double y) { - if (process_events_) { SendPointerMove(x, y); - } } void FlutterWindowsView::OnPointerDown( double x, double y, FlutterPointerMouseButtons flutter_button) { - if (process_events_) { if (flutter_button != 0) { uint64_t mouse_buttons = mouse_state_.buttons | flutter_button; SetMouseButtons(mouse_buttons); SendPointerDown(x, y); } - } } void FlutterWindowsView::OnPointerUp( double x, double y, FlutterPointerMouseButtons flutter_button) { - if (process_events_) { if (flutter_button != 0) { uint64_t mouse_buttons = mouse_state_.buttons & ~flutter_button; SetMouseButtons(mouse_buttons); SendPointerUp(x, y); } - } } void FlutterWindowsView::OnPointerLeave() { - if (process_events_) { SendPointerLeave(); - } } void FlutterWindowsView::OnText(const std::u16string& text) { - if (process_events_) { SendText(text); - } } void FlutterWindowsView::OnKey(int key, int scancode, int action, char32_t character) { - if (process_events_) { SendKey(key, scancode, action, character); - } } void FlutterWindowsView::OnScroll(double x, @@ -173,9 +157,7 @@ void FlutterWindowsView::OnScroll(double x, double delta_x, double delta_y, int scroll_offset_multiplier) { - if (process_events_) { SendScroll(x, y, delta_x, delta_y, scroll_offset_multiplier); - } } void FlutterWindowsView::OnFontChange() { diff --git a/shell/platform/windows/flutter_windows_view.h b/shell/platform/windows/flutter_windows_view.h index 828932aed1913..9a7b0994d2438 100644 --- a/shell/platform/windows/flutter_windows_view.h +++ b/shell/platform/windows/flutter_windows_view.h @@ -34,7 +34,8 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate { ~FlutterWindowsView(); // Factory for creating FlutterWindowsView requiring an implementator of - // WindowBindingHandler. + // WindowBindingHandler. In order for object to render Flutter content + // the SetState method must be called with a valid FlutterEngine instance. static FlutterDesktopViewControllerRef CreateFlutterWindowsView( std::unique_ptr window_binding); @@ -212,9 +213,6 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate { // Handler for the flutter/platform channel. std::unique_ptr platform_handler_; - // should we forword input messages or not - bool process_events_ = false; - // Currently configured WindowBindingHandler for view. std::unique_ptr binding_handler_; }; From a011b08214153fb470aa353e13f9993243f31b43 Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sat, 4 Jul 2020 15:42:35 -0700 Subject: [PATCH 15/15] clang-format --- .../platform/windows/flutter_windows_view.cc | 35 +++++++++---------- .../platform/windows/window_binding_handler.h | 4 +-- .../windows/window_binding_handler_delegate.h | 8 ++--- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/shell/platform/windows/flutter_windows_view.cc b/shell/platform/windows/flutter_windows_view.cc index 31aca5b060fb7..4f6f55e12dc58 100644 --- a/shell/platform/windows/flutter_windows_view.cc +++ b/shell/platform/windows/flutter_windows_view.cc @@ -102,54 +102,53 @@ void FlutterWindowsView::HandlePlatformMessage( auto message = ConvertToDesktopMessage(*engine_message); message_dispatcher_->HandleMessage( - message, [this] { }, - [this] { }); + message, [this] {}, [this] {}); } void FlutterWindowsView::OnWindowSizeChanged(size_t width, size_t height) const { - SendWindowMetrics(width, height, binding_handler_->GetDpiScale()); + SendWindowMetrics(width, height, binding_handler_->GetDpiScale()); } void FlutterWindowsView::OnPointerMove(double x, double y) { - SendPointerMove(x, y); + SendPointerMove(x, y); } void FlutterWindowsView::OnPointerDown( double x, double y, FlutterPointerMouseButtons flutter_button) { - if (flutter_button != 0) { - uint64_t mouse_buttons = mouse_state_.buttons | flutter_button; - SetMouseButtons(mouse_buttons); - SendPointerDown(x, y); - } + if (flutter_button != 0) { + uint64_t mouse_buttons = mouse_state_.buttons | flutter_button; + SetMouseButtons(mouse_buttons); + SendPointerDown(x, y); + } } void FlutterWindowsView::OnPointerUp( double x, double y, FlutterPointerMouseButtons flutter_button) { - if (flutter_button != 0) { - uint64_t mouse_buttons = mouse_state_.buttons & ~flutter_button; - SetMouseButtons(mouse_buttons); - SendPointerUp(x, y); - } + if (flutter_button != 0) { + uint64_t mouse_buttons = mouse_state_.buttons & ~flutter_button; + SetMouseButtons(mouse_buttons); + SendPointerUp(x, y); + } } void FlutterWindowsView::OnPointerLeave() { - SendPointerLeave(); + SendPointerLeave(); } void FlutterWindowsView::OnText(const std::u16string& text) { - SendText(text); + SendText(text); } void FlutterWindowsView::OnKey(int key, int scancode, int action, char32_t character) { - SendKey(key, scancode, action, character); + SendKey(key, scancode, action, character); } void FlutterWindowsView::OnScroll(double x, @@ -157,7 +156,7 @@ void FlutterWindowsView::OnScroll(double x, double delta_x, double delta_y, int scroll_offset_multiplier) { - SendScroll(x, y, delta_x, delta_y, scroll_offset_multiplier); + SendScroll(x, y, delta_x, delta_y, scroll_offset_multiplier); } void FlutterWindowsView::OnFontChange() { diff --git a/shell/platform/windows/window_binding_handler.h b/shell/platform/windows/window_binding_handler.h index 698330a49b20d..730c3dd821a37 100644 --- a/shell/platform/windows/window_binding_handler.h +++ b/shell/platform/windows/window_binding_handler.h @@ -32,8 +32,8 @@ class WindowBindingHandler { public: virtual ~WindowBindingHandler() = default; - // Sets the delegate used to communicate state changes from window to view such - // as key presses, mouse position updates etc. + // Sets the delegate used to communicate state changes from window to view + // such as key presses, mouse position updates etc. virtual void SetView(WindowBindingHandlerDelegate* view) = 0; // Returns a valid WindowsRenderTarget representing the backing diff --git a/shell/platform/windows/window_binding_handler_delegate.h b/shell/platform/windows/window_binding_handler_delegate.h index 2384a2860129f..3ff8f7e889de5 100644 --- a/shell/platform/windows/window_binding_handler_delegate.h +++ b/shell/platform/windows/window_binding_handler_delegate.h @@ -19,14 +19,14 @@ class WindowBindingHandlerDelegate { // Typically called by currently configured WindowBindingHandler virtual void OnPointerMove(double x, double y) = 0; - // Notifies delegate that backing window mouse pointer button has been pressed. - // Typically called by currently configured WindowBindingHandler + // Notifies delegate that backing window mouse pointer button has been + // pressed. Typically called by currently configured WindowBindingHandler virtual void OnPointerDown(double x, double y, FlutterPointerMouseButtons button) = 0; - // Notifies delegate that backing window mouse pointer button has been released. - // Typically called by currently configured WindowBindingHandler + // Notifies delegate that backing window mouse pointer button has been + // released. Typically called by currently configured WindowBindingHandler virtual void OnPointerUp(double x, double y, FlutterPointerMouseButtons button) = 0;