| Flutter Windows Embedder |

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

`#include <host_window.h>`

Inheritance diagram for flutter::HostWindow:

## Classes
struct | HostWindowInitializationParams
struct | SavedWindowInfo

## Public Member Functions
virtual | ~HostWindow ()
HWND | GetWindowHandle () const
HWND | GetFlutterViewWindowHandle () const
void | SetContentSize (const WindowSizeRequest &size)
void | SetConstraints (const WindowConstraints &constraints)
virtual void | SetFullscreen (bool fullscreen, std::optional< FlutterEngineDisplayId > display_id)
virtual bool | GetFullscreen () const
HostWindow * | GetOwnerWindow () const
void | UpdateModalStateLayer ()

## Static Public Member Functions
static std::unique_ptr< HostWindow > | CreateRegularWindow (WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowSizeRequest &preferred_size, const WindowConstraints &preferred_constraints, LPCWSTR title)
static std::unique_ptr< HostWindow > | CreateDialogWindow (WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowSizeRequest &preferred_size, const WindowConstraints &preferred_constraints, LPCWSTR title, HWND parent)
static std::unique_ptr< HostWindow > | CreateTooltipWindow (WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowConstraints &preferred_constraints, GetWindowPositionCallback get_position_callback, HWND parent)
static HostWindow * | GetThisFromHandle (HWND hwnd)
static ActualWindowSize | GetWindowContentSize (HWND hwnd)

## Protected Member Functions
void | InitializeFlutterView (HostWindowInitializationParams const &params)
| HostWindow (WindowManager *window_manager, FlutterWindowsEngine *engine)
virtual LRESULT | HandleMessage (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
void | EnableRecursively (bool enable)
HostWindow * | FindFirstEnabledDescendant () const
std::vector< HostWindow * > | GetOwnedWindows () const
void | DisableRecursively ()
| FML_DISALLOW_COPY_AND_ASSIGN (HostWindow)

## Static Protected Member Functions
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)
static void | FocusRootViewOf (HostWindow *window)
static LRESULT | WndProc (HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)

## Protected Attributes
friend | WindowManager
WindowManager *const | window_manager_ = nullptr
FlutterWindowsEngine * | engine_
std::unique_ptr< FlutterWindowsViewController > | view_controller_
WindowArchetype | archetype_ = WindowArchetype::kRegular
HWND | window_handle_
BoxConstraints | box_constraints_
bool | is_being_destroyed_ = false
bool | is_fullscreen_ = false
SavedWindowInfo | saved_window_info_
Microsoft::WRL::ComPtr< ITaskbarList2 > | task_bar_list_

## Detailed Description

Definition at line 29 of file host_window.h.

## Constructor & Destructor Documentation

## ◆ ~HostWindow()

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

Definition at line 326 of file host_window.cc.

326 {
327 if (view_controller_) {
328 // Unregister the window class. Fail silently if other windows are still
329 // using the class, as only the last window can successfully unregister it.
330 if (!UnregisterClass(kWindowClassName, GetModuleHandle(nullptr))) {
331 // Clear the error state after the failed unregistration.
332 SetLastError(ERROR_SUCCESS);
333 }
334 }
335 }
flutter::HostWindow::view_controller_
std::unique_ptr< FlutterWindowsViewController > view_controller_
Definition: host_window.h:216

## ◆ HostWindow()

flutter::HostWindow::HostWindow | ( | WindowManager * | window_manager,
|  | FlutterWindowsEngine * | engine
| ) |  |
| protected

Definition at line 240 of file host_window.cc.

242 : window_manager_(window_manager), engine_(engine) {}
flutter::HostWindow::engine_
FlutterWindowsEngine * engine_
Definition: host_window.h:211
flutter::HostWindow::window_manager_
WindowManager *const window_manager_
Definition: host_window.h:208

## Member Function Documentation

## ◆ CreateDialogWindow()

std::unique_ptr< HostWindow > flutter::HostWindow::CreateDialogWindow | ( | WindowManager * | window_manager,
|  | FlutterWindowsEngine * | engine,
|  | const WindowSizeRequest & | preferred_size,
|  | const WindowConstraints & | preferred_constraints,
|  | LPCWSTR | title,
|  | HWND | parent
| ) |  |
| static

Definition at line 216 of file host_window.cc.

222 {
223 return std::unique_ptr<HostWindow>(
224 new HostWindowDialog(window_manager, engine, preferred_size,
225 FromWindowConstraints(preferred_constraints), title,
226 parent ? parent : std::optional<HWND>()));
227 }

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

## ◆ CreateRegularWindow()

std::unique_ptr< HostWindow > flutter::HostWindow::CreateRegularWindow | ( | WindowManager * | window_manager,
|  | FlutterWindowsEngine * | engine,
|  | const WindowSizeRequest & | preferred_size,
|  | const WindowConstraints & | preferred_constraints,
|  | LPCWSTR | title
| ) |  |
| static

Definition at line 205 of file host_window.cc.

210 {
211 return std::unique_ptr<HostWindow>(new HostWindowRegular(
212 window_manager, engine, preferred_size,
213 FromWindowConstraints(preferred_constraints), title));
214 }

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

## ◆ CreateTooltipWindow()

std::unique_ptr< HostWindow > flutter::HostWindow::CreateTooltipWindow | ( | WindowManager * | window_manager,
|  | FlutterWindowsEngine * | engine,
|  | const WindowConstraints & | preferred_constraints,
|  | GetWindowPositionCallback | get_position_callback,
|  | HWND | parent
| ) |  |
| static

