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->get_position_callback, request->parent);
64  if (!window || !window->GetWindowHandle()) {
65  FML_LOG(ERROR) << "Failed to create host window";
66  return -1;
67  }
68  FlutterViewId const view_id = window->view_controller_->view()->view_id();
69  active_windows_[window->GetWindowHandle()] = std::move(window);
70  return view_id;
71 }
72 
74  // Don't send any more messages to isolate.
75  on_message_ = nullptr;
76  std::vector<HWND> active_handles;
77  active_handles.reserve(active_windows_.size());
78  for (auto& [hwnd, window] : active_windows_) {
79  active_handles.push_back(hwnd);
80  }
81  for (auto hwnd : active_handles) {
82  // This will destroy the window, which will in turn remove the
83  // HostWindow from map when handling WM_NCDESTROY inside
84  // HandleMessage.
86  }
87 }
88 
89 std::optional<LRESULT> WindowManager::HandleMessage(HWND hwnd,
90  UINT message,
91  WPARAM wparam,
92  LPARAM lparam) {
93  if (message == WM_NCDESTROY) {
94  active_windows_.erase(hwnd);
95  return std::nullopt;
96  }
97 
98  HostWindow* host_window = HostWindow::GetThisFromHandle(hwnd);
99  FlutterWindowsView* view =
100  host_window ? host_window->view_controller_->view() : nullptr;
101 
102  if (!view) {
103  FML_LOG(WARNING) << "Received message for unknown view";
104  return std::nullopt;
105  }
106 
107  WindowsMessage message_struct = {.view_id = view->view_id(),
108  .hwnd = hwnd,
109  .message = message,
110  .wParam = wparam,
111  .lParam = lparam,
112  .result = 0,
113  .handled = false};
114 
115  // Not initialized yet.
116  if (!isolate_) {
117  return std::nullopt;
118  }
119 
120  IsolateScope scope(*isolate_);
121  on_message_(&message_struct);
122  if (message_struct.handled) {
123  return message_struct.result;
124  } else {
125  return std::nullopt;
126  }
127 }
128 
129 } // namespace flutter
130 
132  int64_t engine_id,
133  const flutter::WindowingInitRequest* request) {
136  engine->window_manager()->Initialize(request);
137 }
138 
140  int64_t engine_id,
141  const flutter::RegularWindowCreationRequest* request) {
144  return engine->window_manager()->CreateRegularWindow(request);
145 }
146 
149  int64_t engine_id,
150  const flutter::DialogWindowCreationRequest* request) {
153  return engine->window_manager()->CreateDialogWindow(request);
154 }
155 
158  int64_t engine_id,
159  const flutter::TooltipWindowCreationRequest* request) {
162  return engine->window_manager()->CreateTooltipWindow(request);
163 }
164 
166  int64_t engine_id,
167  FlutterViewId view_id) {
170  flutter::FlutterWindowsView* view = engine->view(view_id);
171  if (view == nullptr) {
172  return nullptr;
173  } else {
174  return GetAncestor(view->GetWindowHandle(), GA_ROOT);
175  }
176 }
177 
181 }
182 
184  HWND hwnd,
185  const flutter::WindowSizeRequest* size) {
187  if (window) {
188  window->SetContentSize(*size);
189  }
190 }
191 
194  HWND flutter_view_handle = nullptr;
195  if (window) {
196  // First reparent the FlutterView to null parent. Otherwise destroying
197  // the window HWND will immediately destroy the FlutterView HWND as well,
198  // which will cause crash when raster thread tries to reallocate surface.
199  // The FlutterView may only be destroyed safely when
200  // FlutterWindowsEngine::RemoveView finishes.
201  flutter_view_handle = window->GetFlutterViewWindowHandle();
202  ShowWindow(flutter_view_handle, SW_HIDE);
203  SetParent(flutter_view_handle, nullptr);
204  }
205  DestroyWindow(hwnd);
206  if (flutter_view_handle) {
207  // Now the flutter view HWND can be destroyed safely.
208  DestroyWindow(flutter_view_handle);
209  }
210 }
211 
213  HWND hwnd,
214  const flutter::WindowConstraints* constraints) {
216  if (window) {
217  window->SetConstraints(*constraints);
218  }
219 }
220 
222  HWND hwnd,
223  const flutter::FullscreenRequest* request) {
225  const std::optional<FlutterEngineDisplayId> display_id =
226  request->has_display_id
227  ? std::optional<FlutterEngineDisplayId>(request->display_id)
228  : std::nullopt;
229  if (window) {
230  window->SetFullscreen(request->fullscreen, display_id);
231  }
232 }
233 
236  if (window) {
237  return window->GetFullscreen();
238  }
239 
240  return false;
241 }
242 
246  flutter::HostWindowTooltip* tooltip_window =
247  reinterpret_cast<flutter::HostWindowTooltip*>(window);
248  tooltip_window->UpdatePosition();
249 }
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:216
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:229
static ActualWindowSize GetWindowContentSize(HWND hwnd)
Definition: host_window.cc:726
void SetContentSize(const WindowSizeRequest &size)
Definition: host_window.cc:493
HWND GetFlutterViewWindowHandle() const
Definition: host_window.cc:356
static HostWindow * GetThisFromHandle(HWND hwnd)
Definition: host_window.cc:337
virtual bool GetFullscreen() const
Definition: host_window.cc:722
void SetConstraints(const WindowConstraints &constraints)
Definition: host_window.cc:535
virtual void SetFullscreen(bool fullscreen, std::optional< FlutterEngineDisplayId > display_id)
Definition: host_window.cc:576
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)