Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
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
9
10namespace {
11DWORD GetWindowStyleForDialog(std::optional<HWND> const& owner_window) {
12 DWORD window_style = WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME;
13 if (!owner_window) {
14 // If the dialog has no owner, add a minimize box and a system menu.
15 window_style |= WS_MINIMIZEBOX | WS_SYSMENU;
16 }
17
18 return window_style;
19}
20
21DWORD GetExtendedWindowStyleForDialog(std::optional<HWND> const& owner_window) {
22 DWORD extended_window_style = WS_EX_DLGMODALFRAME;
23 if (owner_window) {
24 // If the owner window has WS_EX_TOOLWINDOW style, apply the same
25 // style to the dialog.
26 if (GetWindowLongPtr(*owner_window, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) {
27 extended_window_style |= WS_EX_TOOLWINDOW;
28 }
29 }
30 return extended_window_style;
31}
32} // namespace
33
34namespace flutter {
35
38 const WindowSizeRequest& preferred_size,
39 const BoxConstraints& constraints,
40 LPCWSTR title,
41 std::optional<HWND> const& owner_window)
42 : HostWindow(window_manager, engine) {
45 .window_style = GetWindowStyleForDialog(owner_window),
46 .extended_window_style = GetExtendedWindowStyleForDialog(owner_window),
47 .box_constraints = constraints,
48 .initial_window_rect =
49 GetInitialRect(engine, preferred_size, constraints, owner_window),
50 .title = title,
51 .owner_window = owner_window,
52 });
53 auto hwnd = window_handle_;
54 if (owner_window == nullptr) {
55 if (HMENU hMenu = GetSystemMenu(hwnd, FALSE)) {
56 EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
57 }
58 }
59
60 if (owner_window != nullptr) {
61 UpdateModalState();
62 }
63}
64
65Rect HostWindowDialog::GetInitialRect(FlutterWindowsEngine* engine,
66 const WindowSizeRequest& preferred_size,
67 const BoxConstraints& constraints,
68 std::optional<HWND> const& owner_window) {
69 auto const window_style = GetWindowStyleForDialog(owner_window);
70 auto const extended_window_style =
71 GetExtendedWindowStyleForDialog(owner_window);
72 std::optional<Size> const window_size =
74 *engine->windows_proc_table(),
75 Size(preferred_size.preferred_view_width,
76 preferred_size.preferred_view_height),
77 constraints.smallest(), constraints.biggest(), window_style,
78 extended_window_style, owner_window);
79 Point window_origin = {CW_USEDEFAULT, CW_USEDEFAULT};
80 if (owner_window && window_size.has_value()) {
81 // Center dialog in the owner's frame.
82 RECT frame;
83 DwmGetWindowAttribute(*owner_window, DWMWA_EXTENDED_FRAME_BOUNDS, &frame,
84 sizeof(frame));
85 window_origin = {(frame.left + frame.right - window_size->width()) * 0.5,
86 (frame.top + frame.bottom - window_size->height()) * 0.5};
87 }
88
89 return {window_origin,
90 window_size ? *window_size : Size{CW_USEDEFAULT, CW_USEDEFAULT}};
91}
92
95 WPARAM wparam,
96 LPARAM lparam) {
97 switch (message) {
98 case WM_DESTROY:
100 if (HostWindow* const owner_window = GetOwnerWindow()) {
101 UpdateModalState();
102 FocusRootViewOf(owner_window);
103 }
104 break;
105
106 case WM_ACTIVATE:
107 // Forward the message to Dart before handling it on the C++ side.
108 // This ensures that Dart-side handlers (e.g. popup dismiss logic)
109 // can observe activation changes caused by dialog windows.
110 if (auto const result =
112 window_handle_, message, wparam, lparam)) {
113 return *result;
114 }
115
116 if (LOWORD(wparam) != WA_INACTIVE) {
117 // Prevent disabled window from being activated using the task
118 // switcher.
119 if (!IsWindowEnabled(hwnd)) {
120 // Redirect focus and activation to the first enabled descendant.
121 if (HostWindow* enabled_descendant = FindFirstEnabledDescendant()) {
122 SetActiveWindow(enabled_descendant->GetWindowHandle());
123 FocusRootViewOf(this);
124 }
125 return 0;
126 }
127 FocusRootViewOf(this);
128 }
129 return 0;
130 }
131
132 return HostWindow::HandleMessage(hwnd, message, wparam, lparam);
133}
134
135void HostWindowDialog::UpdateModalState() {
136 // Find the root window of the window hierarchy and process
137 // modal state update for the entire branch.
138 HostWindow* root = this;
139 while (HostWindow* const owner = root->GetOwnerWindow()) {
140 root = owner;
141 }
142 root->UpdateModalStateLayer();
143}
144
146 bool fullscreen,
147 std::optional<FlutterEngineDisplayId> display_id) {}
148
150 return false;
151}
152
153} // namespace flutter
Size smallest() const
Definition geometry.h:94
Size biggest() const
Definition geometry.h:93
WindowProcDelegateManager * window_proc_delegate_manager()
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)
HostWindow * GetOwnerWindow() const
static void FocusRootViewOf(HostWindow *window)
FlutterWindowsEngine * engine_
virtual LRESULT HandleMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
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)
HostWindow * FindFirstEnabledDescendant() const
std::optional< LRESULT > OnTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) const
FlutterEngine engine
Definition main.cc:84
const char * message
TSize< Scalar > Size
Definition size.h:159
LONG_PTR LRESULT
unsigned int UINT
LONG_PTR LPARAM
UINT_PTR WPARAM
unsigned long DWORD