Definition at line 229 of file host_window.cc.

234 {
235 return std::unique_ptr<HostWindowTooltip>(new HostWindowTooltip(
236 window_manager, engine, FromWindowConstraints(preferred_constraints),
237 get_position_callback, parent));
238 }

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

## ◆ DisableRecursively()

void flutter::HostWindow::DisableRecursively | ( |  | ) |
| protected

Definition at line 838 of file host_window.cc.

838 {
839 // Disable the window itself.
840 EnableWindow(window_handle_, false);
841
842 for (HostWindow* const owned : GetOwnedWindows()) {
843 owned->DisableRecursively();
844 }
845 }
flutter::HostWindow::window_handle_
HWND window_handle_
Definition: host_window.h:222
flutter::HostWindow::HostWindow
HostWindow(WindowManager *window_manager, FlutterWindowsEngine *engine)
Definition: host_window.cc:240
flutter::HostWindow::GetOwnedWindows
std::vector< HostWindow * > GetOwnedWindows() const
Definition: host_window.cc:808

## ◆ EnableRecursively()

void flutter::HostWindow::EnableRecursively | ( | bool | enable | ) |
| protected

Definition at line 786 of file host_window.cc.

786 {
787 EnableWindow(window_handle_, enable);
788
789 for (HostWindow* const owned : GetOwnedWindows()) {
790 owned->EnableRecursively(enable);
791 }
792 }

## ◆ FindFirstEnabledDescendant()

HostWindow * flutter::HostWindow::FindFirstEnabledDescendant | ( |  | ) | const
| protected

Definition at line 794 of file host_window.cc.

794 {
795 if (IsWindowEnabled(window_handle_)) {
796 return const_cast<HostWindow*>(this);
797 }
798
799 for (HostWindow* const owned : GetOwnedWindows()) {
800 if (HostWindow* const result = owned->FindFirstEnabledDescendant()) {
801 return result;
802 }
803 }
804
805 return nullptr;
806 }

References FindFirstEnabledDescendant().

Referenced by FindFirstEnabledDescendant(), and flutter::HostWindowDialog::HandleMessage().

## ◆ FML_DISALLOW_COPY_AND_ASSIGN()

flutter::HostWindow::FML_DISALLOW_COPY_AND_ASSIGN | ( | HostWindow |  | ) |
| protected

## ◆ FocusRootViewOf()

void flutter::HostWindow::FocusRootViewOf | ( | HostWindow * | window | ) |
| static protected

Definition at line 360 of file host_window.cc.

360 {
361 auto child_content = window->view_controller_->view()->GetWindowHandle();
362 if (window != nullptr && child_content != nullptr) {
363 SetFocus(child_content);
364 }
365 };

References view_controller_.

Referenced by flutter::HostWindowDialog::HandleMessage().

## ◆ GetFlutterViewWindowHandle()

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

Definition at line 356 of file host_window.cc.

356 {
357 return view_controller_->view()->GetWindowHandle();
358 }

References GetWindowHandle().

Referenced by InternalFlutterWindows_WindowManager_OnDestroyWindow().

## ◆ GetFullscreen()

bool flutter::HostWindow::GetFullscreen | ( |  | ) | const
| virtual

Reimplemented in flutter::HostWindowDialog.

Definition at line 722 of file host_window.cc.

722 {
723 return is_fullscreen_;
724 }
flutter::HostWindow::is_fullscreen_
bool is_fullscreen_
Definition: host_window.h:231

Referenced by InternalFlutterWindows_WindowManager_GetFullscreen().

## ◆ GetOwnedWindows()

std::vector< HostWindow * > flutter::HostWindow::GetOwnedWindows | ( |  | ) | const
| protected

Definition at line 808 of file host_window.cc.

808 {
809 std::vector<HostWindow*> owned_windows;
810 struct EnumData {
811 HWND owner_window_handle;
812 std::vector<HostWindow*>* owned_windows;
813 } data{window_handle_, &owned_windows};
814
815 EnumWindows(
816 [](HWND hwnd, LPARAM lparam) -> BOOL {
817 auto* const data = reinterpret_cast<EnumData*>(lparam);
818 if (GetWindow(hwnd, GW_OWNER) == data->owner_window_handle) {
819 HostWindow* const window = GetThisFromHandle(hwnd);
820 if (window && !window->is_being_destroyed_) {
821 data->owned_windows->push_back(window);
822 }
823 }
824 return TRUE;
825 },
826 reinterpret_cast<LPARAM>(&data));
827
828 return owned_windows;
829 }
flutter::HostWindow::GetThisFromHandle
static HostWindow * GetThisFromHandle(HWND hwnd)
Definition: host_window.cc:337

References is_being_destroyed_.

## ◆ GetOwnerWindow()

HostWindow * flutter::HostWindow::GetOwnerWindow | ( |  | ) | const

Definition at line 831 of file host_window.cc.

831 {
832 if (HWND const owner_window_handle = GetWindow(GetWindowHandle(), GW_OWNER)) {
833 return GetThisFromHandle(owner_window_handle);
834 }
835 return nullptr;
836 };
flutter::HostWindow::GetWindowHandle
HWND GetWindowHandle() const
Definition: host_window.cc:352

Referenced by flutter::HostWindowDialog::HandleMessage(), and flutter::testing::TEST_F().

## ◆ GetThisFromHandle()

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

Definition at line 337 of file host_window.cc.

