Flutter Windows Embedder
window_manager.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 
7 #include <dwmapi.h>
8 #include <optional>
9 #include <vector>
10 
11 #include "embedder.h"
16 #include "fml/logging.h"
22 
23 namespace flutter {
24 
26 
28  on_message_ = request->on_message;
29  isolate_ = Isolate::Current();
30 }
31 
33  const RegularWindowCreationRequest* request) {
34  auto window = HostWindow::CreateRegularWindow(
35  this, engine_, request->preferred_size, request->preferred_constraints,
36  request->title, request->sized_to_content, request->resizable);
37  if (!window || !window->GetWindowHandle()) {
38  FML_LOG(ERROR) << "Failed to create host window";
39  return -1;
40  }
41  FlutterViewId const view_id = window->view_controller_->view()->view_id();
42  active_windows_[window->GetWindowHandle()] = std::move(window);
43  return view_id;
44 }
45 
47  const DialogWindowCreationRequest* request) {
48  auto window = HostWindow::CreateDialogWindow(
49  this, engine_, request->preferred_size, request->preferred_constraints,
50  request->title, request->parent_or_null, request->sized_to_content,
51  request->resizable);
52  if (!window || !window->GetWindowHandle()) {
53  FML_LOG(ERROR) << "Failed to create host window";
54  return -1;
55  }
56  FlutterViewId const view_id = window->view_controller_->view()->view_id();
57  active_windows_[window->GetWindowHandle()] = std::move(window);
58  return view_id;
59 }
60 
62  const TooltipWindowCreationRequest* request) {
63  auto window = HostWindow::CreateTooltipWindow(
64  this, engine_, request->preferred_constraints,
65  request->get_position_callback, request->parent);
66  if (!window || !window->GetWindowHandle()) {
67  FML_LOG(ERROR) << "Failed to create host window";
68  return -1;
69  }
70  FlutterViewId const view_id = window->view_controller_->view()->view_id();
71  active_windows_[window->GetWindowHandle()] = std::move(window);
72  return view_id;
73 }
74 
76  const PopupWindowCreationRequest* request) {
77  auto window = HostWindow::CreatePopupWindow(
78  this, engine_, request->preferred_constraints,
79  request->get_position_callback, request->parent);
80  if (!window || !window->GetWindowHandle()) {
81  FML_LOG(ERROR) << "Failed to create host window";
82  return -1;
83  }
84  FlutterViewId const view_id = window->view_controller_->view()->view_id();
85  active_windows_[window->GetWindowHandle()] = std::move(window);
86  return view_id;
87 }
88 
90  // Don't send any more messages to isolate.
91  on_message_ = nullptr;
92  std::vector<HWND> active_handles;
93  active_handles.reserve(active_windows_.size());
94  for (auto& [hwnd, window] : active_windows_) {
95  active_handles.push_back(hwnd);
96  }
97  for (auto hwnd : active_handles) {
98  // This will destroy the window, which will in turn remove the
99  // HostWindow from map when handling WM_NCDESTROY inside
100  // HandleMessage.
102  }
103 }
104 
105 std::optional<LRESULT> WindowManager::HandleMessage(HWND hwnd,
106  UINT message,
107  WPARAM wparam,
108  LPARAM lparam) {
109  if (message == WM_NCDESTROY) {
110  active_windows_.erase(hwnd);
111  return std::nullopt;
112  }
113 
114  HostWindow* host_window = HostWindow::GetThisFromHandle(hwnd);
115  FlutterWindowsView* view =
116  host_window ? host_window->view_controller_->view() : nullptr;
117 
118  if (!view) {
119  FML_LOG(WARNING) << "Received message for unknown view";
120  return std::nullopt;
121  }
122 
123  WindowsMessage message_struct = {.view_id = view->view_id(),
124  .hwnd = hwnd,
125  .message = message,
126  .wParam = wparam,
127  .lParam = lparam,
128  .result = 0,
129  .handled = false};
130 
131  // Not initialized yet.
132  if (!isolate_) {
133  return std::nullopt;
134  }
135 
136  IsolateScope scope(*isolate_);
137  on_message_(&message_struct);
138  if (message_struct.handled) {
139  return message_struct.result;
140  } else {
141  return std::nullopt;
142  }
143 }
144 
145 } // namespace flutter
146 
148  int64_t engine_id,
149  const flutter::WindowingInitRequest* request) {
152  engine->window_manager()->Initialize(request);
153 }
154 
156  int64_t engine_id,
157  const flutter::RegularWindowCreationRequest* request) {
160  return engine->window_manager()->CreateRegularWindow(request);
161 }
162 
165  int64_t engine_id,
166  const flutter::DialogWindowCreationRequest* request) {
169  return engine->window_manager()->CreateDialogWindow(request);
170 }
171 
174  int64_t engine_id,
175  const flutter::TooltipWindowCreationRequest* request) {
178  return engine->window_manager()->CreateTooltipWindow(request);
179 }
180 
183  int64_t engine_id,
184  const flutter::PopupWindowCreationRequest* request) {
187  return engine->window_manager()->CreatePopupWindow(request);
188 }
189 
191  int64_t engine_id,
192  FlutterViewId view_id) {
195  flutter::FlutterWindowsView* view = engine->view(view_id);
196  if (view == nullptr) {
197  return nullptr;
198  } else {
199  return GetAncestor(view->GetWindowHandle(), GA_ROOT);
200  }
201 }
202 
206 }
207 
209  HWND hwnd,
210  const flutter::WindowSizeRequest* size) {
212  if (window) {
213  window->SetContentSize(*size);
214  }
215 }
216 
219  HWND flutter_view_handle = nullptr;
220  if (window) {
221  // First reparent the FlutterView to null parent. Otherwise destroying
222  // the window HWND will immediately destroy the FlutterView HWND as well,
223  // which will cause crash when raster thread tries to reallocate surface.
224  // The FlutterView may only be destroyed safely when
225  // FlutterWindowsEngine::RemoveView finishes.
226  flutter_view_handle = window->GetFlutterViewWindowHandle();
227  ShowWindow(flutter_view_handle, SW_HIDE);
228  SetParent(flutter_view_handle, nullptr);
229  }
230  DestroyWindow(hwnd);
231  if (flutter_view_handle) {
232  // Now the flutter view HWND can be destroyed safely.
233  DestroyWindow(flutter_view_handle);
234  }
235 }
236 
238  HWND hwnd,
239  const flutter::WindowConstraints* constraints) {
241  if (window) {
242  window->SetConstraints(*constraints);
243  }
244 }
245 
247  HWND hwnd,
248  const flutter::FullscreenRequest* request) {
250  const std::optional<FlutterEngineDisplayId> display_id =
251  request->has_display_id
252  ? std::optional<FlutterEngineDisplayId>(request->display_id)
253  : std::nullopt;
254  if (window) {
255  window->SetFullscreen(request->fullscreen, display_id);
256  }
257 }
258 
261  if (window) {
262  return window->GetFullscreen();
263  }
264 
265  return false;
266 }
267 
271  flutter::HostWindowTooltip* tooltip_window =
272  reinterpret_cast<flutter::HostWindowTooltip*>(window);
273  tooltip_window->UpdatePosition();
274 }
275 
279  flutter::HostWindowPopup* popup_window =
280  reinterpret_cast<flutter::HostWindowPopup*>(window);
281  popup_window->UpdatePosition();
282 }
FlutterWindowsView * view(FlutterViewId view_id) const
static FlutterWindowsEngine * GetEngineForId(int64_t engine_id)
virtual HWND GetWindowHandle() const
static std::unique_ptr< HostWindow > CreatePopupWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowConstraints &preferred_constraints, GetWindowPositionCallback get_position_callback, HWND parent)
Definition: host_window.cc:217
static std::unique_ptr< HostWindow > CreateDialogWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowSizeRequest &preferred_size, const WindowConstraints &preferred_constraints, LPCWSTR title, HWND parent, bool sized_to_content, bool resizable)
Definition: host_window.cc:191
std::unique_ptr< FlutterWindowsViewController > view_controller_
Definition: host_window.h:259
static std::unique_ptr< HostWindow > CreateTooltipWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowConstraints &preferred_constraints, GetWindowPositionCallback get_position_callback, HWND parent)
Definition: host_window.cc:206
static ActualWindowSize GetWindowContentSize(HWND hwnd)
Definition: host_window.cc:738
void SetContentSize(const WindowSizeRequest &size)
Definition: host_window.cc:505
static std::unique_ptr< HostWindow > CreateRegularWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowSizeRequest &preferred_size, const WindowConstraints &preferred_constraints, LPCWSTR title, bool sized_to_content, bool resizable)
Definition: host_window.cc:177
HWND GetFlutterViewWindowHandle() const
Definition: host_window.cc:345
static HostWindow * GetThisFromHandle(HWND hwnd)
Definition: host_window.cc:326
virtual bool GetFullscreen() const
Definition: host_window.cc:734
void SetConstraints(const WindowConstraints &constraints)
Definition: host_window.cc:547
virtual void SetFullscreen(bool fullscreen, std::optional< FlutterEngineDisplayId > display_id)
Definition: host_window.cc:588
static Isolate Current()
Definition: isolate_scope.cc:9
FlutterViewId CreateDialogWindow(const DialogWindowCreationRequest *request)
std::optional< LRESULT > HandleMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
FlutterViewId CreateRegularWindow(const RegularWindowCreationRequest *request)
void Initialize(const WindowingInitRequest *request)
WindowManager(FlutterWindowsEngine *engine)
FlutterViewId CreatePopupWindow(const PopupWindowCreationRequest *request)
FlutterViewId CreateTooltipWindow(const TooltipWindowCreationRequest *request)
#define FLUTTER_EXPORT
Win32Message message
int64_t FlutterViewId
FlutterEngineDisplayId display_id
GetWindowPositionCallback get_position_callback
GetWindowPositionCallback get_position_callback
void(* on_message)(WindowsMessage *)
void InternalFlutterWindows_WindowManager_Initialize(int64_t engine_id, const flutter::WindowingInitRequest *request)
void InternalFlutterWindows_WindowManager_SetWindowConstraints(HWND hwnd, const flutter::WindowConstraints *constraints)
FLUTTER_EXPORT void InternalFlutterWindows_WindowManager_UpdateTooltipPosition(HWND hwnd)
bool InternalFlutterWindows_WindowManager_GetFullscreen(HWND hwnd)
void InternalFlutterWindows_WindowManager_SetWindowSize(HWND hwnd, const flutter::WindowSizeRequest *size)
FlutterViewId InternalFlutterWindows_WindowManager_CreateRegularWindow(int64_t engine_id, const flutter::RegularWindowCreationRequest *request)
FLUTTER_EXPORT FlutterViewId InternalFlutterWindows_WindowManager_CreateDialogWindow(int64_t engine_id, const flutter::DialogWindowCreationRequest *request)
void InternalFlutterWindows_WindowManager_SetFullscreen(HWND hwnd, const flutter::FullscreenRequest *request)
FLUTTER_EXPORT void InternalFlutterWindows_WindowManager_UpdatePopupPosition(HWND hwnd)
void InternalFlutterWindows_WindowManager_OnDestroyWindow(HWND hwnd)
flutter::ActualWindowSize InternalFlutterWindows_WindowManager_GetWindowContentSize(HWND hwnd)
FLUTTER_EXPORT FlutterViewId InternalFlutterWindows_WindowManager_CreateTooltipWindow(int64_t engine_id, const flutter::TooltipWindowCreationRequest *request)
FLUTTER_EXPORT FlutterViewId InternalFlutterWindows_WindowManager_CreatePopupWindow(int64_t engine_id, const flutter::PopupWindowCreationRequest *request)
HWND InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(int64_t engine_id, FlutterViewId view_id)