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)]++;
164bool WindowsLifecycleManager::IsLastWindowOfProcess() {
165 DWORD pid = ::GetCurrentProcessId();
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;
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);