337 {
338 wchar_t class_name[256];
339 if (!GetClassName(hwnd, class_name, sizeof(class_name) / sizeof(wchar_t))) {
340 FML_LOG(ERROR) << "Failed to get class name for window handle " << hwnd
341 << ": " << GetLastErrorAsString();
342 return nullptr;
343 }
344 // Ignore window handles that do not match the expected class name.
345 if (wcscmp(class_name, kWindowClassName) != 0) {
346 return nullptr;
347 }
348
349 return reinterpret_cast<HostWindow*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
350 }

Referenced by flutter::WindowManager::HandleMessage(), InternalFlutterWindows_WindowManager_GetFullscreen(), InternalFlutterWindows_WindowManager_OnDestroyWindow(), InternalFlutterWindows_WindowManager_SetFullscreen(), InternalFlutterWindows_WindowManager_SetWindowConstraints(), InternalFlutterWindows_WindowManager_SetWindowSize(), InternalFlutterWindows_WindowManager_UpdateTooltipPosition(), and flutter::testing::TEST_F().

## ◆ GetWindowContentSize()

ActualWindowSize flutter::HostWindow::GetWindowContentSize | ( | HWND | hwnd | ) |
| static

Definition at line 726 of file host_window.cc.

726 {
727 RECT rect;
728 GetClientRect(hwnd, &rect);
729 double const dpr = FlutterDesktopGetDpiForHWND(hwnd) /
730 static_cast<double>(USER_DEFAULT_SCREEN_DPI);
731 double const width = rect.right / dpr;
732 double const height = rect.bottom / dpr;
733 return {
734 .width = rect.right / dpr,
735 .height = rect.bottom / dpr,
736 };
737 }
FlutterDesktopGetDpiForHWND
UINT FlutterDesktopGetDpiForHWND(HWND hwnd)
Definition: flutter_windows.cc:329

References FlutterDesktopGetDpiForHWND().

Referenced by InternalFlutterWindows_WindowManager_GetWindowContentSize().

## ◆ GetWindowHandle()

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

Definition at line 352 of file host_window.cc.

352 {
353 return window_handle_;
354 }

Referenced by GetFlutterViewWindowHandle(), and flutter::testing::TEST_F().

## ◆ GetWindowSizeForClientSize()

std::optional< Size > flutter::HostWindow::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
| ) |  |
| static protected

Definition at line 739 of file host_window.cc.

746 {
747 UINT const dpi = GetDpiForHWND(owner_hwnd ? *owner_hwnd : nullptr);
748 double const scale_factor =
749 static_cast<double>(dpi) / USER_DEFAULT_SCREEN_DPI;
750 RECT rect = {
751 .right = static_cast<LONG>(client_size.width() * scale_factor),
752 .bottom = static_cast<LONG>(client_size.height() * scale_factor)};
753
754 if (!win32.AdjustWindowRectExForDpi(&rect, window_style, FALSE,
755 extended_window_style, dpi)) {
756 FML_LOG(ERROR) << "Failed to run AdjustWindowRectExForDpi: "
757 << GetLastErrorAsString();
758 return std::nullopt;
759 }
760
761 double width = static_cast<double>(rect.right - rect.left);
762 double height = static_cast<double>(rect.bottom - rect.top);
763
764 // Apply size constraints.
765 double const non_client_width = width - (client_size.width() * scale_factor);
766 double const non_client_height =
767 height - (client_size.height() * scale_factor);
768 if (smallest) {
769 flutter::Size min_physical_size = ClampToVirtualScreen(
770 flutter::Size(smallest->width() * scale_factor + non_client_width,
771 smallest->height() * scale_factor + non_client_height));
772 width = std::max(width, min_physical_size.width());
773 height = std::max(height, min_physical_size.height());
774 }
775 if (biggest) {
776 flutter::Size max_physical_size = ClampToVirtualScreen(
777 flutter::Size(biggest->width() * scale_factor + non_client_width,
778 biggest->height() * scale_factor + non_client_height));
779 width = std::min(width, max_physical_size.width());
780 height = std::min(height, max_physical_size.height());
781 }
782
783 return flutter::Size{width, height};
784 }
flutter::GetDpiForHWND
UINT GetDpiForHWND(HWND hwnd)
Definition: dpi_utils.cc:128

References flutter::WindowsProcTable::AdjustWindowRectExForDpi(), and flutter::GetDpiForHWND().

## ◆ HandleMessage()

LRESULT flutter::HostWindow::HandleMessage | ( | HWND | hwnd,
|  | UINT | message,
|  | WPARAM | wparam,
|  | LPARAM | lparam
| ) |  |
| protected virtual

Reimplemented in flutter::HostWindowTooltip, and flutter::HostWindowDialog.

Definition at line 384 of file host_window.cc.

