Flutter Windows Embedder
windows_lifecycle_manager.h
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOWS_LIFECYCLE_MANAGER_H_
6 #define FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOWS_LIFECYCLE_MANAGER_H_
7 
8 #include <Windows.h>
9 
10 #include <cstdint>
11 #include <map>
12 #include <mutex>
13 #include <optional>
14 #include <set>
15 
17 
18 namespace flutter {
19 
20 class FlutterWindowsEngine;
21 
22 /// An event representing a change in window state that may update the
23 // application lifecycle state.
24 enum class WindowStateEvent {
25  kShow,
26  kHide,
27  kFocus,
28  kUnfocus,
29 };
30 
31 /// A manager for lifecycle events of the top-level windows.
32 ///
33 /// WndProc is called for window messages of the top-level Flutter window.
34 /// ExternalWindowMessage is called for non-flutter top-level window messages.
35 /// OnWindowStateEvent is called when the visibility or focus state of a window
36 /// is changed, including the FlutterView window.
38  public:
40  virtual ~WindowsLifecycleManager();
41 
42  // Called when the engine is notified it should quit, e.g. by an application
43  // call to `exitApplication`. When window is std::nullopt, this quits the
44  // application. Otherwise, it holds the HWND of the window that initiated the
45  // request, and exit_code is unused.
46  virtual void Quit(std::optional<HWND> window,
47  std::optional<WPARAM> wparam,
48  std::optional<LPARAM> lparam,
49  UINT exit_code);
50 
51  // Intercept top level window WM_CLOSE message and listen to events that may
52  // update the application lifecycle.
53  bool WindowProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l, LRESULT* result);
54 
55  // Signal to start sending lifecycle state update messages.
56  virtual void BeginProcessingLifecycle();
57 
58  // Signal to start consuming WM_CLOSE messages.
59  virtual void BeginProcessingExit();
60 
61  // Update the app lifecycle state in response to a change in window state.
62  // When the app lifecycle state actually changes, this sends a platform
63  // message to the framework notifying it of the state change.
64  virtual void SetLifecycleState(AppLifecycleState state);
65 
66  // Respond to a change in window state.
67  // Saves the state for the HWND and schedules UpdateState to be called
68  // if it is not already scheduled.
69  virtual void OnWindowStateEvent(HWND hwnd, WindowStateEvent event);
70 
71  AppLifecycleState GetLifecycleState() { return state_; }
72 
73  // Used in tests to wait until the state is updated.
74  bool IsUpdateStateScheduled() const { return update_state_scheduled_; }
75 
76  // Called by the engine when a non-Flutter window receives an event that may
77  // alter the lifecycle state. The logic for external windows must differ from
78  // that used for FlutterWindow instances, because:
79  // - FlutterWindow does not receive WM_SHOW messages,
80  // - When FlutterWindow receives WM_SIZE messages, wparam stores no meaningful
81  // information, whereas it usually indicates the action which changed the
82  // window size.
83  // When this returns a result, the message has been consumed and should not be
84  // processed further. Currently, it will always return nullopt.
85  std::optional<LRESULT> ExternalWindowMessage(HWND hwnd,
86  UINT message,
87  WPARAM wparam,
88  LPARAM lparam);
89 
90  protected:
91  // Check the number of top-level windows associated with this process, and
92  // return true only if there are 1 or fewer.
93  virtual bool IsLastWindowOfProcess();
94 
95  virtual void DispatchMessage(HWND window,
96  UINT msg,
97  WPARAM wparam,
98  LPARAM lparam);
99 
100  private:
101  // Pass top-level window close notifications to the application lifecycle
102  // logic. If the last window of the process receives WM_CLOSE and a listener
103  // is registered for WidgetsBindingObserver.didRequestAppExit, the message is
104  // sent to the framework to query whether the application should be allowed
105  // to quit.
106  bool HandleCloseMessage(HWND hwnd, WPARAM wparam, LPARAM lparam);
107 
108  FlutterWindowsEngine* engine_;
109 
110  std::map<std::tuple<HWND, WPARAM, LPARAM>, int> sent_close_messages_;
111 
112  bool process_lifecycle_ = false;
113  bool process_exit_ = false;
114 
115  std::set<HWND> visible_windows_;
116  std::set<HWND> focused_windows_;
117 
118  // Transitions the application state. If any windows are focused,
119  // the application is considered resumed. If no windows are focused
120  // but there are visible windows, application is considered inactive.
121  // Otherwise, if there are no visible window, application is considered
122  // hidden.
123  void UpdateState();
124 
125  // Whether update state is scheduled to be called in next run loop turn.
126  // This is needed to provide atomic updates of the state.
127  bool update_state_scheduled_ = false;
128 
130 };
131 
132 } // namespace flutter
133 
134 #endif // FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOWS_LIFECYCLE_MANAGER_H_
virtual void OnWindowStateEvent(HWND hwnd, WindowStateEvent event)
std::optional< LRESULT > ExternalWindowMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
WindowsLifecycleManager(FlutterWindowsEngine *engine)
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 void SetLifecycleState(AppLifecycleState state)
Win32Message message
WindowStateEvent
An event representing a change in window state that may update the.