diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index 95fd0061eec3a..46fec1b3ca9a0 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -352,7 +352,6 @@ ../../../flutter/shell/platform/windows/text_input_plugin_unittest.cc ../../../flutter/shell/platform/windows/window_proc_delegate_manager_unittests.cc ../../../flutter/shell/platform/windows/window_unittests.cc -../../../flutter/shell/platform/windows/windows_lifecycle_manager_unittests.cc ../../../flutter/shell/profiling/sampling_profiler_unittest.cc ../../../flutter/shell/testing ../../../flutter/shell/vmservice/.dart_tool diff --git a/shell/platform/windows/BUILD.gn b/shell/platform/windows/BUILD.gn index 10369da9c097e..5ee5b431991c8 100644 --- a/shell/platform/windows/BUILD.gn +++ b/shell/platform/windows/BUILD.gn @@ -221,7 +221,6 @@ executable("flutter_windows_unittests") { "text_input_plugin_unittest.cc", "window_proc_delegate_manager_unittests.cc", "window_unittests.cc", - "windows_lifecycle_manager_unittests.cc", ] configs += diff --git a/shell/platform/windows/client_wrapper/flutter_engine.cc b/shell/platform/windows/client_wrapper/flutter_engine.cc index 53d32f443f88f..00ccbbcff7cab 100644 --- a/shell/platform/windows/client_wrapper/flutter_engine.cc +++ b/shell/platform/windows/client_wrapper/flutter_engine.cc @@ -100,19 +100,6 @@ void FlutterEngine::SetNextFrameCallback(std::function callback) { this); } -std::optional FlutterEngine::ProcessExternalWindowMessage( - HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam) { - LRESULT result; - if (FlutterDesktopEngineProcessExternalWindowMessage( - engine_, hwnd, message, wparam, lparam, &result)) { - return result; - } - return std::nullopt; -} - FlutterDesktopEngineRef FlutterEngine::RelinquishEngine() { owns_engine_ = false; return engine_; diff --git a/shell/platform/windows/client_wrapper/flutter_engine_unittests.cc b/shell/platform/windows/client_wrapper/flutter_engine_unittests.cc index 78ad17b1efdf1..a1274998eadce 100644 --- a/shell/platform/windows/client_wrapper/flutter_engine_unittests.cc +++ b/shell/platform/windows/client_wrapper/flutter_engine_unittests.cc @@ -56,17 +56,6 @@ class TestFlutterWindowsApi : public testing::StubFlutterWindowsApi { // |flutter::testing::StubFlutterWindowsApi| void EngineReloadSystemFonts() override { reload_fonts_called_ = true; } - // |flutter::testing::StubFlutterWindowsApi| - bool EngineProcessExternalWindowMessage(FlutterDesktopEngineRef engine, - HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam, - LRESULT* result) override { - last_external_message_ = message; - return false; - } - bool create_called() { return create_called_; } bool run_called() { return run_called_; } @@ -85,8 +74,6 @@ class TestFlutterWindowsApi : public testing::StubFlutterWindowsApi { next_frame_callback_ = nullptr; } - UINT last_external_message() { return last_external_message_; } - private: bool create_called_ = false; bool run_called_ = false; @@ -95,7 +82,6 @@ class TestFlutterWindowsApi : public testing::StubFlutterWindowsApi { std::vector dart_entrypoint_arguments_; VoidCallback next_frame_callback_ = nullptr; void* next_frame_user_data_ = nullptr; - UINT last_external_message_ = 0; }; } // namespace @@ -215,16 +201,4 @@ TEST(FlutterEngineTest, SetNextFrameCallback) { EXPECT_TRUE(success); } -TEST(FlutterEngineTest, ProcessExternalWindowMessage) { - testing::ScopedStubFlutterWindowsApi scoped_api_stub( - std::make_unique()); - auto test_api = static_cast(scoped_api_stub.stub()); - - FlutterEngine engine(DartProject(L"fake/project/path")); - - engine.ProcessExternalWindowMessage(reinterpret_cast(1), 1234, 0, 0); - - EXPECT_EQ(test_api->last_external_message(), 1234); -} - } // namespace flutter diff --git a/shell/platform/windows/client_wrapper/include/flutter/flutter_engine.h b/shell/platform/windows/client_wrapper/include/flutter/flutter_engine.h index b71c5cd479611..63a820ce2d6bd 100644 --- a/shell/platform/windows/client_wrapper/include/flutter/flutter_engine.h +++ b/shell/platform/windows/client_wrapper/include/flutter/flutter_engine.h @@ -9,7 +9,6 @@ #include #include -#include #include #include "binary_messenger.h" @@ -85,16 +84,6 @@ class FlutterEngine : public PluginRegistry { // once on the platform thread. void SetNextFrameCallback(std::function callback); - // Called to pass an external window message to the engine for lifecycle - // state updates. This does not consume the window message. Non-Flutter - // windows must call this method in their WndProc in order to be included in - // the logic for application lifecycle state updates. Returns a result when - // the message has been consumed. - std::optional ProcessExternalWindowMessage(HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam); - private: // For access to RelinquishEngine. friend class FlutterViewController; diff --git a/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.cc b/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.cc index da0a8c57712d3..ed9f9d3bcb2ff 100644 --- a/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.cc +++ b/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.cc @@ -162,20 +162,6 @@ IDXGIAdapter* FlutterDesktopViewGetGraphicsAdapter(FlutterDesktopViewRef view) { return nullptr; } -bool FlutterDesktopEngineProcessExternalWindowMessage( - FlutterDesktopEngineRef engine, - HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam, - LRESULT* result) { - if (s_stub_implementation) { - return s_stub_implementation->EngineProcessExternalWindowMessage( - engine, hwnd, message, wparam, lparam, result); - } - return false; -} - FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView( FlutterDesktopPluginRegistrarRef controller) { // The stub ignores this, so just return an arbitrary non-zero value. diff --git a/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.h b/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.h index 73e920d949e32..a1864d4f07720 100644 --- a/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.h +++ b/shell/platform/windows/client_wrapper/testing/stub_flutter_windows_api.h @@ -89,17 +89,6 @@ class StubFlutterWindowsApi { // FlutterDesktopPluginRegistrarUnregisterTopLevelWindowProcDelegate. virtual void PluginRegistrarUnregisterTopLevelWindowProcDelegate( FlutterDesktopWindowProcCallback delegate) {} - - // Claled for FlutterDesktopEngineProcessExternalWindowMessage. - virtual bool EngineProcessExternalWindowMessage( - FlutterDesktopEngineRef engine, - HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam, - LRESULT* result) { - return false; - } }; // A test helper that owns a stub implementation, making it the test stub for diff --git a/shell/platform/windows/flutter_window.cc b/shell/platform/windows/flutter_window.cc index 61e51afa67841..6dba8cadc368b 100644 --- a/shell/platform/windows/flutter_window.cc +++ b/shell/platform/windows/flutter_window.cc @@ -74,19 +74,11 @@ FlutterWindow::FlutterWindow(int width, int height) current_cursor_ = ::LoadCursor(nullptr, IDC_ARROW); } -FlutterWindow::~FlutterWindow() { - OnWindowStateEvent(WindowStateEvent::kHide); -} +FlutterWindow::~FlutterWindow() {} void FlutterWindow::SetView(WindowBindingHandlerDelegate* window) { binding_handler_delegate_ = window; direct_manipulation_owner_->SetBindingHandlerDelegate(window); - if (restored_) { - OnWindowStateEvent(WindowStateEvent::kShow); - } - if (focused_) { - OnWindowStateEvent(WindowStateEvent::kFocus); - } } WindowsRenderTarget FlutterWindow::GetRenderTarget() { @@ -336,26 +328,4 @@ bool FlutterWindow::NeedsVSync() { return true; } -void FlutterWindow::OnWindowStateEvent(WindowStateEvent event) { - switch (event) { - case WindowStateEvent::kShow: - restored_ = true; - break; - case WindowStateEvent::kHide: - restored_ = false; - focused_ = false; - break; - case WindowStateEvent::kFocus: - focused_ = true; - break; - case WindowStateEvent::kUnfocus: - focused_ = false; - break; - } - HWND hwnd = GetPlatformWindow(); - if (hwnd && binding_handler_delegate_) { - binding_handler_delegate_->OnWindowStateEvent(hwnd, event); - } -} - } // namespace flutter diff --git a/shell/platform/windows/flutter_window.h b/shell/platform/windows/flutter_window.h index 55d9db885a4d0..5725af5de1a6a 100644 --- a/shell/platform/windows/flutter_window.h +++ b/shell/platform/windows/flutter_window.h @@ -162,9 +162,6 @@ class FlutterWindow : public Window, public WindowBindingHandler { // |Window| ui::AXFragmentRootDelegateWin* GetAxFragmentRootDelegate() override; - // |Window| - void OnWindowStateEvent(WindowStateEvent event) override; - private: // A pointer to a FlutterWindowsView that can be used to update engine // windowing and input state. @@ -176,12 +173,6 @@ class FlutterWindow : public Window, public WindowBindingHandler { // The cursor rect set by Flutter. RECT cursor_rect_; - // The window receives resize and focus messages before its view is set, so - // these values cache the state of the window in the meantime so that the - // proper application lifecycle state can be updated once the view is set. - bool restored_ = false; - bool focused_ = false; - FML_DISALLOW_COPY_AND_ASSIGN(FlutterWindow); }; diff --git a/shell/platform/windows/flutter_window_unittests.cc b/shell/platform/windows/flutter_window_unittests.cc index 8ba12aecd7cda..e8ec2820666b1 100644 --- a/shell/platform/windows/flutter_window_unittests.cc +++ b/shell/platform/windows/flutter_window_unittests.cc @@ -27,7 +27,7 @@ class MockFlutterWindow : public FlutterWindow { ON_CALL(*this, GetDpiScale()) .WillByDefault(Return(this->FlutterWindow::GetDpiScale())); } - virtual ~MockFlutterWindow() { SetView(nullptr); } + virtual ~MockFlutterWindow() {} // Wrapper for GetCurrentDPI() which is a protected method. UINT GetDpi() { return GetCurrentDPI(); } @@ -229,10 +229,6 @@ TEST(FlutterWindowTest, OnPointerStarSendsDeviceType) { kDefaultPointerDeviceId, WM_LBUTTONDOWN); win32window.OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus, kDefaultPointerDeviceId); - - // Destruction of win32window sends a HIDE update. In situ, the window is - // owned by the delegate, and so is destructed first. Not so here. - win32window.SetView(nullptr); } // Tests that calls to OnScroll in turn calls GetScrollOffsetMultiplier @@ -328,61 +324,5 @@ TEST(FlutterWindowTest, AlertNode) { EXPECT_EQ(role.lVal, ROLE_SYSTEM_ALERT); } -TEST(FlutterWindowTest, LifecycleFocusMessages) { - MockFlutterWindow win32window; - ON_CALL(win32window, GetPlatformWindow).WillByDefault([]() { - return reinterpret_cast(1); - }); - MockWindowBindingHandlerDelegate delegate; - win32window.SetView(&delegate); - - WindowStateEvent last_event; - ON_CALL(delegate, OnWindowStateEvent) - .WillByDefault([&last_event](HWND hwnd, WindowStateEvent event) { - last_event = event; - }); - - win32window.InjectWindowMessage(WM_SIZE, 0, 0); - EXPECT_EQ(last_event, WindowStateEvent::kHide); - - win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1)); - EXPECT_EQ(last_event, WindowStateEvent::kShow); - - win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0); - EXPECT_EQ(last_event, WindowStateEvent::kFocus); - - win32window.InjectWindowMessage(WM_KILLFOCUS, 0, 0); - EXPECT_EQ(last_event, WindowStateEvent::kUnfocus); -} - -TEST(FlutterWindowTest, CachedLifecycleMessage) { - MockFlutterWindow win32window; - ON_CALL(win32window, GetPlatformWindow).WillByDefault([]() { - return reinterpret_cast(1); - }); - - // Restore - win32window.InjectWindowMessage(WM_SIZE, 0, MAKEWORD(1, 1)); - - // Focus - win32window.InjectWindowMessage(WM_SETFOCUS, 0, 0); - - MockWindowBindingHandlerDelegate delegate; - bool focused = false; - bool restored = false; - ON_CALL(delegate, OnWindowStateEvent) - .WillByDefault([&](HWND hwnd, WindowStateEvent event) { - if (event == WindowStateEvent::kFocus) { - focused = true; - } else if (event == WindowStateEvent::kShow) { - restored = true; - } - }); - - win32window.SetView(&delegate); - EXPECT_TRUE(focused); - EXPECT_TRUE(restored); -} - } // namespace testing } // namespace flutter diff --git a/shell/platform/windows/flutter_windows.cc b/shell/platform/windows/flutter_windows.cc index fd3071d898505..50bc538f1f8e0 100644 --- a/shell/platform/windows/flutter_windows.cc +++ b/shell/platform/windows/flutter_windows.cc @@ -207,22 +207,6 @@ IDXGIAdapter* FlutterDesktopViewGetGraphicsAdapter(FlutterDesktopViewRef view) { return nullptr; } -bool FlutterDesktopEngineProcessExternalWindowMessage( - FlutterDesktopEngineRef engine, - HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam, - LRESULT* result) { - std::optional lresult = - EngineFromHandle(engine)->ProcessExternalWindowMessage(hwnd, message, - wparam, lparam); - if (result && lresult.has_value()) { - *result = lresult.value(); - } - return lresult.has_value(); -} - FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView( FlutterDesktopPluginRegistrarRef registrar) { return HandleForView(registrar->engine->view()); diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc index 8ab6b7d5fae74..68cccd27ab19f 100644 --- a/shell/platform/windows/flutter_windows_engine.cc +++ b/shell/platform/windows/flutter_windows_engine.cc @@ -584,9 +584,10 @@ void FlutterWindowsEngine::SetNextFrameCallback(fml::closure callback) { } void FlutterWindowsEngine::SetLifecycleState(flutter::AppLifecycleState state) { - if (lifecycle_manager_) { - lifecycle_manager_->SetLifecycleState(state); - } + const char* state_name = flutter::AppLifecycleStateToString(state); + SendPlatformMessage("flutter/lifecycle", + reinterpret_cast(state_name), + strlen(state_name), nullptr, nullptr); } void FlutterWindowsEngine::SendSystemLocales() { @@ -795,21 +796,4 @@ void FlutterWindowsEngine::OnApplicationLifecycleEnabled() { lifecycle_manager_->BeginProcessingClose(); } -void FlutterWindowsEngine::OnWindowStateEvent(HWND hwnd, - WindowStateEvent event) { - lifecycle_manager_->OnWindowStateEvent(hwnd, event); -} - -std::optional FlutterWindowsEngine::ProcessExternalWindowMessage( - HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam) { - if (lifecycle_manager_) { - return lifecycle_manager_->ExternalWindowMessage(hwnd, message, wparam, - lparam); - } - return std::nullopt; -} - } // namespace flutter diff --git a/shell/platform/windows/flutter_windows_engine.h b/shell/platform/windows/flutter_windows_engine.h index 36147c00c821c..3e5a7343287b6 100644 --- a/shell/platform/windows/flutter_windows_engine.h +++ b/shell/platform/windows/flutter_windows_engine.h @@ -262,22 +262,6 @@ class FlutterWindowsEngine { // Registers the top level handler for the WM_CLOSE window message. void OnApplicationLifecycleEnabled(); - // Called when a Window receives an event that may alter the application - // lifecycle state. - void OnWindowStateEvent(HWND hwnd, WindowStateEvent event); - - // Handle a message from a non-Flutter window in the same application. - // Returns a result when the message is consumed and should not be processed - // further. - std::optional ProcessExternalWindowMessage(HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam); - - WindowsLifecycleManager* lifecycle_manager() { - return lifecycle_manager_.get(); - } - protected: // Creates the keyboard key handler. // diff --git a/shell/platform/windows/flutter_windows_engine_unittests.cc b/shell/platform/windows/flutter_windows_engine_unittests.cc index 8dcb50846f23c..80fb26f6cd3b3 100644 --- a/shell/platform/windows/flutter_windows_engine_unittests.cc +++ b/shell/platform/windows/flutter_windows_engine_unittests.cc @@ -608,7 +608,6 @@ class MockFlutterWindowsView : public FlutterWindowsView { MOCK_METHOD2(NotifyWinEventWrapper, void(ui::AXPlatformNodeWin*, ax::mojom::Event)); - MOCK_METHOD0(GetPlatformWindow, HWND()); private: FML_DISALLOW_COPY_AND_ASSIGN(MockFlutterWindowsView); @@ -669,7 +668,6 @@ class MockWindowsLifecycleManager : public WindowsLifecycleManager { UINT)); MOCK_METHOD4(DispatchMessage, void(HWND, UINT, WPARAM, LPARAM)); MOCK_METHOD0(IsLastWindowOfProcess, bool(void)); - MOCK_METHOD1(SetLifecycleState, void(AppLifecycleState)); }; TEST_F(FlutterWindowsEngineTest, TestExit) { @@ -897,110 +895,5 @@ TEST_F(FlutterWindowsEngineTest, EnableApplicationLifecycle) { 0); } -TEST_F(FlutterWindowsEngineTest, AppStartsInResumedState) { - FlutterWindowsEngineBuilder builder{GetContext()}; - - auto window_binding_handler = - std::make_unique<::testing::NiceMock>(); - MockFlutterWindowsView view(std::move(window_binding_handler)); - view.SetEngine(builder.Build()); - FlutterWindowsEngine* engine = view.GetEngine(); - - EngineModifier modifier(engine); - modifier.embedder_api().RunsAOTCompiledDartCode = []() { return false; }; - auto handler = std::make_unique(engine); - EXPECT_CALL(*handler, SetLifecycleState(AppLifecycleState::kResumed)) - .Times(1); - modifier.SetLifecycleManager(std::move(handler)); - engine->Run(); -} - -TEST_F(FlutterWindowsEngineTest, LifecycleStateTransition) { - FlutterWindowsEngineBuilder builder{GetContext()}; - - auto window_binding_handler = - std::make_unique<::testing::NiceMock>(); - MockFlutterWindowsView view(std::move(window_binding_handler)); - view.SetEngine(builder.Build()); - FlutterWindowsEngine* engine = view.GetEngine(); - - EngineModifier modifier(engine); - modifier.embedder_api().RunsAOTCompiledDartCode = []() { return false; }; - engine->Run(); - - engine->window_proc_delegate_manager()->OnTopLevelWindowProc( - (HWND)1, WM_SIZE, SIZE_RESTORED, 0); - EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(), - AppLifecycleState::kResumed); - - engine->window_proc_delegate_manager()->OnTopLevelWindowProc( - (HWND)1, WM_SIZE, SIZE_MINIMIZED, 0); - EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(), - AppLifecycleState::kHidden); - - engine->window_proc_delegate_manager()->OnTopLevelWindowProc( - (HWND)1, WM_SIZE, SIZE_RESTORED, 0); - EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(), - AppLifecycleState::kInactive); -} - -TEST_F(FlutterWindowsEngineTest, ExternalWindowMessage) { - FlutterWindowsEngineBuilder builder{GetContext()}; - - auto window_binding_handler = - std::make_unique<::testing::NiceMock>(); - MockFlutterWindowsView view(std::move(window_binding_handler)); - view.SetEngine(builder.Build()); - FlutterWindowsEngine* engine = view.GetEngine(); - - EngineModifier modifier(engine); - modifier.embedder_api().RunsAOTCompiledDartCode = []() { return false; }; - // Sets lifecycle state to resumed. - engine->Run(); - - // Ensure HWND(1) is in the set of visible windows before hiding it. - engine->ProcessExternalWindowMessage(reinterpret_cast(1), WM_SHOWWINDOW, - TRUE, NULL); - engine->ProcessExternalWindowMessage(reinterpret_cast(1), WM_SHOWWINDOW, - FALSE, NULL); - - EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(), - AppLifecycleState::kHidden); -} - -TEST_F(FlutterWindowsEngineTest, InnerWindowHidden) { - FlutterWindowsEngineBuilder builder{GetContext()}; - HWND outer = reinterpret_cast(1); - HWND inner = reinterpret_cast(2); - - auto window_binding_handler = - std::make_unique<::testing::NiceMock>(); - MockFlutterWindowsView view(std::move(window_binding_handler)); - ON_CALL(view, GetPlatformWindow).WillByDefault([=]() { return inner; }); - view.SetEngine(builder.Build()); - FlutterWindowsEngine* engine = view.GetEngine(); - - EngineModifier modifier(engine); - modifier.embedder_api().RunsAOTCompiledDartCode = []() { return false; }; - // Sets lifecycle state to resumed. - engine->Run(); - - // Show both top-level and Flutter window. - engine->window_proc_delegate_manager()->OnTopLevelWindowProc( - outer, WM_SHOWWINDOW, TRUE, NULL); - view.OnWindowStateEvent(inner, WindowStateEvent::kShow); - view.OnWindowStateEvent(inner, WindowStateEvent::kFocus); - - EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(), - AppLifecycleState::kResumed); - - // Hide Flutter window, but not top level window. - view.OnWindowStateEvent(inner, WindowStateEvent::kHide); - - // The top-level window is still visible, so we ought not enter hidden state. - EXPECT_EQ(engine->lifecycle_manager()->GetLifecycleState(), - AppLifecycleState::kInactive); -} - } // namespace testing } // namespace flutter diff --git a/shell/platform/windows/flutter_windows_view.cc b/shell/platform/windows/flutter_windows_view.cc index d668d2f447b6c..131cd2a52a82c 100644 --- a/shell/platform/windows/flutter_windows_view.cc +++ b/shell/platform/windows/flutter_windows_view.cc @@ -673,10 +673,4 @@ void FlutterWindowsView::OnDwmCompositionChanged() { } } -void FlutterWindowsView::OnWindowStateEvent(HWND hwnd, WindowStateEvent event) { - if (engine_) { - engine_->OnWindowStateEvent(hwnd, event); - } -} - } // namespace flutter diff --git a/shell/platform/windows/flutter_windows_view.h b/shell/platform/windows/flutter_windows_view.h index 792db3f5b9f95..8dc31fafee39c 100644 --- a/shell/platform/windows/flutter_windows_view.h +++ b/shell/platform/windows/flutter_windows_view.h @@ -211,9 +211,6 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate, return accessibility_bridge_; } - // |WindowBindingHandlerDelegate| - void OnWindowStateEvent(HWND hwnd, WindowStateEvent event) override; - protected: virtual void NotifyWinEventWrapper(ui::AXPlatformNodeWin* node, ax::mojom::Event event); diff --git a/shell/platform/windows/public/flutter_windows.h b/shell/platform/windows/public/flutter_windows.h index beee0f029f4ff..767c3468d45d3 100644 --- a/shell/platform/windows/public/flutter_windows.h +++ b/shell/platform/windows/public/flutter_windows.h @@ -212,19 +212,6 @@ FLUTTER_EXPORT HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view); FLUTTER_EXPORT IDXGIAdapter* FlutterDesktopViewGetGraphicsAdapter( FlutterDesktopViewRef view); -// Called to pass an external window message to the engine for lifecycle -// state updates. This does not consume the window message. Non-Flutter windows -// must call this method in their WndProc in order to be included in the logic -// for application lifecycle state updates. Returns true when the message is -// consumed. -FLUTTER_EXPORT bool FlutterDesktopEngineProcessExternalWindowMessage( - FlutterDesktopEngineRef engine, - HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam, - LRESULT* result); - // ========== Plugin Registrar (extensions) ========== // These are Windows-specific extensions to flutter_plugin_registrar.h diff --git a/shell/platform/windows/testing/mock_window.h b/shell/platform/windows/testing/mock_window.h index 4294476d91750..53567b723dafc 100644 --- a/shell/platform/windows/testing/mock_window.h +++ b/shell/platform/windows/testing/mock_window.h @@ -66,8 +66,6 @@ class MockWindow : public Window { MOCK_METHOD3(OnGetObject, LRESULT(UINT, WPARAM, LPARAM)); - MOCK_METHOD1(OnWindowStateEvent, void(WindowStateEvent)); - void CallOnImeComposition(UINT const message, WPARAM const wparam, LPARAM const lparam); diff --git a/shell/platform/windows/testing/mock_window_binding_handler_delegate.h b/shell/platform/windows/testing/mock_window_binding_handler_delegate.h index fb58b354cb72d..35147d4e09200 100644 --- a/shell/platform/windows/testing/mock_window_binding_handler_delegate.h +++ b/shell/platform/windows/testing/mock_window_binding_handler_delegate.h @@ -61,8 +61,6 @@ class MockWindowBindingHandlerDelegate : public WindowBindingHandlerDelegate { MOCK_METHOD0(GetAxFragmentRootDelegate, ui::AXFragmentRootDelegateWin*()); - MOCK_METHOD2(OnWindowStateEvent, void(HWND, WindowStateEvent)); - private: FML_DISALLOW_COPY_AND_ASSIGN(MockWindowBindingHandlerDelegate); }; diff --git a/shell/platform/windows/window.cc b/shell/platform/windows/window.cc index a4cc4efec6754..ceb9cb8379ff9 100644 --- a/shell/platform/windows/window.cc +++ b/shell/platform/windows/window.cc @@ -352,9 +352,6 @@ Window::HandleMessage(UINT const message, current_width_ = width; current_height_ = height; HandleResize(width, height); - - OnWindowStateEvent(width == 0 && height == 0 ? WindowStateEvent::kHide - : WindowStateEvent::kShow); break; case WM_PAINT: OnPaint(); @@ -433,11 +430,9 @@ Window::HandleMessage(UINT const message, break; } case WM_SETFOCUS: - OnWindowStateEvent(WindowStateEvent::kFocus); ::CreateCaret(window_handle_, nullptr, 1, 1); break; case WM_KILLFOCUS: - OnWindowStateEvent(WindowStateEvent::kUnfocus); ::DestroyCaret(); break; case WM_LBUTTONDOWN: diff --git a/shell/platform/windows/window.h b/shell/platform/windows/window.h index b3605cd7b19d5..632e140979575 100644 --- a/shell/platform/windows/window.h +++ b/shell/platform/windows/window.h @@ -18,7 +18,6 @@ #include "flutter/shell/platform/windows/keyboard_manager.h" #include "flutter/shell/platform/windows/sequential_id_generator.h" #include "flutter/shell/platform/windows/text_input_manager.h" -#include "flutter/shell/platform/windows/windows_lifecycle_manager.h" #include "flutter/shell/platform/windows/windows_proc_table.h" #include "flutter/shell/platform/windows/windowsx_shim.h" #include "flutter/third_party/accessibility/ax/platform/ax_fragment_root_delegate_win.h" @@ -224,9 +223,6 @@ class Window : public KeyboardManager::WindowDelegate { // Called to obtain a pointer to the fragment root delegate. virtual ui::AXFragmentRootDelegateWin* GetAxFragmentRootDelegate() = 0; - // Called on a resize or focus event. - virtual void OnWindowStateEvent(WindowStateEvent event) = 0; - protected: // Win32's DefWindowProc. // diff --git a/shell/platform/windows/window_binding_handler_delegate.h b/shell/platform/windows/window_binding_handler_delegate.h index 27c5687adf168..1812107f2dfa9 100644 --- a/shell/platform/windows/window_binding_handler_delegate.h +++ b/shell/platform/windows/window_binding_handler_delegate.h @@ -9,7 +9,6 @@ #include "flutter/shell/platform/common/geometry.h" #include "flutter/shell/platform/embedder/embedder.h" -#include "flutter/shell/platform/windows/windows_lifecycle_manager.h" #include "flutter/third_party/accessibility/ax/platform/ax_fragment_root_delegate_win.h" #include "flutter/third_party/accessibility/gfx/native_widget_types.h" @@ -145,10 +144,6 @@ class WindowBindingHandlerDelegate { // MSAA, UIA elements do not explicitly store or enumerate their // children and parents, so a method such as this is required. virtual ui::AXFragmentRootDelegateWin* GetAxFragmentRootDelegate() = 0; - - // Called when a window receives an event that may alter application lifecycle - // state. - virtual void OnWindowStateEvent(HWND hwnd, WindowStateEvent event) = 0; }; } // namespace flutter diff --git a/shell/platform/windows/windows_lifecycle_manager.cc b/shell/platform/windows/windows_lifecycle_manager.cc index dbd5e71658a2e..f8bf5de37f7bf 100644 --- a/shell/platform/windows/windows_lifecycle_manager.cc +++ b/shell/platform/windows/windows_lifecycle_manager.cc @@ -75,26 +75,6 @@ bool WindowsLifecycleManager::WindowProc(HWND hwnd, case WM_DWMCOMPOSITIONCHANGED: engine_->OnDwmCompositionChanged(); break; - - case WM_SIZE: - if (wpar == SIZE_MAXIMIZED || wpar == SIZE_RESTORED) { - OnWindowStateEvent(hwnd, WindowStateEvent::kShow); - } else if (wpar == SIZE_MINIMIZED) { - OnWindowStateEvent(hwnd, WindowStateEvent::kHide); - } - break; - - case WM_SHOWWINDOW: - if (!wpar) { - OnWindowStateEvent(hwnd, WindowStateEvent::kHide); - } else { - OnWindowStateEvent(hwnd, WindowStateEvent::kShow); - } - break; - - case WM_DESTROY: - OnWindowStateEvent(hwnd, WindowStateEvent::kHide); - break; } return false; } @@ -183,108 +163,4 @@ void WindowsLifecycleManager::BeginProcessingClose() { process_close_ = true; } -void WindowsLifecycleManager::SetLifecycleState(AppLifecycleState state) { - if (state_ == state) { - return; - } - state_ = state; - if (engine_) { - const char* state_name = AppLifecycleStateToString(state); - engine_->SendPlatformMessage("flutter/lifecycle", - reinterpret_cast(state_name), - strlen(state_name), nullptr, nullptr); - } -} - -void WindowsLifecycleManager::OnWindowStateEvent(HWND hwnd, - WindowStateEvent event) { - // Synthesize an unfocus event when a focused window is hidden. - if (event == WindowStateEvent::kHide && - focused_windows_.find(hwnd) != focused_windows_.end()) { - OnWindowStateEvent(hwnd, WindowStateEvent::kUnfocus); - } - - std::lock_guard guard(state_update_lock_); - switch (event) { - case WindowStateEvent::kShow: { - bool first_shown_window = visible_windows_.empty(); - auto pair = visible_windows_.insert(hwnd); - if (first_shown_window && pair.second && - state_ == AppLifecycleState::kHidden) { - SetLifecycleState(AppLifecycleState::kInactive); - } - break; - } - case WindowStateEvent::kHide: { - bool present = visible_windows_.erase(hwnd); - bool empty = visible_windows_.empty(); - if (present && empty && - (state_ == AppLifecycleState::kResumed || - state_ == AppLifecycleState::kInactive)) { - SetLifecycleState(AppLifecycleState::kHidden); - } - break; - } - case WindowStateEvent::kFocus: { - bool first_focused_window = focused_windows_.empty(); - auto pair = focused_windows_.insert(hwnd); - if (first_focused_window && pair.second && - state_ == AppLifecycleState::kInactive) { - SetLifecycleState(AppLifecycleState::kResumed); - } - break; - } - case WindowStateEvent::kUnfocus: { - if (focused_windows_.erase(hwnd) && focused_windows_.empty() && - state_ == AppLifecycleState::kResumed) { - SetLifecycleState(AppLifecycleState::kInactive); - } - break; - } - } -} - -std::optional WindowsLifecycleManager::ExternalWindowMessage( - HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam) { - std::optional event = std::nullopt; - - // TODO (schectman): Handle WM_CLOSE messages. - // https://github.com/flutter/flutter/issues/131497 - switch (message) { - case WM_SHOWWINDOW: - event = wparam ? flutter::WindowStateEvent::kShow - : flutter::WindowStateEvent::kHide; - break; - case WM_SIZE: - switch (wparam) { - case SIZE_MINIMIZED: - event = flutter::WindowStateEvent::kHide; - break; - case SIZE_RESTORED: - case SIZE_MAXIMIZED: - event = flutter::WindowStateEvent::kShow; - break; - } - break; - case WM_SETFOCUS: - event = flutter::WindowStateEvent::kFocus; - break; - case WM_KILLFOCUS: - event = flutter::WindowStateEvent::kUnfocus; - break; - case WM_DESTROY: - event = flutter::WindowStateEvent::kHide; - break; - } - - if (event.has_value()) { - OnWindowStateEvent(hwnd, *event); - } - - return std::nullopt; -} - } // namespace flutter diff --git a/shell/platform/windows/windows_lifecycle_manager.h b/shell/platform/windows/windows_lifecycle_manager.h index 2a2ca7a3160c1..b08ec57a4dbd8 100644 --- a/shell/platform/windows/windows_lifecycle_manager.h +++ b/shell/platform/windows/windows_lifecycle_manager.h @@ -9,31 +9,17 @@ #include #include -#include #include -#include - -#include "flutter/shell/platform/common/app_lifecycle_state.h" namespace flutter { class FlutterWindowsEngine; -/// An event representing a change in window state that may update the -// application lifecycle state. -enum class WindowStateEvent { - kShow, - kHide, - kFocus, - kUnfocus, -}; - -/// A manager for lifecycle events of the top-level windows. +/// A manager for lifecycle events of the top-level window. /// -/// WndProc is called for window messages of the top-level Flutter window. -/// ExternalWindowMessage is called for non-flutter top-level window messages. -/// OnWindowStateEvent is called when the visibility or focus state of a window -/// is changed, including the FlutterView window. +/// Currently handles the following events: +/// 1. WM_CLOSE +/// 2. WM_DWMCOMPOSITIONCHANGED class WindowsLifecycleManager { public: WindowsLifecycleManager(FlutterWindowsEngine* engine); @@ -48,43 +34,12 @@ class WindowsLifecycleManager { std::optional lparam, UINT exit_code); - // Intercept top level window WM_CLOSE message and listen to events that may - // update the application lifecycle. + // Intercept top level window messages, only paying attention to WM_CLOSE. bool WindowProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l, LRESULT* result); // Signal to start consuming WM_CLOSE messages. void BeginProcessingClose(); - // Update the app lifecycle state in response to a change in window state. - // When the app lifecycle state actually changes, this sends a platform - // message to the framework notifying it of the state change. - virtual void SetLifecycleState(AppLifecycleState state); - - // Respond to a change in window state. Transitions as follows: - // When the only visible window is hidden, transition from resumed or - // inactive to hidden. - // When the only focused window is unfocused, transition from resumed to - // inactive. - // When a window is focused, transition from inactive to resumed. - // When a window is shown, transition from hidden to inactive. - virtual void OnWindowStateEvent(HWND hwnd, WindowStateEvent event); - - AppLifecycleState GetLifecycleState() { return state_; } - - // Called by the engine when a non-Flutter window receives an event that may - // alter the lifecycle state. The logic for external windows must differ from - // that used for FlutterWindow instances, because: - // - FlutterWindow does not receive WM_SHOW messages, - // - When FlutterWindow receives WM_SIZE messages, wparam stores no meaningful - // information, whereas it usually indicates the action which changed the - // window size. - // When this returns a result, the message has been consumed and should not be - // processed further. Currently, it will always return nullopt. - std::optional ExternalWindowMessage(HWND hwnd, - UINT message, - WPARAM wparam, - LPARAM lparam); - protected: // Check the number of top-level windows associated with this process, and // return true only if there are 1 or fewer. @@ -101,14 +56,6 @@ class WindowsLifecycleManager { std::map, int> sent_close_messages_; bool process_close_; - - std::set visible_windows_; - - std::set focused_windows_; - - std::mutex state_update_lock_; - - flutter::AppLifecycleState state_; }; } // namespace flutter diff --git a/shell/platform/windows/windows_lifecycle_manager_unittests.cc b/shell/platform/windows/windows_lifecycle_manager_unittests.cc deleted file mode 100644 index 6414d0ade78a0..0000000000000 --- a/shell/platform/windows/windows_lifecycle_manager_unittests.cc +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/shell/platform/windows/windows_lifecycle_manager.h" - -#include "flutter/shell/platform/windows/testing/windows_test.h" -#include "gtest/gtest.h" - -namespace flutter { -namespace testing { - -class WindowsLifecycleManagerTest : public WindowsTest {}; - -TEST_F(WindowsLifecycleManagerTest, StateTransitions) { - WindowsLifecycleManager manager(nullptr); - HWND win1 = reinterpret_cast(1); - HWND win2 = reinterpret_cast(2); - - // Hidden to inactive upon window shown. - manager.SetLifecycleState(AppLifecycleState::kHidden); - manager.OnWindowStateEvent(win1, WindowStateEvent::kShow); - EXPECT_EQ(manager.GetLifecycleState(), AppLifecycleState::kInactive); - - // Showing a second window does not change state. - manager.OnWindowStateEvent(win2, WindowStateEvent::kShow); - EXPECT_EQ(manager.GetLifecycleState(), AppLifecycleState::kInactive); - - // Inactive to resumed upon window focus. - manager.OnWindowStateEvent(win2, WindowStateEvent::kFocus); - EXPECT_EQ(manager.GetLifecycleState(), AppLifecycleState::kResumed); - - // Showing a second window does not change state. - manager.OnWindowStateEvent(win1, WindowStateEvent::kFocus); - EXPECT_EQ(manager.GetLifecycleState(), AppLifecycleState::kResumed); - - // Unfocusing one window does not change state while another is focused. - manager.OnWindowStateEvent(win1, WindowStateEvent::kUnfocus); - EXPECT_EQ(manager.GetLifecycleState(), AppLifecycleState::kResumed); - - // Unfocusing final remaining focused window transitions to inactive. - manager.OnWindowStateEvent(win2, WindowStateEvent::kUnfocus); - EXPECT_EQ(manager.GetLifecycleState(), AppLifecycleState::kInactive); - - // Hiding one of two visible windows does not change state. - manager.OnWindowStateEvent(win2, WindowStateEvent::kHide); - EXPECT_EQ(manager.GetLifecycleState(), AppLifecycleState::kInactive); - - // Hiding only visible window transitions to hidden. - manager.OnWindowStateEvent(win1, WindowStateEvent::kHide); - EXPECT_EQ(manager.GetLifecycleState(), AppLifecycleState::kHidden); - - // Transition directly from resumed to hidden when the window is hidden. - manager.OnWindowStateEvent(win1, WindowStateEvent::kShow); - manager.OnWindowStateEvent(win1, WindowStateEvent::kFocus); - manager.OnWindowStateEvent(win1, WindowStateEvent::kHide); - EXPECT_EQ(manager.GetLifecycleState(), AppLifecycleState::kHidden); -} - -} // namespace testing -} // namespace flutter