387 {
388 auto result = engine_->window_proc_delegate_manager()->OnTopLevelWindowProc(
389 window_handle_, message, wparam, lparam);
390 if (result) {
391 return *result;
392 }
393
394 switch (message) {
395 case WM_DESTROY:
396 is_being_destroyed_ = true;
397 break;
398
399 case WM_NCLBUTTONDOWN: {
400 // Fix for 500ms hang after user clicks on the title bar, but before
401 // moving mouse. Reference:
402 // https://gamedev.net/forums/topic/672094-keeping-things-moving-during-win32-moveresize-events/5254386/
403 if (SendMessage(window_handle_, WM_NCHITTEST, wparam, lparam) ==
404 HTCAPTION) {
405 POINT cursorPos;
406 // Get the current cursor position and synthesize WM_MOUSEMOVE to
407 // unblock default window proc implementation for WM_NCLBUTTONDOWN at
408 // HTCAPTION.
409 GetCursorPos(&cursorPos);
410 ScreenToClient(window_handle_, &cursorPos);
411 PostMessage(window_handle_, WM_MOUSEMOVE, 0,
412 MAKELPARAM(cursorPos.x, cursorPos.y));
413 }
414 break;
415 }
416
417 case WM_DPICHANGED: {
418 auto* const new_scaled_window_rect = reinterpret_cast<RECT*>(lparam);
419 LONG const width =
420 new_scaled_window_rect->right - new_scaled_window_rect->left;
421 LONG const height =
422 new_scaled_window_rect->bottom - new_scaled_window_rect->top;
423 SetWindowPos(hwnd, nullptr, new_scaled_window_rect->left,
424 new_scaled_window_rect->top, width, height,
425 SWP_NOZORDER | SWP_NOACTIVATE);
426 return 0;
427 }
428
429 case WM_GETMINMAXINFO: {
430 RECT window_rect;
431 GetWindowRect(hwnd, &window_rect);
432 RECT client_rect;
433 GetClientRect(hwnd, &client_rect);
434 LONG const non_client_width = (window_rect.right - window_rect.left) -
435 (client_rect.right - client_rect.left);
436 LONG const non_client_height = (window_rect.bottom - window_rect.top) -
437 (client_rect.bottom - client_rect.top);
438
439 UINT const dpi = flutter::GetDpiForHWND(hwnd);
440 double const scale_factor =
441 static_cast<double>(dpi) / USER_DEFAULT_SCREEN_DPI;
442
443 MINMAXINFO* info = reinterpret_cast<MINMAXINFO*>(lparam);
444 Size const min_physical_size = ClampToVirtualScreen(Size(
445 box_constraints_.smallest().width() * scale_factor + non_client_width,
446 box_constraints_.smallest().height() * scale_factor +
447 non_client_height));
448
449 info->ptMinTrackSize.x = min_physical_size.width();
450 info->ptMinTrackSize.y = min_physical_size.height();
451 Size const max_physical_size = ClampToVirtualScreen(Size(
452 box_constraints_.biggest().width() * scale_factor + non_client_width,
453 box_constraints_.biggest().height() * scale_factor +
454 non_client_height));
455
456 info->ptMaxTrackSize.x = max_physical_size.width();
457 info->ptMaxTrackSize.y = max_physical_size.height();
458 return 0;
459 }
460
461 case WM_SIZE: {
462 auto child_content = view_controller_->view()->GetWindowHandle();
463 if (child_content != nullptr) {
464 // Resize and reposition the child content window.
465 RECT client_rect;
466 GetClientRect(hwnd, &client_rect);
467 MoveWindow(child_content, client_rect.left, client_rect.top,
468 client_rect.right - client_rect.left,
469 client_rect.bottom - client_rect.top, TRUE);
470 }
471 return 0;
472 }
473
474 case WM_ACTIVATE:
475 FocusRootViewOf(this);
476 return 0;
477
478 case WM_DWMCOLORIZATIONCOLORCHANGED:
479 UpdateTheme(hwnd);
480 return 0;
481
482 default:
483 break;
484 }
485
486 if (!view_controller_) {
487 return 0;
488 }
489
490 return DefWindowProc(hwnd, message, wparam, lparam);
491 }
flutter::FlutterWindowsEngine::window_proc_delegate_manager
WindowProcDelegateManager * window_proc_delegate_manager()
Definition: flutter_windows_engine.h:185
flutter::HostWindow::box_constraints_
BoxConstraints box_constraints_
Definition: host_window.h:225
flutter::HostWindow::is_being_destroyed_
bool is_being_destroyed_
Definition: host_window.h:228
flutter::HostWindow::FocusRootViewOf
static void FocusRootViewOf(HostWindow *window)
Definition: host_window.cc:360
flutter::WindowProcDelegateManager::OnTopLevelWindowProc
std::optional< LRESULT > OnTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) const
Definition: window_proc_delegate_manager.cc:37
message
Win32Message message
Definition: keyboard_unittests.cc:137

Referenced by flutter::HostWindowDialog::HandleMessage(), and flutter::HostWindowTooltip::HandleMessage().

## ◆ InitializeFlutterView()

void flutter::HostWindow::InitializeFlutterView | ( | HostWindowInitializationParams const & | params | ) |
| protected

Definition at line 244 of file host_window.cc.

