12#include "flutter/shell/platform/windows/flutter_windows_engine.h"
22 std::optional<WPARAM> wparam,
23 std::optional<LPARAM> lparam,
25 if (!hwnd.has_value()) {
26 ::PostQuitMessage(exit_code);
28 BASE_CHECK(wparam.has_value() && lparam.has_value());
29 sent_close_messages_[std::make_tuple(*hwnd, *wparam, *lparam)]++;
41bool WindowsLifecycleManager::HandleCloseMessage(HWND hwnd,
47 auto key = std::make_tuple(hwnd, wparam, lparam);
48 auto itr = sent_close_messages_.find(
key);
49 if (itr != sent_close_messages_.end()) {
50 if (itr->second == 1) {
51 sent_close_messages_.erase(itr);
53 sent_close_messages_[
key]--;
76 return HandleCloseMessage(hwnd, wpar, lpar);
80 case WM_DWMCOMPOSITIONCHANGED:
85 if (wpar == SIZE_MAXIMIZED || wpar == SIZE_RESTORED) {
87 }
else if (wpar == SIZE_MINIMIZED) {
110 thread_snapshot_ = ::CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
114 ::CloseHandle(thread_snapshot_);
123 THREADENTRY32 thread;
124 thread.dwSize =
sizeof(thread);
125 if (!::Thread32First(thread_snapshot_, &thread)) {
129 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
130 error_num, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), msg, 256,
132 FML_LOG(
ERROR) <<
"Failed to get thread(" << error_num <<
"): " << msg;
142 return ::Thread32Next(thread_snapshot_, &thread);
150 int64_t num_windows = 0;
153 [](HWND hwnd,
LPARAM lparam) {
154 int64_t* windows_ptr = reinterpret_cast<int64_t*>(lparam);
155 if (::GetParent(hwnd) == nullptr) {
160 reinterpret_cast<LPARAM>(&num_windows));
164bool WindowsLifecycleManager::IsLastWindowOfProcess() {
167 std::optional<THREADENTRY32> first_thread = thread_snapshot.
GetFirstThread();
168 if (!first_thread.has_value()) {
174 THREADENTRY32 thread = *first_thread;
176 if (thread.th32OwnerProcessID == pid) {
178 if (num_windows > 1) {
184 return num_windows <= 1;
187void WindowsLifecycleManager::BeginProcessingLifecycle() {
188 process_lifecycle_ =
true;
191void WindowsLifecycleManager::BeginProcessingExit() {
192 process_exit_ =
true;
196 if (state_ ==
state) {
200 if (engine_ && process_lifecycle_) {
202 engine_->SendPlatformMessage(
"flutter/lifecycle",
203 reinterpret_cast<const uint8_t*
>(state_name),
204 strlen(state_name),
nullptr,
nullptr);
208void WindowsLifecycleManager::OnWindowStateEvent(HWND hwnd,
211 if (
event == WindowStateEvent::kHide &&
212 focused_windows_.find(hwnd) != focused_windows_.end()) {
213 OnWindowStateEvent(hwnd, WindowStateEvent::kUnfocus);
216 std::lock_guard guard(state_update_lock_);
218 case WindowStateEvent::kShow: {
219 bool first_shown_window = visible_windows_.empty();
220 auto pair = visible_windows_.insert(hwnd);
221 if (first_shown_window && pair.second &&
222 state_ == AppLifecycleState::kHidden) {
223 SetLifecycleState(AppLifecycleState::kInactive);
227 case WindowStateEvent::kHide: {
228 bool present = visible_windows_.erase(hwnd);
229 bool empty = visible_windows_.empty();
230 if (present &&
empty &&
231 (state_ == AppLifecycleState::kResumed ||
232 state_ == AppLifecycleState::kInactive)) {
233 SetLifecycleState(AppLifecycleState::kHidden);
237 case WindowStateEvent::kFocus: {
238 bool first_focused_window = focused_windows_.empty();
239 auto pair = focused_windows_.insert(hwnd);
240 if (first_focused_window && pair.second &&
241 state_ == AppLifecycleState::kInactive) {
242 SetLifecycleState(AppLifecycleState::kResumed);
246 case WindowStateEvent::kUnfocus: {
247 if (focused_windows_.erase(hwnd) && focused_windows_.empty() &&
248 state_ == AppLifecycleState::kResumed) {
249 SetLifecycleState(AppLifecycleState::kInactive);
256std::optional<LRESULT> WindowsLifecycleManager::ExternalWindowMessage(
261 std::optional<flutter::WindowStateEvent>
event = std::nullopt;
291 if (HandleCloseMessage(hwnd, wparam, lparam)) {
297 if (
event.has_value()) {
298 OnWindowStateEvent(hwnd, *
event);
void OnDwmCompositionChanged()
void RequestApplicationQuit(HWND hwnd, WPARAM wparam, LPARAM lparam, AppExitType exit_type)
std::optional< THREADENTRY32 > GetFirstThread()
bool GetNextThread(THREADENTRY32 &thread)
virtual void OnWindowStateEvent(HWND hwnd, WindowStateEvent event)
WindowsLifecycleManager(FlutterWindowsEngine *engine)
virtual ~WindowsLifecycleManager()
bool WindowProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l, LRESULT *result)
virtual void Quit(std::optional< HWND > window, std::optional< WPARAM > wparam, std::optional< LPARAM > lparam, UINT exit_code)
virtual void DispatchMessage(HWND window, UINT msg, WPARAM wparam, LPARAM lparam)
virtual bool IsLastWindowOfProcess()
EMSCRIPTEN_KEEPALIVE void empty()
#define FML_LOG(severity)
static zx_koid_t GetCurrentProcessId()
constexpr const char * AppLifecycleStateToString(AppLifecycleState state)
static int64_t NumWindowsForThread(const THREADENTRY32 &thread)
WindowStateEvent
An event representing a change in window state that may update the.
#define BASE_CHECK(condition)
#define INVALID_HANDLE_VALUE
WINBASEAPI _Check_return_ _Post_equals_last_error_ DWORD WINAPI GetLastError(VOID)