blob: fc20b382467fa6b95168cf555b6d683f2ebed5fb [file] [log] [blame]
// 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_