245 {
246 // Set up the view.
247 auto view_window = std::make_unique<FlutterWindow>(
248 params.initial_window_rect.width(), params.initial_window_rect.height(),
249 engine_->display_manager(), engine_->windows_proc_table());
250
251 std::unique_ptr<FlutterWindowsView> view =
252 engine_->CreateView(std::move(view_window), params.is_sized_to_content,
253 params.box_constraints, params.sizing_delegate);
254 FML_CHECK(view != nullptr);
255
256 view_controller_ =
257 std::make_unique<FlutterWindowsViewController>(nullptr, std::move(view));
258 FML_CHECK(engine_->running());
259 // The Windows embedder listens to accessibility updates using the
260 // view's HWND. The embedder's accessibility features may be stale if
261 // the app was in headless mode.
262 engine_->UpdateAccessibilityFeatures();
263
264 // Register the window class.
265 if (!IsClassRegistered(kWindowClassName)) {
266 auto const idi_app_icon = 101;
267 WNDCLASSEX window_class = {};
268 window_class.cbSize = sizeof(WNDCLASSEX);
269 window_class.style = CS_HREDRAW | CS_VREDRAW;
270 window_class.lpfnWndProc = HostWindow::WndProc;
271 window_class.hInstance = GetModuleHandle(nullptr);
272 window_class.hIcon =
273 LoadIcon(window_class.hInstance, MAKEINTRESOURCE(idi_app_icon));
274 if (!window_class.hIcon) {
275 window_class.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
276 }
277 window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
278 window_class.lpszClassName = kWindowClassName;
279
280 FML_CHECK(RegisterClassEx(&window_class));
281 }
282
283 // Create the native window.
284 window_handle_ = CreateWindowEx(
285 params.extended_window_style, kWindowClassName, params.title,
286 params.window_style, params.initial_window_rect.left(),
287 params.initial_window_rect.top(), params.initial_window_rect.width(),
288 params.initial_window_rect.height(),
289 params.owner_window ? *params.owner_window : nullptr, nullptr,
290 GetModuleHandle(nullptr), engine_->windows_proc_table().get());
291 FML_CHECK(window_handle_ != nullptr);
292
293 // Adjust the window position so its origin aligns with the top-left corner
294 // of the window frame, not the window rectangle (which includes the
295 // drop-shadow). This adjustment must be done post-creation since the frame
296 // rectangle is only available after the window has been created.
297 RECT frame_rect;
298 DwmGetWindowAttribute(window_handle_, DWMWA_EXTENDED_FRAME_BOUNDS,
299 &frame_rect, sizeof(frame_rect));
300 RECT window_rect;
301 GetWindowRect(window_handle_, &window_rect);
302 LONG const left_dropshadow_width = frame_rect.left - window_rect.left;
303 LONG const top_dropshadow_height = window_rect.top - frame_rect.top;
304 SetWindowPos(window_handle_, nullptr,
305 window_rect.left - left_dropshadow_width,
306 window_rect.top - top_dropshadow_height, 0, 0,
307 SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);
308
309 UpdateTheme(window_handle_);
310
311 SetChildContent(view_controller_->view()->GetWindowHandle(), window_handle_);
312
313 // Defer showing the window until the first frame is rendered so the user
314 // doesn't see a blank window. Each view has its own first-frame callback,
315 // so this works correctly for multi-window apps.
316 view_controller_->view()->SetFirstFrameCallback(
317 [hwnd = window_handle_, cmd_show = params.nCmdShow]() {
318 if (::IsWindow(hwnd)) {
319 ShowWindow(hwnd, cmd_show);
320 }
321 });
322 SetWindowLongPtr(window_handle_, GWLP_USERDATA,
323 reinterpret_cast<LONG_PTR>(this));
324 }
flutter::FlutterWindowsEngine::windows_proc_table
std::shared_ptr< WindowsProcTable > windows_proc_table()
Definition: flutter_windows_engine.h:324
flutter::FlutterWindowsEngine::UpdateAccessibilityFeatures
void UpdateAccessibilityFeatures()
Definition: flutter_windows_engine.cc:1021
flutter::FlutterWindowsEngine::display_manager
std::shared_ptr< DisplayManagerWin32 > display_manager()
Definition: flutter_windows_engine.h:166
flutter::FlutterWindowsEngine::CreateView
std::unique_ptr< FlutterWindowsView > CreateView(std::unique_ptr< WindowBindingHandler > window, bool is_sized_to_content, const BoxConstraints &box_constraints, FlutterWindowsViewSizingDelegate *sizing_delegate=nullptr)
Definition: flutter_windows_engine.cc:526
flutter::FlutterWindowsEngine::running
virtual bool running() const
Definition: flutter_windows_engine.h:125
flutter::HostWindow::WndProc
static LRESULT WndProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
Definition: host_window.cc:367

References flutter::HostWindow::HostWindowInitializationParams::box_constraints, flutter::FlutterWindowsEngine::CreateView(), flutter::FlutterWindowsEngine::display_manager(), engine_, flutter::HostWindow::HostWindowInitializationParams::extended_window_style, flutter::HostWindow::HostWindowInitializationParams::initial_window_rect, flutter::HostWindow::HostWindowInitializationParams::is_sized_to_content, flutter::HostWindow::HostWindowInitializationParams::nCmdShow, flutter::HostWindow::HostWindowInitializationParams::owner_window, flutter::FlutterWindowsEngine::running(), flutter::HostWindow::HostWindowInitializationParams::sizing_delegate, flutter::HostWindow::HostWindowInitializationParams::title, flutter::FlutterWindowsEngine::UpdateAccessibilityFeatures(), view_controller_, window_handle_, flutter::HostWindow::HostWindowInitializationParams::window_style, flutter::FlutterWindowsEngine::windows_proc_table(), and WndProc().

Referenced by flutter::HostWindowDialog::HostWindowDialog(), and flutter::HostWindowRegular::HostWindowRegular().

## ◆ SetConstraints()

void flutter::HostWindow::SetConstraints | ( | const WindowConstraints & | constraints | ) |

Definition at line 535 of file host_window.cc.

