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
10
11namespace flutter {
12
13DWORD HostWindowDialog::GetWindowStyleForDialog(
14 std::optional<HWND> const& owner_window,
15 bool resizable) {
16 DWORD window_style = WS_OVERLAPPED | WS_CAPTION;
17 if (resizable) {
18 window_style |= WS_THICKFRAME;
19 }
20 if (!owner_window) {
21 // If the dialog has no owner, add a minimize box and a system menu.
22 window_style |= WS_MINIMIZEBOX | WS_SYSMENU;
23 }
24 return window_style;
25}
26
27DWORD HostWindowDialog::GetExtendedWindowStyleForDialog(
28 std::optional<HWND> const& owner_window) {
29 DWORD extended_window_style = WS_EX_DLGMODALFRAME;
30 if (owner_window) {
31 // If the owner window has WS_EX_TOOLWINDOW style, apply the same
32 // style to the dialog.
33 if (GetWindowLongPtr(*owner_window, GWL_EXSTYLE) & WS_EX_TOOLWINDOW) {
34 extended_window_style |= WS_EX_TOOLWINDOW;
35 }
36 }
37 return extended_window_style;
38}
39
42 const WindowSizeRequest& preferred_size,
43 const BoxConstraints& constraints,
44 LPCWSTR title,
45 std::optional<HWND> const& owner_window,
47 bool resizable)
48 : HostWindowSized(window_manager, engine, resizable) {
52 .window_style = GetWindowStyleForDialog(owner_window, resizable),
53 .extended_window_style = GetExtendedWindowStyleForDialog(owner_window),
54 .box_constraints = constraints,
55 .initial_window_rect =
56 GetInitialRect(engine, preferred_size, constraints, owner_window,
57 sized_to_content, resizable),
58 .title = title,
59 .owner_window = owner_window,
60 .sizing_delegate = sized_to_content ? AsSizingDelegate() : nullptr,
61 .is_sized_to_content = sized_to_content,
62 });
63
64 auto hwnd = window_handle_;
65 if (owner_window) {
66 if (HMENU hMenu = GetSystemMenu(hwnd, FALSE)) {
67 EnableMenuItem(hMenu, SC_CLOSE, MF_BYCOMMAND | MF_GRAYED);
68 }
69 }
70
71 if (owner_window) {
72 UpdateModalState();
73 }
74}
75
77 // Reset the view while this most-derived object is still fully alive, to stop
78 // the raster thread from sizing it before any subobject is torn down. See the
79 // destructor comment in host_window_sized.h for the rationale.
80 view_controller_.reset();
81}
82
83Rect HostWindowDialog::GetInitialRect(FlutterWindowsEngine* engine,
84 const WindowSizeRequest& preferred_size,
85 const BoxConstraints& constraints,
86 std::optional<HWND> const& owner_window,
88 bool resizable) {
89 auto const window_style = GetWindowStyleForDialog(owner_window, resizable);
90 auto const extended_window_style =
91 GetExtendedWindowStyleForDialog(owner_window);
92
93 double client_width;
94 double client_height;
95 if (sized_to_content) {
96 // Use the minimum constraint as the initial window size. The window will
97 // be resized to match the rendered content after the first frame.
98 client_width = std::max(1.0, constraints.smallest().width());
99 client_height = std::max(1.0, constraints.smallest().height());
100 } else {
101 client_width = preferred_size.preferred_view_width;
102 client_height = preferred_size.preferred_view_height;
103 }
104
105 std::optional<Size> const window_size =
107 *engine->windows_proc_table(), Size(client_width, client_height),
108 constraints.smallest(), constraints.biggest(), window_style,
109 extended_window_style, owner_window);
110
111 Point window_origin = {CW_USEDEFAULT, CW_USEDEFAULT};
112 if (!sized_to_content && owner_window && window_size.has_value()) {
113 // Center dialog in the owner's frame.
114 RECT frame;
115 DwmGetWindowAttribute(*owner_window, DWMWA_EXTENDED_FRAME_BOUNDS, &frame,
116 sizeof(frame));
117 window_origin = {(frame.left + frame.right - window_size->width()) * 0.5,
118 (frame.top + frame.bottom - window_size->height()) * 0.5};
119 }
120
121 return {window_origin,
122 window_size ? *window_size : Size{CW_USEDEFAULT, CW_USEDEFAULT}};
123}
124
127 WPARAM wparam,
128 LPARAM lparam) {
129 switch (message) {
130 case WM_DESTROY:
131 is_being_destroyed_ = true;
132 if (HostWindow* const owner_window = GetOwnerWindow()) {
133 UpdateModalState();
134 FocusRootViewOf(owner_window);
135 }
136 break;
137
138 case WM_ACTIVATE:
139 // Forward the message to Dart before handling it on the C++ side.
140 // This ensures that Dart-side handlers (e.g. popup dismiss logic)
141 // can observe activation changes caused by dialog windows.
142 if (auto const result =
144 window_handle_, message, wparam, lparam)) {
145 return *result;
146 }
147
148 HandleWindowActivation(hwnd, wparam);
149 return 0;
150 }
151
152 return HostWindow::HandleMessage(hwnd, message, wparam, lparam);
153}
154
155void HostWindowDialog::UpdateModalState() {
156 // Find the root window of the window hierarchy and process
157 // modal state update for the entire branch.
158 HostWindow* root = this;
159 while (HostWindow* const owner = root->GetOwnerWindow()) {
160 root = owner;
161 }
162 root->UpdateModalStateLayer();
163}
164
166 bool fullscreen,
167 std::optional<FlutterEngineDisplayId> display_id) {}
168
170 return false;
171}
172
173} // namespace flutter
Size smallest() const
Definition geometry.h:94
Size biggest() const
Definition geometry.h:93
WindowProcDelegateManager * window_proc_delegate_manager()
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
HostWindowDialog(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowSizeRequest &preferred_size, const BoxConstraints &constraints, LPCWSTR title, std::optional< HWND > const &owner_window, bool sized_to_content, bool resizable)
void InitializeFlutterView(HostWindowInitializationParams const &params)
void HandleWindowActivation(HWND hwnd, WPARAM wparam)
std::unique_ptr< FlutterWindowsViewController > view_controller_
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)
FlutterWindowsViewSizingDelegate * AsSizingDelegate()
double height() const
Definition geometry.h:45
double width() const
Definition geometry.h:44
std::optional< LRESULT > OnTopLevelWindowProc(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam) const
FlutterEngine engine
Definition main.cc:84
const char * message
G_BEGIN_DECLS gboolean sized_to_content
#define FML_CHECK(condition)
Definition logging.h:104
TPoint< Scalar > Point
Definition point.h:426
TSize< Scalar > Size
Definition size.h:159
LONG_PTR LRESULT
unsigned int UINT
LONG_PTR LPARAM
UINT_PTR WPARAM
unsigned long DWORD