| Flutter Windows Embedder |

Public Member Functions | Static Public Member Functions | List of all members
flutter::HostWindow Class Reference

`#include <host_window.h>`

## Public Member Functions
virtual | ~HostWindow ()
HWND | GetWindowHandle () const
void | SetContentSize (const WindowSizing &size)

## Static Public Member Functions
static std::unique_ptr< HostWindow > | CreateRegularWindow (WindowManager *controller, FlutterWindowsEngine *engine, const WindowSizing &content_size)
static HostWindow * | GetThisFromHandle (HWND hwnd)

## Detailed Description

Definition at line 24 of file host_window.h.

## Constructor & Destructor Documentation

## ◆ ~HostWindow()

flutter::HostWindow::~HostWindow | ( |  | ) |
| virtual

Definition at line 332 of file host_window.cc.

332 {
333 if (view_controller_) {
334 // Unregister the window class. Fail silently if other windows are still
335 // using the class, as only the last window can successfully unregister it.
336 if (!UnregisterClass(kWindowClassName, GetModuleHandle(nullptr))) {
337 // Clear the error state after the failed unregistration.
338 SetLastError(ERROR_SUCCESS);
339 }
340 }
341 }

## Member Function Documentation

## ◆ CreateRegularWindow()

std::unique_ptr< HostWindow > flutter::HostWindow::CreateRegularWindow | ( | WindowManager * | controller,
|  | FlutterWindowsEngine * | engine,
|  | const WindowSizing & | content_size
| ) |  |
| static

Definition at line 200 of file host_window.cc.

203 {
204 DWORD window_style = WS_OVERLAPPEDWINDOW;
205 DWORD extended_window_style = 0;
206 std::optional<Size> smallest = std::nullopt;
207 std::optional<Size> biggest = std::nullopt;
208
209 if (content_size.has_view_constraints) {
210 smallest = Size(content_size.view_min_width, content_size.view_min_height);
211 if (content_size.view_max_width > 0 && content_size.view_max_height > 0) {
212 biggest = Size(content_size.view_max_width, content_size.view_max_height);
213 }
214 }
215
216 // TODO(knopp): What about windows sized to content?
217 FML_CHECK(content_size.has_preferred_view_size);
218
219 // Calculate the screen space window rectangle for the new window.
220 // Default positioning values (CW_USEDEFAULT) are used
221 // if the window has no owner.
222 Rect const initial_window_rect = [&]() -> Rect {
223 std::optional<Size> const window_size = GetWindowSizeForClientSize(
224 *engine->windows_proc_table(),
225 Size(content_size.preferred_view_width,
226 content_size.preferred_view_height),
227 smallest, biggest, window_style, extended_window_style, nullptr);
228 return {{CW_USEDEFAULT, CW_USEDEFAULT},
229 window_size ? *window_size : Size{CW_USEDEFAULT, CW_USEDEFAULT}};
230 }();
231
232 // Set up the view.
233 auto view_window = std::make_unique<FlutterWindow>(
234 initial_window_rect.width(), initial_window_rect.height(),
235 engine->windows_proc_table());
236
237 std::unique_ptr<FlutterWindowsView> view =
238 engine->CreateView(std::move(view_window));
239 if (view == nullptr) {
240 FML_LOG(ERROR) << "Failed to create view";
241 return nullptr;
242 }
243
244 std::unique_ptr<FlutterWindowsViewController> view_controller =
245 std::make_unique<FlutterWindowsViewController>(nullptr, std::move(view));
246 FML_CHECK(engine->running());
247 // The Windows embedder listens to accessibility updates using the
248 // view's HWND. The embedder's accessibility features may be stale if
249 // the app was in headless mode.
250 engine->UpdateAccessibilityFeatures();
251
252 // Register the window class.
253 if (!IsClassRegistered(kWindowClassName)) {
254 auto const idi_app_icon = 101;
255 WNDCLASSEX window_class = {};
256 window_class.cbSize = sizeof(WNDCLASSEX);
257 window_class.style = CS_HREDRAW | CS_VREDRAW;
258 window_class.lpfnWndProc = HostWindow::WndProc;
259 window_class.hInstance = GetModuleHandle(nullptr);
260 window_class.hIcon =
261 LoadIcon(window_class.hInstance, MAKEINTRESOURCE(idi_app_icon));
262 if (!window_class.hIcon) {
263 window_class.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
264 }
265 window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
266 window_class.lpszClassName = kWindowClassName;
267
268 if (!RegisterClassEx(&window_class)) {
269 FML_LOG(ERROR) << "Cannot register window class " << kWindowClassName
270 << ": " << GetLastErrorAsString();
271 return nullptr;
272 }
273 }
274
275 // Create the native window.
276 HWND hwnd = CreateWindowEx(
277 extended_window_style, kWindowClassName, L"", window_style,
278 initial_window_rect.left(), initial_window_rect.top(),
279 initial_window_rect.width(), initial_window_rect.height(), nullptr,
280 nullptr, GetModuleHandle(nullptr), engine->windows_proc_table().get());
281 if (!hwnd) {
282 FML_LOG(ERROR) << "Cannot create window: " << GetLastErrorAsString();
283 return nullptr;
284 }
285
286 // Adjust the window position so its origin aligns with the top-left corner
287 // of the window frame, not the window rectangle (which includes the
288 // drop-shadow). This adjustment must be done post-creation since the frame
289 // rectangle is only available after the window has been created.
290 RECT frame_rect;
291 DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &frame_rect,
292 sizeof(frame_rect));
293 RECT window_rect;
294 GetWindowRect(hwnd, &window_rect);
295 LONG const left_dropshadow_width = frame_rect.left - window_rect.left;
296 LONG const top_dropshadow_height = window_rect.top - frame_rect.top;
297 SetWindowPos(hwnd, nullptr, window_rect.left - left_dropshadow_width,
298 window_rect.top - top_dropshadow_height, 0, 0,
299 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
300
301 UpdateTheme(hwnd);
302
303 SetChildContent(view_controller->view()->GetWindowHandle(), hwnd);
304
305 // TODO(loicsharma): Hide the window until the first frame is rendered.
306 // Single window apps use the engine's next frame callback to show the
307 // window. This doesn't work for multi window apps as the engine cannot have
308 // multiple next frame callbacks. If multiple windows are created, only the
309 // last one will be shown.
310 ShowWindow(hwnd, SW_SHOWNORMAL);
311 return std::unique_ptr<HostWindow>(new HostWindow(
312 window_manager, engine, WindowArchetype::kRegular,
313 std::move(view_controller), BoxConstraints(smallest, biggest), hwnd));
314 }
flutter::WindowArchetype::kRegular
@ kRegular

