Flutter Windows Embedder
host_window.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_HOST_WINDOW_H_
6 #define FLUTTER_SHELL_PLATFORM_WINDOWS_HOST_WINDOW_H_
7 
8 #include <shobjidl.h>
9 #include <windows.h>
10 #include <wrl/client.h>
11 #include <memory>
12 #include <optional>
13 #include <string>
14 
15 #include "flutter/fml/macros.h"
16 #include "flutter/shell/geometry/geometry.h"
19 
20 namespace flutter {
21 
22 class WindowManager;
23 class WindowsProcTable;
24 class FlutterWindowsView;
25 class FlutterWindowsViewSizingDelegate;
26 class FlutterWindowsViewController;
27 
28 // A Win32 window that hosts a |FlutterWindow| in its client area.
29 class HostWindow {
30  public:
31  virtual ~HostWindow();
32 
33  // Creates a regular Win32 window with a child view confined to its client
34  // area. |window_manager| is a pointer to the window manager that manages the
35  // |HostWindow|. |engine| is a pointer to the engine that manages
36  // the window manager. |preferred_size| is the preferred size of the window.
37  // |preferred_constraints| are the constraints set on the window's size.
38  // |title| is the title of the window.
39  //
40  // On success, a valid window handle can be retrieved
41  // via |HostWindow::GetWindowHandle|. |nullptr| will be returned
42  // on failure.
43  static std::unique_ptr<HostWindow> CreateRegularWindow(
44  WindowManager* window_manager,
45  FlutterWindowsEngine* engine,
46  const WindowSizeRequest& preferred_size,
47  const WindowConstraints& preferred_constraints,
48  LPCWSTR title,
49  bool sized_to_content,
50  bool resizable);
51 
52  // Creates a dialog Win32 window with a child view confined to its client
53  // area. |window_manager| is a pointer to the window manager that manages the
54  // |HostWindow|. |engine| is a pointer to the engine that manages
55  // the window manager. |preferred_size| is the preferred size of the window.
56  // |preferred_constraints| are the constraints set on the window's size.
57  // |title| is the title of the window. |parent| is the parent of this dialog,
58  // which can be `nullptr`.
59  //
60  // On success, a valid window handle can be retrieved
61  // via |HostWindow::GetWindowHandle|. `nullptr` will be returned
62  // on failure.
63  static std::unique_ptr<HostWindow> CreateDialogWindow(
64  WindowManager* window_manager,
65  FlutterWindowsEngine* engine,
66  const WindowSizeRequest& preferred_size,
67  const WindowConstraints& preferred_constraints,
68  LPCWSTR title,
69  HWND parent,
70  bool sized_to_content,
71  bool resizable);
72 
73  // Creates a tooltip Win32 window with a child view confined to its client
74  // area. |window_manager| is a pointer to the window manager that manages the
75  // |HostWindow|. |engine| is a pointer to the engine that manages
76  // the window manager. |preferred_constraints| are the constraints set on
77  // the window's size. |get_position_callback| is a callback
78  // that determines the position of the tooltip window. It is invoked on the
79  // platform thread whenever the rendered content size of the tooltip changes,
80  // including after the initial frame is rendered and on any subsequent content
81  // resize. It is not called in response to parent window movement or other
82  // Win32 window messages. |parent| is the parent of this tooltip, which must
83  // be non-null.
84  static std::unique_ptr<HostWindow> CreateTooltipWindow(
85  WindowManager* window_manager,
86  FlutterWindowsEngine* engine,
87  const WindowConstraints& preferred_constraints,
88  GetWindowPositionCallback get_position_callback,
89  HWND parent);
90 
91  // Creates a popup Win32 window with a child view confined to its client
92  // area. |window_manager| is a pointer to the window manager that manages the
93  // |HostWindow|. |engine| is a pointer to the engine that manages
94  // the window manager. |preferred_constraints| are the constraints set on
95  // the window's size. |get_position_callback| is a callback that determines
96  // the position of the popup window. It is invoked on the platform thread
97  // whenever the rendered content size of the popup changes, including after
98  // the initial frame is rendered and on any subsequent content resize. It is
99  // not called in response to parent window movement or other Win32 window
100  // messages. |parent| is the parent of this popup, which must be non-null.
101  static std::unique_ptr<HostWindow> CreatePopupWindow(
102  WindowManager* window_manager,
103  FlutterWindowsEngine* engine,
104  const WindowConstraints& preferred_constraints,
105  GetWindowPositionCallback get_position_callback,
106  HWND parent);
107 
108  // Returns the instance pointer for |hwnd| or nullptr if invalid.
109  static HostWindow* GetThisFromHandle(HWND hwnd);
110 
111  // Returns the backing window handle, or nullptr if the native window is not
112  // created or has already been destroyed.
113  HWND GetWindowHandle() const;
114 
115  // Returns the HWND of the FlutterView hosted in this window.
116  HWND GetFlutterViewWindowHandle() const;
117 
118  // Resizes the window to accommodate a client area of the given
119  // |size|. If the size does not satisfy the constraints, the window will be
120  // resized to the minimum or maximum size as appropriate.
121  void SetContentSize(const WindowSizeRequest& size);
122 
123  // Sets the constaints on the client area of the window.
124  // If the current window size does not satisfy the new constraints,
125  // the window will be resized to satisy thew new constraints.
126  void SetConstraints(const WindowConstraints& constraints);
127 
128  // Set the fullscreen state. |display_id| indicates the display where
129  // the window should be shown fullscreen; std::nullopt indicates
130  // that no display was specified, so the current display may be used.
131  virtual void SetFullscreen(bool fullscreen,
132  std::optional<FlutterEngineDisplayId> display_id);
133 
134  // Returns |true| if this window is fullscreen, otherwise |false|.
135  virtual bool GetFullscreen() const;
136 
137  // Given a window identifier, returns the window content size of the
138  // window.
139  static ActualWindowSize GetWindowContentSize(HWND hwnd);
140 
141  // Returns the owner window, or nullptr if none.
142  HostWindow* GetOwnerWindow() const;
143 
144  // This method is called when a dialog is created or destroyed.
145  // It walks the path of child windows to make sure that the right
146  // windows are enabled or disabled.
147  void UpdateModalStateLayer();
148 
149  protected:
154  const BoxConstraints& box_constraints;
156  LPCWSTR title;
157  std::optional<HWND> const& owner_window;
158  int nCmdShow = SW_SHOWNORMAL;
160  bool is_sized_to_content = false;
161  };
162 
163  // Initialize the underlying native window and the Flutter view.
164  //
165  // See:
166  // - https://learn.microsoft.com/windows/win32/winmsg/window-styles
167  // - https://learn.microsoft.com/windows/win32/winmsg/extended-window-styles
169 
171 
172  // Information saved before going into fullscreen mode, used to restore the
173  // window afterwards.
175  LONG style;
176  LONG ex_style;
177  RECT rect;
179  int dpi;
180  HMONITOR monitor;
181  MONITORINFO monitor_info;
182  };
183 
184  // Construct a host window.
185  //
186  // Derived classes should call InitializeFlutterView() after construction to
187  // set up the native window and the Flutter view.
188  HostWindow(WindowManager* window_manager, FlutterWindowsEngine* engine);
189 
190  // Calculates the required window size, in physical coordinates, to
191  // accommodate the given |client_size|, in logical coordinates, constrained by
192  // optional |smallest| and |biggest|, for a window with the specified
193  // |window_style| and |extended_window_style|. If |owner_hwnd| is not null,
194  // the DPI of the display with the largest area of intersection with
195  // |owner_hwnd| is used for the calculation; otherwise, the primary display's
196  // DPI is used. The resulting size includes window borders, non-client areas,
197  // and drop shadows. On error, returns std::nullopt and logs an error message.
198  static std::optional<Size> GetWindowSizeForClientSize(
199  WindowsProcTable const& win32,
200  Size const& client_size,
201  std::optional<Size> smallest,
202  std::optional<Size> biggest,
203  DWORD window_style,
204  DWORD extended_window_style,
205  std::optional<HWND> const& owner_hwnd);
206 
207  // Processes and routes salient window messages for mouse handling,
208  // size change and DPI. Delegates handling of these to member overloads that
209  // inheriting classes can handle.
210  virtual LRESULT HandleMessage(HWND hwnd,
211  UINT message,
212  WPARAM wparam,
213  LPARAM lparam);
214 
215  // Sets the focus to the child view window of |window|.
216  static void FocusRootViewOf(HostWindow* window);
217 
218  // Handles a WM_ACTIVATE message for |hwnd| with the given |wparam|. When the
219  // window is being activated, focus its view; if the window is disabled
220  // (e.g. it owns a modal dialog), activation is instead redirected to the
221  // first enabled descendant. Does nothing when the window is being
222  // deactivated, so that a deactivated window does not reactivate itself and
223  // jump back to the top of the z-order.
224  void HandleWindowActivation(HWND hwnd, WPARAM wparam);
225 
226  // Enables or disables mouse and keyboard input to this window and all its
227  // descendants.
228  void EnableRecursively(bool enable);
229 
230  // Returns the first enabled descendant window. If the current window itself
231  // is enabled, returns the current window. If no window is enabled, returns
232  // `nullptr`.
234 
235  // Returns the archetype of this window.
237 
238  // Returns windows owned by this window.
239  std::vector<HostWindow*> GetOwnedWindows() const;
240 
241  // Disables mouse and keyboard input to the window and all its descendants.
242  void DisableRecursively();
243 
244  // OS callback called by message pump. Handles the WM_NCCREATE message which
245  // is passed when the non-client area is being created and enables automatic
246  // non-client DPI scaling so that the non-client area automatically
247  // responds to changes in DPI. Delegates other messages to the controller.
248  static LRESULT WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam);
249 
250  // Controller for this window.
251  WindowManager* const window_manager_ = nullptr;
252 
253  // The Flutter engine that owns this window.
255 
256  // Controller for the view hosted in this window. Value-initialized if the
257  // window is created from an existing top-level native window created by the
258  // runner.
259  std::unique_ptr<FlutterWindowsViewController> view_controller_;
260 
261  // The window archetype.
263 
264  // Backing handle for this window.
266 
267  // The constraints on the window's client area.
268  BoxConstraints box_constraints_;
269 
270  // True while handling WM_DESTROY; used to detect in-progress destruction.
271  bool is_being_destroyed_ = false;
272 
273  // Whether or not the window is currently in a fullscreen state.
274  bool is_fullscreen_ = false;
275 
276  // Saved window information from before entering fullscreen mode.
278 
279  // Used to mark a window as fullscreen.
280  Microsoft::WRL::ComPtr<ITaskbarList2> task_bar_list_;
281 
283 };
284 
285 } // namespace flutter
286 
287 #endif // FLUTTER_SHELL_PLATFORM_WINDOWS_HOST_WINDOW_H_
Microsoft::WRL::ComPtr< ITaskbarList2 > task_bar_list_
Definition: host_window.h:280
HWND GetWindowHandle() const
Definition: host_window.cc:341
BoxConstraints box_constraints_
Definition: host_window.h:268
static std::unique_ptr< HostWindow > CreatePopupWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowConstraints &preferred_constraints, GetWindowPositionCallback get_position_callback, HWND parent)
Definition: host_window.cc:217
static std::unique_ptr< HostWindow > CreateDialogWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowSizeRequest &preferred_size, const WindowConstraints &preferred_constraints, LPCWSTR title, HWND parent, bool sized_to_content, bool resizable)
Definition: host_window.cc:191
WindowArchetype archetype_
Definition: host_window.h:262
void InitializeFlutterView(HostWindowInitializationParams const &params)
Definition: host_window.cc:232
void HandleWindowActivation(HWND hwnd, WPARAM wparam)
Definition: host_window.cc:356
SavedWindowInfo saved_window_info_
Definition: host_window.h:277
FML_DISALLOW_COPY_AND_ASSIGN(HostWindow)
std::unique_ptr< FlutterWindowsViewController > view_controller_
Definition: host_window.h:259
static LRESULT WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
Definition: host_window.cc:380
HostWindow * GetOwnerWindow() const
Definition: host_window.cc:843
static std::unique_ptr< HostWindow > CreateTooltipWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowConstraints &preferred_constraints, GetWindowPositionCallback get_position_callback, HWND parent)
Definition: host_window.cc:206
static ActualWindowSize GetWindowContentSize(HWND hwnd)
Definition: host_window.cc:738
void EnableRecursively(bool enable)
Definition: host_window.cc:798
void SetContentSize(const WindowSizeRequest &size)
Definition: host_window.cc:505
void UpdateModalStateLayer()
Definition: host_window.cc:859
static std::unique_ptr< HostWindow > CreateRegularWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowSizeRequest &preferred_size, const WindowConstraints &preferred_constraints, LPCWSTR title, bool sized_to_content, bool resizable)
Definition: host_window.cc:177
static void FocusRootViewOf(HostWindow *window)
Definition: host_window.cc:349
HWND GetFlutterViewWindowHandle() const
Definition: host_window.cc:345
FlutterWindowsEngine * engine_
Definition: host_window.h:254
static HostWindow * GetThisFromHandle(HWND hwnd)
Definition: host_window.cc:326
HostWindow(WindowManager *window_manager, FlutterWindowsEngine *engine)
Definition: host_window.cc:228
std::vector< HostWindow * > GetOwnedWindows() const
Definition: host_window.cc:820
WindowArchetype GetArchetype() const
Definition: host_window.h:236
virtual bool GetFullscreen() const
Definition: host_window.cc:734
void SetConstraints(const WindowConstraints &constraints)
Definition: host_window.cc:547
virtual void SetFullscreen(bool fullscreen, std::optional< FlutterEngineDisplayId > display_id)
Definition: host_window.cc:588
virtual LRESULT HandleMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
Definition: host_window.cc:396
static std::optional< Size > GetWindowSizeForClientSize(WindowsProcTable const &win32, Size const &client_size, std::optional< Size > smallest, std::optional< Size > biggest, DWORD window_style, DWORD extended_window_style, std::optional< HWND > const &owner_hwnd)
Definition: host_window.cc:751
HostWindow * FindFirstEnabledDescendant() const
Definition: host_window.cc:806
WindowManager *const window_manager_
Definition: host_window.h:251
Win32Message message
WindowRect *(* GetWindowPositionCallback)(const WindowSize &child_size, const WindowRect &parent_rect, const WindowRect &output_rect)
WindowArchetype
Definition: windowing.h:11
FlutterWindowsViewSizingDelegate * sizing_delegate
Definition: host_window.h:159