| // 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_WINDOWS_LIFECYCLE_MANAGER_H_ | |
| #define FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOWS_LIFECYCLE_MANAGER_H_ | |
| #include <Windows.h> | |
| #include <cstdint> | |
| #include <map> | |
| #include <mutex> | |
| #include <optional> | |
| #include <set> | |
| #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. | |
| /// | |
| /// 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. | |
| class WindowsLifecycleManager { | |
| public: | |
| WindowsLifecycleManager(FlutterWindowsEngine* engine); | |
| virtual ~WindowsLifecycleManager(); | |
| // Called when the engine is notified it should quit, e.g. by an application | |
| // call to `exitApplication`. When window is std::nullopt, this quits the | |
| // application. Otherwise, it holds the HWND of the window that initiated the | |
| // request, and exit_code is unused. | |
| virtual void Quit(std::optional<HWND> window, | |
| std::optional<WPARAM> wparam, | |
| std::optional<LPARAM> lparam, | |
| UINT exit_code); | |
| // Intercept top level window WM_CLOSE message and listen to events that may | |
| // update the application lifecycle. | |
| bool WindowProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l, LRESULT* result); | |
| // Signal to start sending lifecycle state update messages. | |
| virtual void BeginProcessingLifecycle(); | |
| // Signal to start consuming WM_CLOSE messages. | |
| virtual void BeginProcessingExit(); | |
| // 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<LRESULT> 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. | |
| virtual bool IsLastWindowOfProcess(); | |
| virtual void DispatchMessage(HWND window, | |
| UINT msg, | |
| WPARAM wparam, | |
| LPARAM lparam); | |
| private: | |
| // Pass top-level window close notifications to the application lifecycle | |
| // logic. If the last window of the process receives WM_CLOSE and a listener | |
| // is registered for WidgetsBindingObserver.didRequestAppExit, the message is | |
| // sent to the framework to query whether the application should be allowed | |
| // to quit. | |
| bool HandleCloseMessage(HWND hwnd, WPARAM wparam, LPARAM lparam); | |
| FlutterWindowsEngine* engine_; | |
| std::map<std::tuple<HWND, WPARAM, LPARAM>, int> sent_close_messages_; | |
| bool process_lifecycle_ = false; | |
| bool process_exit_ = false; | |
| std::set<HWND> visible_windows_; | |
| std::set<HWND> focused_windows_; | |
| std::mutex state_update_lock_; | |
| flutter::AppLifecycleState state_; | |
| }; | |
| } // namespace flutter | |
| #endif // FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOWS_LIFECYCLE_MANAGER_H_ |