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"
21 
22 namespace flutter {
23 
25 
27  on_message_ = request->on_message;
28  isolate_ = Isolate::Current();
29 }
30 
32  const RegularWindowCreationRequest* request) {
33  auto window = HostWindow::CreateRegularWindow(
34  this, engine_, request->preferred_size, request->preferred_constraints,
35  request->title);
36  if (!window || !window->GetWindowHandle()) {
37  FML_LOG(ERROR) << "Failed to create host window";
38  return -1;
39  }
40  FlutterViewId const view_id = window->view_controller_->view()->view_id();
41  active_windows_[window->GetWindowHandle()] = std::move(window);
42  return view_id;
43 }
44 
46  const DialogWindowCreationRequest* request) {
47  auto window = HostWindow::CreateDialogWindow(
48  this, engine_, request->preferred_size, request->preferred_constraints,
49  request->title, request->parent_or_null);
50  if (!window || !window->GetWindowHandle()) {
51  FML_LOG(ERROR) << "Failed to create host window";
52  return -1;
53  }
54  FlutterViewId const view_id = window->view_controller_->view()->view_id();
55  active_windows_[window->GetWindowHandle()] = std::move(window);
56  return view_id;
57 }
58 
60  const TooltipWindowCreationRequest* request) {
61  auto window = HostWindow::CreateTooltipWindow(
62  this, engine_, request->preferred_constraints,
63  request->is_sized_to_content, request->get_position_callback,
64  request->parent);
65  if (!window || !window->GetWindowHandle()) {
66  FML_LOG(ERROR) << "Failed to create host window";
67  return -1;
68  }
69  FlutterViewId const view_id = window->view_controller_->view()->view_id();
70  active_windows_[window->GetWindowHandle()] = std::move(window);
71  return view_id;
72 }
73 
75  // Don't send any more messages to isolate.
76  on_message_ = nullptr;
77  std::vector<HWND> active_handles;
78  active_handles.reserve(active_windows_.size());
79  for (auto& [hwnd, window] : active_windows_) {
80  active_handles.push_back(hwnd);
81  }
82  for (auto hwnd : active_handles) {
83  // This will destroy the window, which will in turn remove the
84  // HostWindow from map when handling WM_NCDESTROY inside
85  // HandleMessage.
87  }
88 }
89 
90 std::optional<LRESULT> WindowManager::HandleMessage(HWND hwnd,
91  UINT message,
92  WPARAM wparam,
93  LPARAM lparam) {
94  if (message == WM_NCDESTROY) {
95  active_windows_.erase(hwnd);
96  return std::nullopt;
97  }
98 
99  HostWindow* host_window = HostWindow::GetThisFromHandle(hwnd);
100  FlutterWindowsView* view =
101  host_window ? host_window->view_controller_->view() : nullptr;
102 
103  if (!view) {
104  FML_LOG(WARNING) << "Received message for unknown view";
105  return std::nullopt;
106  }
107 
108  WindowsMessage message_struct = {.view_id = view->view_id(),
109  .hwnd = hwnd,
110  .message = message,
111  .wParam = wparam,
112  .lParam = lparam,
113  .result = 0,
114  .handled = false};
115 
116  // Not initialized yet.
117  if (!isolate_) {
118  return std::nullopt;
119  }
120 
121  IsolateScope scope(*isolate_);
122  on_message_(&message_struct);
123  if (message_struct.handled) {
124  return message_struct.result;
125  } else {
126  return std::nullopt;
127  }
128 }
129 
130 } // namespace flutter
131 
133  int64_t engine_id,
134  const flutter::WindowingInitRequest* request) {
137  engine->window_manager()->Initialize(request);
138 }
139 
141  int64_t engine_id,
142  const flutter::RegularWindowCreationRequest* request) {
145  return engine->window_manager()->CreateRegularWindow(request);
146 }
147 
150  int64_t engine_id,
151  const flutter::DialogWindowCreationRequest* request) {
154  return engine->window_manager()->CreateDialogWindow(request);
155 }
156 
159  int64_t engine_id,
160  const flutter::TooltipWindowCreationRequest* request) {
163  return engine->window_manager()->CreateTooltipWindow(request);
164 }
165 
167  int64_t engine_id,
168  FlutterViewId view_id) {
171  flutter::FlutterWindowsView* view = engine->view(view_id);
172  if (view == nullptr) {
173  return nullptr;
174  } else {
175  return GetAncestor(view->GetWindowHandle(), GA_ROOT);
176  }
177 }
178 
182 }
183 
185  HWND hwnd,
186  const flutter::WindowSizeRequest* size) {
188  if (window) {
189  window->SetContentSize(*size);
190  }
191 }
192 
195  HWND flutter_view_handle = nullptr;
196  if (window) {
197  // First reparent the FlutterView to null parent. Otherwise destroying
198  // the window HWND will immediately destroy the FlutterView HWND as well,
199  // which will cause crash when raster thread tries to reallocate surface.
200  // The FlutterView may only be destroyed safely when
201  // FlutterWindowsEngine::RemoveView finishes.
202  flutter_view_handle = window->GetFlutterViewWindowHandle();
203  ShowWindow(flutter_view_handle, SW_HIDE);
204  SetParent(flutter_view_handle, nullptr);
205  }
206  DestroyWindow(hwnd);
207  if (flutter_view_handle) {
208  // Now the flutter view HWND can be destroyed safely.
209  DestroyWindow(flutter_view_handle);
210  }
211 }
212 
214  HWND hwnd,
215  const flutter::WindowConstraints* constraints) {
217  if (window) {
218  window->SetConstraints(*constraints);
219  }
220 }
221 
223  HWND hwnd,
224  const flutter::FullscreenRequest* request) {
226  const std::optional<FlutterEngineDisplayId> display_id =
227  request->has_display_id
228  ? std::optional<FlutterEngineDisplayId>(request->display_id)
229  : std::nullopt;
230  if (window) {
231  window->SetFullscreen(request->fullscreen, display_id);
232  }
233 }
234 
237  if (window) {
238  return window->GetFullscreen();
239  }
240 
241  return false;
242 }
243 
247  flutter::HostWindowTooltip* tooltip_window =
248  reinterpret_cast<flutter::HostWindowTooltip*>(window);
249  tooltip_window->UpdatePosition();
250 }
FlutterWindowsView * view(FlutterViewId view_id) const
static FlutterWindowsEngine * GetEngineForId(int64_t engine_id)
virtual HWND GetWindowHandle() const
std::unique_ptr< FlutterWindowsViewController > view_controller_
Definition: host_window.h:217
static ActualWindowSize GetWindowContentSize(HWND hwnd)
Definition: host_window.cc:724
void SetContentSize(const WindowSizeRequest &size)
Definition: host_window.cc:491
HWND GetFlutterViewWindowHandle() const
Definition: host_window.cc:354
static HostWindow * GetThisFromHandle(HWND hwnd)
Definition: host_window.cc:335
virtual bool GetFullscreen() const
Definition: host_window.cc:720
void SetConstraints(const WindowConstraints &constraints)
Definition: host_window.cc:533
static std::unique_ptr< HostWindow > CreateTooltipWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowConstraints &preferred_constraints, bool is_sized_to_content, GetWindowPositionCallback get_position_callback, HWND parent)
Definition: host_window.cc:229
virtual void SetFullscreen(bool fullscreen, std::optional< FlutterEngineDisplayId > display_id)
Definition: host_window.cc:574
static std::unique_ptr< HostWindow > CreateDialogWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowSizeRequest &preferred_size, const WindowConstraints &preferred_constraints, LPCWSTR title, HWND parent)
Definition: host_window.cc:216
static std::unique_ptr< HostWindow > CreateRegularWindow(WindowManager *window_manager, FlutterWindowsEngine *engine, const WindowSizeRequest &preferred_size, const WindowConstraints &preferred_constraints, LPCWSTR title)
Definition: host_window.cc:205
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 CreateTooltipWindow(const TooltipWindowCreationRequest *request)
#define FLUTTER_EXPORT
Win32Message message
int64_t FlutterViewId
FlutterEngineDisplayId display_id
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)
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)
HWND InternalFlutterWindows_WindowManager_GetTopLevelWindowHandle(int64_t engine_id, FlutterViewId view_id)