535 {
536 box_constraints_ = FromWindowConstraints(constraints);
537
538 if (GetFullscreen()) {
539 std::optional<Size> const window_size = GetWindowSizeForClientSize(
540 *engine_->windows_proc_table(),
541 Size(saved_window_info_.client_size.width,
542 saved_window_info_.client_size.height),
543 box_constraints_.smallest(), box_constraints_.biggest(),
544 saved_window_info_.style, saved_window_info_.ex_style, nullptr);
545 if (!window_size) {
546 return;
547 }
548
549 saved_window_info_.rect.right =
550 saved_window_info_.rect.left + static_cast<LONG>(window_size->width());
551 saved_window_info_.rect.bottom =
552 saved_window_info_.rect.top + static_cast<LONG>(window_size->height());
553 } else {
554 auto const client_size = GetWindowContentSize(window_handle_);
555 auto const current_size = Size(client_size.width, client_size.height);
556 WINDOWINFO window_info = {.cbSize = sizeof(WINDOWINFO)};
557 GetWindowInfo(window_handle_, &window_info);
558 std::optional<Size> const window_size = GetWindowSizeForClientSize(
559 *engine_->windows_proc_table(), current_size,
560 box_constraints_.smallest(), box_constraints_.biggest(),
561 window_info.dwStyle, window_info.dwExStyle, nullptr);
562
563 if (window_size && current_size != window_size) {
564 SetWindowPos(window_handle_, NULL, 0, 0, window_size->width(),
565 window_size->height(),
566 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
567 }
568 }
569 }
flutter::HostWindow::saved_window_info_
SavedWindowInfo saved_window_info_
Definition: host_window.h:234
flutter::HostWindow::GetWindowContentSize
static ActualWindowSize GetWindowContentSize(HWND hwnd)
Definition: host_window.cc:726
flutter::HostWindow::GetFullscreen
virtual bool GetFullscreen() const
Definition: host_window.cc:722
flutter::HostWindow::GetWindowSizeForClientSize
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:739
flutter::ActualWindowSize::width
double width
Definition: window_manager.h:96
flutter::ActualWindowSize::height
double height
Definition: window_manager.h:97
flutter::HostWindow::SavedWindowInfo::client_size
ActualWindowSize client_size
Definition: host_window.h:146
flutter::HostWindow::SavedWindowInfo::ex_style
LONG ex_style
Definition: host_window.h:144
flutter::HostWindow::SavedWindowInfo::style
LONG style
Definition: host_window.h:143
flutter::HostWindow::SavedWindowInfo::rect
RECT rect
Definition: host_window.h:145

Referenced by InternalFlutterWindows_WindowManager_SetWindowConstraints().

## ◆ SetContentSize()

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

Definition at line 493 of file host_window.cc.

493 {
494 if (!size.has_preferred_view_size) {
495 return;
496 }
497
498 if (GetFullscreen()) {
499 std::optional<Size> const window_size = GetWindowSizeForClientSize(
500 *engine_->windows_proc_table(),
501 Size(size.preferred_view_width, size.preferred_view_height),
502 box_constraints_.smallest(), box_constraints_.biggest(),
503 saved_window_info_.style, saved_window_info_.ex_style, nullptr);
504 if (!window_size) {
505 return;
506 }
507
508 saved_window_info_.client_size =
509 ActualWindowSize{.width = size.preferred_view_width,
510 .height = size.preferred_view_height};
511 saved_window_info_.rect.right =
512 saved_window_info_.rect.left + static_cast<LONG>(window_size->width());
513 saved_window_info_.rect.bottom =
514 saved_window_info_.rect.top + static_cast<LONG>(window_size->height());
515 } else {
516 WINDOWINFO window_info = {.cbSize = sizeof(WINDOWINFO)};
517 GetWindowInfo(window_handle_, &window_info);
518
519 std::optional<Size> const window_size = GetWindowSizeForClientSize(
520 *engine_->windows_proc_table(),
521 Size(size.preferred_view_width, size.preferred_view_height),
522 box_constraints_.smallest(), box_constraints_.biggest(),
523 window_info.dwStyle, window_info.dwExStyle, nullptr);
524
525 if (!window_size) {
526 return;
527 }
528
529 SetWindowPos(window_handle_, NULL, 0, 0, window_size->width(),
530 window_size->height(),
531 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
532 }
533 }

References flutter::WindowSizeRequest::has_preferred_view_size.

Referenced by InternalFlutterWindows_WindowManager_SetWindowSize().

## ◆ SetFullscreen()

void flutter::HostWindow::SetFullscreen | ( | bool | fullscreen,
|  | std::optional< FlutterEngineDisplayId > | display_id
| ) |  |
| virtual

Reimplemented in flutter::HostWindowDialog.

Definition at line 576 of file host_window.cc.

578 {
579 if (fullscreen == GetFullscreen()) {
580 return;
581 }
582
583 if (fullscreen) {
584 WINDOWINFO window_info = {.cbSize = sizeof(WINDOWINFO)};
585 GetWindowInfo(window_handle_, &window_info);
586 saved_window_info_.style = window_info.dwStyle;
587 saved_window_info_.ex_style = window_info.dwExStyle;
588 // Store the original window rect, DPI, and monitor info to detect changes
589 // and more accurately restore window placements when exiting fullscreen.
590 ::GetWindowRect(window_handle_, &saved_window_info_.rect);
591 saved_window_info_.client_size = GetWindowContentSize(window_handle_);
592 saved_window_info_.dpi = GetDpiForHWND(window_handle_);
593 saved_window_info_.monitor =
594 MonitorFromWindow(window_handle_, MONITOR_DEFAULTTONEAREST);
595 saved_window_info_.monitor_info.cbSize =
596 sizeof(saved_window_info_.monitor_info);
597 GetMonitorInfo(saved_window_info_.monitor,
598 &saved_window_info_.monitor_info);
599 }
600
601 if (fullscreen) {
602 // Next, get the raw HMONITOR that we want to be fullscreened on
603 HMONITOR monitor =
604 MonitorFromWindow(window_handle_, MONITOR_DEFAULTTONEAREST);
605 if (display_id) {
606 if (auto const display =
607 engine_->display_manager()->FindById(display_id.value())) {
608 monitor = reinterpret_cast<HMONITOR>(display->display_id);
609 }
610 }
611
612 MONITORINFO monitor_info;
613 monitor_info.cbSize = sizeof(monitor_info);
614 if (!GetMonitorInfo(monitor, &monitor_info)) {
615 FML_LOG(ERROR) << "Cannot set window fullscreen because the monitor info "
616 "was not found";
617 }
618
619 auto const width = RectWidth(monitor_info.rcMonitor);
620 auto const height = RectHeight(monitor_info.rcMonitor);
621 WINDOWINFO window_info = {.cbSize = sizeof(WINDOWINFO)};
622 GetWindowInfo(window_handle_, &window_info);
623
624 // Set new window style and size.
625 SetWindowLong(window_handle_, GWL_STYLE,
626 saved_window_info_.style & ~(WS_CAPTION | WS_THICKFRAME));
627 SetWindowLong(
628 window_handle_, GWL_EXSTYLE,
629 saved_window_info_.ex_style & ~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE |
630 WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
631
632 // We call SetWindowPos first to set the window flags immediately. This
633 // makes it so that the WM_GETMINMAXINFO gets called with the correct window
634 // and content sizes.
635 SetWindowPos(window_handle_, NULL, 0, 0, 0, 0,
636 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
637
638 SetWindowPos(window_handle_, nullptr, monitor_info.rcMonitor.left,
639 monitor_info.rcMonitor.top, width, height,
640 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
641 } else {
642 // Restore the window style and bounds saved prior to entering fullscreen.
643 // Use WS_VISIBLE for windows shown after SetFullscreen: crbug.com/1062251.
644 // Making multiple window adjustments here is ugly, but if SetWindowPos()
645 // doesn't redraw, the taskbar won't be repainted.
646 SetWindowLong(window_handle_, GWL_STYLE,
647 saved_window_info_.style | WS_VISIBLE);
648 SetWindowLong(window_handle_, GWL_EXSTYLE, saved_window_info_.ex_style);
649
650 // We call SetWindowPos first to set the window flags immediately. This
651 // makes it so that the WM_GETMINMAXINFO gets called with the correct window
652 // and content sizes.
653 SetWindowPos(window_handle_, NULL, 0, 0, 0, 0,
654 SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
655
656 HMONITOR monitor =
657 MonitorFromRect(&saved_window_info_.rect, MONITOR_DEFAULTTONEAREST);
658 MONITORINFO monitor_info;
659 monitor_info.cbSize = sizeof(monitor_info);
660 GetMonitorInfo(monitor, &monitor_info);
661
662 auto window_rect = saved_window_info_.rect;
663
664 // Adjust the window bounds to restore, if displays were disconnected,
665 // virtually rearranged, or otherwise changed metrics during fullscreen.
666 if (monitor != saved_window_info_.monitor ||
667 !AreRectsEqual(saved_window_info_.monitor_info.rcWork,
668 monitor_info.rcWork)) {
669 window_rect = AdjustToFit(monitor_info.rcWork, window_rect);
670 }
671
672 auto const fullscreen_dpi = GetDpiForHWND(window_handle_);
673 SetWindowPos(window_handle_, nullptr, window_rect.left, window_rect.top,
674 RectWidth(window_rect), RectHeight(window_rect),
675 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
676 auto const final_dpi = GetDpiForHWND(window_handle_);
677 if (final_dpi != saved_window_info_.dpi || final_dpi != fullscreen_dpi) {
678 // Reissue SetWindowPos if the DPI changed from saved or fullscreen DPIs.
679 // The first call may misinterpret bounds spanning displays, if the
680 // fullscreen display's DPI does not match the target display's DPI.
681 //
682 // Scale and clamp the bounds if the final DPI changed from the saved DPI.
683 // This more accurately matches the original placement, while avoiding
684 // unexpected offscreen placement in a recongifured multi-screen space.
685 if (final_dpi != saved_window_info_.dpi) {
686 auto const scale =
687 final_dpi / static_cast<float>(saved_window_info_.dpi);
688 auto const width = static_cast<LONG>(scale * RectWidth(window_rect));
689 auto const height = static_cast<LONG>(scale * RectHeight(window_rect));
690 window_rect.right = window_rect.left + width;
691 window_rect.bottom = window_rect.top + height;
692 window_rect = AdjustToFit(monitor_info.rcWork, window_rect);
693 }
694
695 SetWindowPos(window_handle_, nullptr, window_rect.left, window_rect.top,
696 RectWidth(window_rect), RectHeight(window_rect),
697 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
698 }
699 }
700
701 if (!task_bar_list_) {
702 HRESULT hr =
703 ::CoCreateInstance(CLSID_TaskbarList, nullptr, CLSCTX_INPROC_SERVER,
704 IID_PPV_ARGS(&task_bar_list_));
705 if (SUCCEEDED(hr) && FAILED(task_bar_list_->HrInit())) {
706 task_bar_list_ = nullptr;
707 }
708 }
709
710 // As per MSDN marking the window as fullscreen should ensure that the
711 // taskbar is moved to the bottom of the Z-order when the fullscreen window
712 // is activated. If the window is not fullscreen, the Shell falls back to
713 // heuristics to determine how the window should be treated, which means
714 // that it could still consider the window as fullscreen. :(
715 if (task_bar_list_) {
716 task_bar_list_->MarkFullscreenWindow(window_handle_, !!fullscreen);
717 }
718
719 is_fullscreen_ = fullscreen;
720 }
flutter::HostWindow::task_bar_list_
Microsoft::WRL::ComPtr< ITaskbarList2 > task_bar_list_
Definition: host_window.h:237
flutter::RectWidth
LONG RectWidth(const RECT &r)
Definition: rect_helper.h:11
flutter::AreRectsEqual
bool AreRectsEqual(const RECT &a, const RECT &b)
Definition: rect_helper.h:19
flutter::RectHeight
LONG RectHeight(const RECT &r)
Definition: rect_helper.h:15
flutter::HostWindow::SavedWindowInfo::dpi
int dpi
Definition: host_window.h:147
flutter::HostWindow::SavedWindowInfo::monitor_info
MONITORINFO monitor_info
Definition: host_window.h:149
flutter::HostWindow::SavedWindowInfo::monitor
HMONITOR monitor
Definition: host_window.h:148

References flutter::GetDpiForHWND().

Referenced by InternalFlutterWindows_WindowManager_SetFullscreen().

## ◆ UpdateModalStateLayer()

void flutter::HostWindow::UpdateModalStateLayer | ( |  | ) |

Definition at line 847 of file host_window.cc.

847 {
848 auto children = GetOwnedWindows();
849 if (children.empty()) {
850 // Leaf window in the active path, enable it.
851 EnableWindow(window_handle_, true);
852 } else {
853 // Non-leaf window in the active path, disable it and process children.
854 EnableWindow(window_handle_, false);
855
856 // On same level of window hierarchy the most recently created window
857 // will remain enabled.
858 auto latest_child = *std::max_element(
859 children.begin(), children.end(), [](HostWindow* a, HostWindow* b) {
860 return a->view_controller_->view()->view_id() <
861 b->view_controller_->view()->view_id();
862 });
863
864 for (HostWindow* const child : children) {
865 if (child == latest_child) {
866 child->UpdateModalStateLayer();
867 } else {
868 child->DisableRecursively();
869 }
870 }
871 }
872 }

## ◆ WndProc()

LRESULT flutter::HostWindow::WndProc | ( | HWND | hwnd,
|  | UINT | message,
|  | WPARAM | wparam,
|  | LPARAM | lparam
| ) |  |
| static protected

Definition at line 367 of file host_window.cc.

370 {
371 if (message == WM_NCCREATE) {
372 auto* const create_struct = reinterpret_cast<CREATESTRUCT*>(lparam);
373 auto* const windows_proc_table =
374 static_cast<WindowsProcTable*>(create_struct->lpCreateParams);
375 windows_proc_table->EnableNonClientDpiScaling(hwnd);
376 EnableTransparentWindowBackground(hwnd, *windows_proc_table);
377 } else if (HostWindow* const window = GetThisFromHandle(hwnd)) {
378 return window->HandleMessage(hwnd, message, wparam, lparam);
379 }
380
381 return DefWindowProc(hwnd, message, wparam, lparam);
382 }

References flutter::WindowsProcTable::EnableNonClientDpiScaling(), and message.

Referenced by InitializeFlutterView().

## Member Data Documentation

## ◆ archetype_

WindowArchetype flutter::HostWindow::archetype_ = WindowArchetype::kRegular
| protected

Definition at line 219 of file host_window.h.

## ◆ box_constraints_

BoxConstraints flutter::HostWindow::box_constraints_
| protected

Definition at line 225 of file host_window.h.

## ◆ engine_

FlutterWindowsEngine* flutter::HostWindow::engine_
| protected

Definition at line 211 of file host_window.h.

Referenced by InitializeFlutterView().

## ◆ is_being_destroyed_

bool flutter::HostWindow::is_being_destroyed_ = false
| protected

Definition at line 228 of file host_window.h.

Referenced by GetOwnedWindows(), and flutter::HostWindowDialog::HandleMessage().

## ◆ is_fullscreen_

bool flutter::HostWindow::is_fullscreen_ = false
| protected

Definition at line 231 of file host_window.h.

## ◆ saved_window_info_

SavedWindowInfo flutter::HostWindow::saved_window_info_
| protected

Definition at line 234 of file host_window.h.

## ◆ task_bar_list_

Microsoft::WRL::ComPtr<ITaskbarList2> flutter::HostWindow::task_bar_list_
| protected

Definition at line 237 of file host_window.h.

## ◆ view_controller_

std::unique_ptr<FlutterWindowsViewController> flutter::HostWindow::view_controller_
| protected

Definition at line 216 of file host_window.h.

Referenced by FocusRootViewOf(), flutter::WindowManager::HandleMessage(), InitializeFlutterView(), and flutter::HostWindowTooltip::UpdatePosition().

## ◆ window_handle_

HWND flutter::HostWindow::window_handle_
| protected

Definition at line 222 of file host_window.h.

Referenced by flutter::HostWindowDialog::HostWindowDialog(), InitializeFlutterView(), and flutter::HostWindowTooltip::UpdatePosition().

## ◆ window_manager_

WindowManager* const flutter::HostWindow::window_manager_ = nullptr
| protected

Definition at line 208 of file host_window.h.

## ◆ WindowManager

friend flutter::HostWindow::WindowManager
| protected

Definition at line 138 of file host_window.h.

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

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