References flutter::FlutterWindowsEngine::CreateView(), flutter::WindowSizing::has_preferred_view_size, flutter::WindowSizing::has_view_constraints, flutter::Rect::height(), flutter::kRegular, flutter::Rect::left(), flutter::WindowSizing::preferred_view_height, flutter::WindowSizing::preferred_view_width, flutter::FlutterWindowsEngine::running(), flutter::Rect::top(), flutter::FlutterWindowsEngine::UpdateAccessibilityFeatures(), flutter::WindowSizing::view_max_height, flutter::WindowSizing::view_max_width, flutter::WindowSizing::view_min_height, flutter::WindowSizing::view_min_width, flutter::Rect::width(), and flutter::FlutterWindowsEngine::windows_proc_table().

Referenced by flutter::WindowManager::CreateRegularWindow().

## ◆ GetThisFromHandle()

HostWindow * flutter::HostWindow::GetThisFromHandle | ( | HWND | hwnd | ) |
| static

Definition at line 343 of file host_window.cc.

343 {
344 return reinterpret_cast<HostWindow*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
345 }

Referenced by InternalFlutterWindows_WindowManager_SetWindowContentSize().

## ◆ GetWindowHandle()

HWND flutter::HostWindow::GetWindowHandle | ( |  | ) | const

Definition at line 347 of file host_window.cc.

347 {
348 return window_handle_;
349 }

## ◆ SetContentSize()

void flutter::HostWindow::SetContentSize | ( | const WindowSizing & | size | ) |

Definition at line 466 of file host_window.cc.

466 {
467 WINDOWINFO window_info = {.cbSize = sizeof(WINDOWINFO)};
468 GetWindowInfo(window_handle_, &window_info);
469
470 std::optional<Size> smallest, biggest;
471 if (size.has_view_constraints) {
472 smallest = Size(size.view_min_width, size.view_min_height);
473 if (size.view_max_width > 0 && size.view_max_height > 0) {
474 biggest = Size(size.view_max_width, size.view_max_height);
475 }
476 }
477
478 box_constraints_ = BoxConstraints(smallest, biggest);
479
480 if (size.has_preferred_view_size) {
481 std::optional<Size> const window_size = GetWindowSizeForClientSize(
482 *engine_->windows_proc_table(),
483 Size(size.preferred_view_width, size.preferred_view_height),
484 box_constraints_.smallest(), box_constraints_.biggest(),
485 window_info.dwStyle, window_info.dwExStyle, nullptr);
486
487 if (window_size) {
488 SetWindowPos(window_handle_, NULL, 0, 0, window_size->width(),
489 window_size->height(),
490 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
491 }
492 }
493 }
flutter::BoxConstraints::smallest
Size smallest() const
Definition: geometry.h:97
flutter::BoxConstraints::biggest
Size biggest() const
Definition: geometry.h:96
flutter::FlutterWindowsEngine::windows_proc_table
std::shared_ptr< WindowsProcTable > windows_proc_table()
Definition: flutter_windows_engine.h:308

References flutter::BoxConstraints::biggest(), flutter::WindowSizing::has_preferred_view_size, flutter::WindowSizing::has_view_constraints, flutter::WindowSizing::preferred_view_height, flutter::WindowSizing::preferred_view_width, flutter::BoxConstraints::smallest(), flutter::WindowSizing::view_max_height, flutter::WindowSizing::view_max_width, flutter::WindowSizing::view_min_height, flutter::WindowSizing::view_min_width, and flutter::FlutterWindowsEngine::windows_proc_table().

Referenced by InternalFlutterWindows_WindowManager_SetWindowContentSize().

The documentation for this class was generated from the following files:

- shell/platform/windows/host_window.h
- shell/platform/windows/host_window.cc