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(window_manager, engine) {
44  .window_style = GetWindowStyleForDialog(owner_window),
45  .extended_window_style = GetExtendedWindowStyleForDialog(owner_window),
46  .box_constraints = constraints,
47  .initial_window_rect =
48  GetInitialRect(engine, preferred_size, constraints, owner_window),
49  .title = title,
50  .owner_window = owner_window,
51  });
52  auto hwnd = window_handle_;
53  if (owner_window == nullptr) {
54  if (HMENU hMenu = GetSystemMenu(hwnd, FALSE)) {
55  EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
56  }
57  }
58 
59  if (owner_window != nullptr) {
60  UpdateModalState();
61  }
62 }
63 
64 Rect HostWindowDialog::GetInitialRect(FlutterWindowsEngine* engine,
65  const WindowSizeRequest& preferred_size,
66  const BoxConstraints& constraints,
67  std::optional<HWND> const& owner_window) {
68  auto const window_style = GetWindowStyleForDialog(owner_window);
69  auto const extended_window_style =
70  GetExtendedWindowStyleForDialog(owner_window);
71  std::optional<Size> const window_size =
73  *engine->windows_proc_table(),
74  Size(preferred_size.preferred_view_width,
75  preferred_size.preferred_view_height),
76  constraints.smallest(), constraints.biggest(), window_style,
77  extended_window_style, owner_window);
78  Point window_origin = {CW_USEDEFAULT, CW_USEDEFAULT};
79  if (owner_window && window_size.has_value()) {
80  // Center dialog in the owner's frame.
81  RECT frame;
82  DwmGetWindowAttribute(*owner_window, DWMWA_EXTENDED_FRAME_BOUNDS, &frame,
83  sizeof(frame));
84  window_origin = {(frame.left + frame.right - window_size->width()) * 0.5,
85  (frame.top + frame.bottom - window_size->height()) * 0.5};
86  }
87 
88  return {window_origin,
89  window_size ? *window_size : Size{CW_USEDEFAULT, CW_USEDEFAULT}};
90 }
91 
93  UINT message,
94  WPARAM wparam,
95  LPARAM lparam) {
96  switch (message) {
97  case WM_DESTROY:
98  is_being_destroyed_ = true;
99  if (HostWindow* const owner_window = GetOwnerWindow()) {
100  UpdateModalState();
101  FocusRootViewOf(owner_window);
102  }
103  break;
104 
105  case WM_ACTIVATE:
106  if (LOWORD(wparam) != WA_INACTIVE) {
107  // Prevent disabled window from being activated using the task
108  // switcher.
109  if (!IsWindowEnabled(hwnd)) {
110  // Redirect focus and activation to the first enabled descendant.
111  if (HostWindow* enabled_descendant = FindFirstEnabledDescendant()) {
112  SetActiveWindow(enabled_descendant->GetWindowHandle());
113  FocusRootViewOf(this);
114  }
115  return 0;
116  }
117  FocusRootViewOf(this);
118  }
119  return 0;
120  }
121 
122  return HostWindow::HandleMessage(hwnd, message, wparam, lparam);
123 }
124 
125 void HostWindowDialog::UpdateModalState() {
126  // Find the root window of the window hierarchy and process
127  // modal state update for the entire branch.
128  HostWindow* root = this;
129  while (HostWindow* const owner = root->GetOwnerWindow()) {
130  root = owner;
131  }
132  root->UpdateModalStateLayer();
133 }
134 
136  bool fullscreen,
137  std::optional<FlutterEngineDisplayId> display_id) {}
138 
140  return false;
141 }
142 
143 } // 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
void InitializeFlutterView(HostWindowInitializationParams const &params)
Definition: host_window.cc:245
HostWindow * GetOwnerWindow() const
Definition: host_window.cc:829
void UpdateModalStateLayer()
Definition: host_window.cc:845
static void FocusRootViewOf(HostWindow *window)
Definition: host_window.cc:358
virtual LRESULT HandleMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
Definition: host_window.cc:382
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:737
HostWindow * FindFirstEnabledDescendant() const
Definition: host_window.cc:792
Win32Message message