Flutter Windows Embedder
host_window_dialog.cc
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 
6 
8 
9 namespace {
10 DWORD GetWindowStyleForDialog(std::optional<HWND> const& owner_window) {
11  DWORD window_style = WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME;
12  if (!owner_window) {
13  // If the dialog has no owner, add a minimize box and a system menu.
14  window_style |= WS_MINIMIZEBOX | WS_SYSMENU;
15  }
16 
17  return window_style;
18 }
19 
20 DWORD GetExtendedWindowStyleForDialog(std::optional<HWND> const& owner_window) {
21  DWORD extended_window_style = WS_EX_DLGMODALFRAME;
22  if (owner_window) {
23  // If the owner window has WS_EX_TOOLWINDOW style, apply the same
24  // style to the dialog.
25  if (GetWindowLongPtr(*owner_window, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) {
26  extended_window_style |= WS_EX_TOOLWINDOW;
27  }
28  }
29  return extended_window_style;
30 }
31 } // namespace
32 
33 namespace flutter {
34 
36  FlutterWindowsEngine* engine,
37  const WindowSizeRequest& preferred_size,
38  const BoxConstraints& constraints,
39  LPCWSTR title,
40  std::optional<HWND> const& owner_window)
41  : HostWindow(
42  window_manager,
43  engine,
45  GetWindowStyleForDialog(owner_window),
46  GetExtendedWindowStyleForDialog(owner_window),
47  constraints,
48  GetInitialRect(engine, preferred_size, constraints, owner_window),
49  title,
50  owner_window) {
51  auto hwnd = window_handle_;
52  if (owner_window == nullptr) {
53  if (HMENU hMenu = GetSystemMenu(hwnd, FALSE)) {
54  EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
55  }
56  }
57 
58  if (owner_window != nullptr) {
59  UpdateModalState();
60  }
61 }
62 
63 Rect HostWindowDialog::GetInitialRect(FlutterWindowsEngine* engine,
64  const WindowSizeRequest& preferred_size,
65  const BoxConstraints& constraints,
66  std::optional<HWND> const& owner_window) {
67  auto const window_style = GetWindowStyleForDialog(owner_window);
68  auto const extended_window_style =
69  GetExtendedWindowStyleForDialog(owner_window);
70  std::optional<Size> const window_size =
72  *engine->windows_proc_table(),
73  Size(preferred_size.preferred_view_width,
74  preferred_size.preferred_view_height),
75  constraints.smallest(), constraints.biggest(), window_style,
76  extended_window_style, owner_window);
77  Point window_origin = {CW_USEDEFAULT, CW_USEDEFAULT};
78  if (owner_window && window_size.has_value()) {
79  // Center dialog in the owner's frame.
80  RECT frame;
81  DwmGetWindowAttribute(*owner_window, DWMWA_EXTENDED_FRAME_BOUNDS, &frame,
82  sizeof(frame));
83  window_origin = {(frame.left + frame.right - window_size->width()) * 0.5,
84  (frame.top + frame.bottom - window_size->height()) * 0.5};
85  }
86 
87  return {window_origin,
88  window_size ? *window_size : Size{CW_USEDEFAULT, CW_USEDEFAULT}};
89 }
90 
92  UINT message,
93  WPARAM wparam,
94  LPARAM lparam) {
95  switch (message) {
96  case WM_DESTROY:
97  is_being_destroyed_ = true;
98  if (HostWindow* const owner_window = GetOwnerWindow()) {
99  UpdateModalState();
100  FocusRootViewOf(owner_window);
101  }
102  break;
103 
104  case WM_ACTIVATE:
105  if (LOWORD(wparam) != WA_INACTIVE) {
106  // Prevent disabled window from being activated using the task
107  // switcher.
108  if (!IsWindowEnabled(hwnd)) {
109  // Redirect focus and activation to the first enabled descendant.
110  if (HostWindow* enabled_descendant = FindFirstEnabledDescendant()) {
111  SetActiveWindow(enabled_descendant->GetWindowHandle());
112  FocusRootViewOf(this);
113  }
114  return 0;
115  }
116  FocusRootViewOf(this);
117  }
118  return 0;
119  }
120 
121  return HostWindow::HandleMessage(hwnd, message, wparam, lparam);
122 }
123 
124 void HostWindowDialog::UpdateModalState() {
125  // Find the root window of the window hierarchy and process
126  // modal state update for the entire branch.
127  HostWindow* root = this;
128  while (HostWindow* const owner = root->GetOwnerWindow()) {
129  root = owner;
130  }
131  root->UpdateModalStateLayer();
132 }
133 
135  bool fullscreen,
136  std::optional<FlutterEngineDisplayId> display_id) {}
137 
139  return false;
140 }
141 
142 } // namespace flutter
std::shared_ptr< WindowsProcTable > windows_proc_table()
HostWindowDialog(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowSizeRequest &preferred_size, const BoxConstraints &constraints, LPCWSTR title, std::optional< HWND > const &owner_window)
bool GetFullscreen() const override
void SetFullscreen(bool fullscreen, std::optional< FlutterEngineDisplayId > display_id) override
LRESULT HandleMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) override
HostWindow * GetOwnerWindow() const
Definition: host_window.cc:817
void UpdateModalStateLayer()
Definition: host_window.cc:833
static void FocusRootViewOf(HostWindow *window)
Definition: host_window.cc:346
virtual LRESULT HandleMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
Definition: host_window.cc:370
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:725
HostWindow * FindFirstEnabledDescendant() const
Definition: host_window.cc:780
Win32Message message
WindowArchetype
Definition: windowing.h:11