Flutter Engine Uber Docs
Docs for the entire Flutter Engine repo.
 
Loading...
Searching...
No Matches
flutter_windows.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 <io.h>
8
9#include <algorithm>
10#include <chrono>
11#include <cstdlib>
12#include <filesystem>
13#include <memory>
14#include <vector>
15
28
29static_assert(FLUTTER_ENGINE_VERSION == 1, "");
30
31// Returns the engine corresponding to the given opaque API handle.
36
37// Returns the opaque API handle for the given engine instance.
42
47
50 return reinterpret_cast<FlutterDesktopViewControllerRef>(view_controller);
51}
52
53// Returns the view corresponding to the given opaque API handle.
57
58// Returns the opaque API handle for the given view instance.
62
63// Returns the texture registrar corresponding to the given opaque API handle.
68
69// Returns the opaque API handle for the given texture registrar instance.
74
75// Creates a view controller that might own the engine.
76//
77// If `owns_engine` is true, then the returned `FlutterDesktopViewControllerRef`
78// owns `engine_ref` and will deallocate `engine_ref` upon its own destruction.
80 FlutterDesktopEngineRef engine_ref,
81 int width,
82 int height,
83 bool owns_engine) {
84 flutter::FlutterWindowsEngine* engine_ptr = EngineFromHandle(engine_ref);
85 std::unique_ptr<flutter::WindowBindingHandler> window_wrapper =
86 std::make_unique<flutter::FlutterWindow>(
87 width, height, engine_ptr->display_manager(),
88 engine_ptr->windows_proc_table());
89
90 std::unique_ptr<flutter::FlutterWindowsEngine> engine;
91 if (owns_engine) {
92 engine = std::unique_ptr<flutter::FlutterWindowsEngine>(engine_ptr);
93 }
94
95 std::unique_ptr<flutter::FlutterWindowsView> view = engine_ptr->CreateView(
96 std::move(window_wrapper), false, flutter::BoxConstraints());
97 if (!view) {
98 return nullptr;
99 }
100
101 auto controller = std::make_unique<flutter::FlutterWindowsViewController>(
102 std::move(engine), std::move(view));
103
104 // Launch the engine if it is not running already.
105 if (!controller->engine()->running()) {
106 if (!controller->engine()->Run()) {
107 return nullptr;
108 }
109 }
110
111 // Must happen after engine is running.
112 controller->view()->SendInitialBounds();
113
114 // The Windows embedder listens to accessibility updates using the
115 // view's HWND. The embedder's accessibility features may be stale if
116 // the app was in headless mode.
117 controller->engine()->UpdateAccessibilityFeatures();
118
119 return HandleForViewController(controller.release());
120}
121
128
135
137 auto controller = ViewControllerFromHandle(ref);
138 controller->Destroy();
139 delete controller;
140}
141
144 auto controller = ViewControllerFromHandle(ref);
145 return static_cast<FlutterDesktopViewId>(controller->view()->view_id());
146}
147
153
159
162 auto controller = ViewControllerFromHandle(ref);
163 controller->view()->ForceRedraw();
164}
165
168 HWND hwnd,
170 WPARAM wparam,
171 LPARAM lparam,
172 LRESULT* result) {
173 auto controller = ViewControllerFromHandle(ref);
174 std::optional<LRESULT> delegate_result =
175 controller->engine()
176 ->window_proc_delegate_manager()
177 ->OnTopLevelWindowProc(hwnd, message, wparam, lparam);
178 if (delegate_result) {
179 *result = *delegate_result;
180 }
181 return delegate_result.has_value();
182}
183
185 const FlutterDesktopEngineProperties* engine_properties) {
186 flutter::FlutterProjectBundle project(*engine_properties);
187 auto engine = std::make_unique<flutter::FlutterWindowsEngine>(project);
188 return HandleForEngine(engine.release());
189}
190
193 bool result = true;
194 if (engine->running()) {
195 result = engine->Stop();
196 }
197 delete engine;
198 return result;
199}
200
206
208 const char* entry_point) {
209 std::string_view entry_point_view{""};
210 if (entry_point != nullptr) {
211 entry_point_view = entry_point;
212 }
213
214 return EngineFromHandle(engine)->Run(entry_point_view);
215}
216
218 return std::chrono::nanoseconds::max().count();
219}
220
224
227 const char* plugin_name) {
228 // Currently, one registrar acts as the registrar for all plugins, so the
229 // name is ignored. It is part of the API to reduce churn in the future when
230 // aligning more closely with the Flutter registrar system.
231
233}
234
239
245
252
256
259 VoidCallback on_cancel,
260 void* user_data) {
261 FML_DCHECK(callback) << "Callback must not be null";
262 struct Context {
264 VoidCallback on_cancel;
265 void* user_data;
266 bool invoked = false;
267
268 ~Context() {
269 if (!invoked && on_cancel) {
270 on_cancel(user_data);
271 }
272 }
273 };
274
275 auto context =
276 std::make_shared<Context>(Context{callback, on_cancel, user_data});
278 context->invoked = true;
279 context->callback(context->user_data);
280 });
281}
282
286
289 IDXGIAdapter* adapter;
291 &adapter)) {
292 return nullptr;
293 }
294 return adapter;
295}
296
298 IDXGIAdapter** adapter_out) {
299 auto egl_manager = EngineFromHandle(engine)->egl_manager();
300 if (egl_manager) {
301 Microsoft::WRL::ComPtr<ID3D11Device> d3d_device;
302 Microsoft::WRL::ComPtr<IDXGIDevice> dxgi_device;
303 if (egl_manager->GetDevice(d3d_device.GetAddressOf()) &&
304 SUCCEEDED(d3d_device.As(&dxgi_device))) {
305 if (SUCCEEDED(dxgi_device->GetAdapter(adapter_out))) {
306 return true;
307 }
308 }
309 }
310 return false;
311}
312
315 HWND hwnd,
317 WPARAM wparam,
318 LPARAM lparam,
319 LRESULT* result) {
320 std::optional<LRESULT> lresult =
322 wparam, lparam);
323 if (result && lresult.has_value()) {
324 *result = lresult.value();
325 }
326 return lresult.has_value();
327}
328
331 const char* view_type_name,
333 // TODO(schectman): forward to platform view manager.
334 // https://github.com/flutter/flutter/issues/143375
335}
336
341
347
351 void* user_data) {
352 registrar->engine->window_proc_delegate_manager()
353 ->RegisterTopLevelWindowProcDelegate(delegate, user_data);
354}
355
359 registrar->engine->window_proc_delegate_manager()
360 ->UnregisterTopLevelWindowProcDelegate(delegate);
361}
362
365 IDXGIAdapter** adapter_out) {
367 HandleForEngine(registrar->engine), adapter_out);
368}
369
371 return flutter::GetDpiForHWND(hwnd);
372}
373
375 return flutter::GetDpiForMonitor(monitor);
376}
377
379 FILE* unused;
380 if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
381 _dup2(_fileno(stdout), 1);
382 }
383 if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
384 _dup2(_fileno(stdout), 2);
385 }
386 std::ios::sync_with_stdio();
387}
388
389// Implementations of common/ API methods.
390
395
399 registrar->engine->AddPluginRegistrarDestructionCallback(callback, registrar);
400}
401
403 const char* channel,
404 const uint8_t* message,
405 const size_t message_size,
406 const FlutterDesktopBinaryReply reply,
407 void* user_data) {
409 << "Messenger must reference a running engine to send a message";
410
412 ->GetEngine()
413 ->SendPlatformMessage(channel, message, message_size, reply, user_data);
414}
415
417 const char* channel,
418 const uint8_t* message,
419 const size_t message_size) {
421 message_size, nullptr, nullptr);
422}
423
427 const uint8_t* data,
428 size_t data_length) {
430 << "Messenger must reference a running engine to send a response";
431
433 ->GetEngine()
434 ->SendPlatformMessageResponse(handle, data, data_length);
435}
436
438 const char* channel,
440 void* user_data) {
442 << "Messenger must reference a running engine to set a callback";
443
445 ->GetEngine()
448}
449
456
460
465
471
475
480
487
490 int64_t texture_id,
491 void (*callback)(void* user_data),
492 void* user_data) {
494 if (callback) {
495 registrar->UnregisterTexture(
497 return;
498 }
499 registrar->UnregisterTexture(texture_id);
500}
501
FlutterDesktopMessengerRef ToRef()
Convert to FlutterDesktopMessengerRef.
flutter::FlutterWindowsEngine * GetEngine() const
Getter for the engine field.
static FlutterDesktopMessenger * FromRef(FlutterDesktopMessengerRef ref)
Convert from FlutterDesktopMessengerRef.
FlutterDesktopMessengerRef messenger()
bool SendPlatformMessage(const char *channel, const uint8_t *message, const size_t message_size, const FlutterDesktopBinaryReply reply, void *user_data)
std::optional< LRESULT > ProcessExternalWindowMessage(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)
std::shared_ptr< WindowsProcTable > windows_proc_table()
IncomingMessageDispatcher * message_dispatcher()
void SendPlatformMessageResponse(const FlutterDesktopMessageResponseHandle *handle, const uint8_t *data, size_t data_length)
static FlutterWindowsEngine * GetEngineForId(int64_t engine_id)
std::unique_ptr< FlutterWindowsView > CreateView(std::unique_ptr< WindowBindingHandler > window, bool is_sized_to_content, const BoxConstraints &box_constraints, FlutterWindowsViewSizingDelegate *sizing_delegate=nullptr)
std::shared_ptr< DisplayManagerWin32 > display_manager()
void SetNextFrameCallback(fml::closure callback)
FlutterDesktopPluginRegistrarRef GetRegistrar()
int64_t RegisterTexture(const FlutterDesktopTextureInfo *texture_info)
Controls a view that displays Flutter content.
FlutterWindowsEngine * GetEngine() const
void SetMessageCallback(const std::string &channel, FlutterDesktopMessageCallback callback, void *user_data)
virtual bool RunsTasksOnCurrentThread() const
void PostTask(TaskClosure task)
void(* VoidCallback)(void *)
Definition embedder.h:416
#define FLUTTER_ENGINE_VERSION
Definition embedder.h:70
FlutterEngine engine
Definition main.cc:84
FlView * view
const char * message
const gchar * channel
G_BEGIN_DECLS FlutterViewId view_id
#define FLUTTER_EXPORT
void(* FlutterDesktopBinaryReply)(const uint8_t *data, size_t data_size, void *user_data)
void(* FlutterDesktopMessageCallback)(FlutterDesktopMessengerRef, const FlutterDesktopMessage *, void *)
void(* FlutterDesktopOnPluginRegistrarDestroyed)(FlutterDesktopPluginRegistrarRef)
struct FlutterDesktopTextureRegistrar * FlutterDesktopTextureRegistrarRef
void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger, const char *channel, FlutterDesktopMessageCallback callback, void *user_data)
UINT FlutterDesktopGetDpiForHWND(HWND hwnd)
void FlutterDesktopViewControllerForceRedraw(FlutterDesktopViewControllerRef ref)
static FlutterDesktopTextureRegistrarRef HandleForTextureRegistrar(flutter::FlutterWindowsTextureRegistrar *registrar)
bool FlutterDesktopEngineGetGraphicsAdapter(FlutterDesktopEngineRef engine, IDXGIAdapter **adapter_out)
FlutterDesktopEngineRef FlutterDesktopEngineCreate(const FlutterDesktopEngineProperties *engine_properties)
void FlutterDesktopEngineReloadSystemFonts(FlutterDesktopEngineRef engine)
bool FlutterDesktopEngineProcessExternalWindowMessage(FlutterDesktopEngineRef engine, HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, LRESULT *result)
bool FlutterDesktopPluginRegistrarGetGraphicsAdapter(FlutterDesktopPluginRegistrarRef registrar, IDXGIAdapter **adapter_out)
static flutter::FlutterWindowsEngine * EngineFromHandle(FlutterDesktopEngineRef ref)
void FlutterDesktopResyncOutputStreams()
void FlutterDesktopEngineRegisterPlatformViewType(FlutterDesktopEngineRef engine, const char *view_type_name, FlutterPlatformViewTypeEntry view_type)
static FlutterDesktopViewRef HandleForView(flutter::FlutterWindowsView *view)
static FlutterDesktopViewControllerRef CreateViewController(FlutterDesktopEngineRef engine_ref, int width, int height, bool owns_engine)
FLUTTER_EXPORT FlutterDesktopEngineRef FlutterDesktopEngineForId(int64_t engine_id)
void FlutterDesktopMessengerSendResponse(FlutterDesktopMessengerRef messenger, const FlutterDesktopMessageResponseHandle *handle, const uint8_t *data, size_t data_length)
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetViewById(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopViewId view_id)
static FlutterDesktopEngineRef HandleForEngine(flutter::FlutterWindowsEngine *engine)
bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger, const char *channel, const uint8_t *message, const size_t message_size, const FlutterDesktopBinaryReply reply, void *user_data)
void FlutterDesktopPluginRegistrarSetDestructionHandler(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopOnPluginRegistrarDestroyed callback)
FlutterDesktopPluginRegistrarRef FlutterDesktopEngineGetPluginRegistrar(FlutterDesktopEngineRef engine, const char *plugin_name)
int64_t FlutterDesktopTextureRegistrarRegisterExternalTexture(FlutterDesktopTextureRegistrarRef texture_registrar, const FlutterDesktopTextureInfo *texture_info)
static FlutterDesktopViewControllerRef HandleForViewController(flutter::FlutterWindowsViewController *view_controller)
bool FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable(FlutterDesktopTextureRegistrarRef texture_registrar, int64_t texture_id)
bool FlutterDesktopEngineIsPlatformThread(FlutterDesktopEngineRef engine)
FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(int width, int height, FlutterDesktopEngineRef engine)
FlutterDesktopMessengerRef FlutterDesktopMessengerLock(FlutterDesktopMessengerRef messenger)
void FlutterDesktopTextureRegistrarUnregisterExternalTexture(FlutterDesktopTextureRegistrarRef texture_registrar, int64_t texture_id, void(*callback)(void *user_data), void *user_data)
bool FlutterDesktopEngineDestroy(FlutterDesktopEngineRef engine_ref)
UINT FlutterDesktopGetDpiForMonitor(HMONITOR monitor)
void FlutterDesktopEnginePostPlatformThreadTask(FlutterDesktopEngineRef engine, VoidCallback callback, VoidCallback on_cancel, void *user_data)
bool FlutterDesktopMessengerIsAvailable(FlutterDesktopMessengerRef messenger)
bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger, const char *channel, const uint8_t *message, const size_t message_size)
FlutterDesktopTextureRegistrarRef FlutterDesktopEngineGetTextureRegistrar(FlutterDesktopEngineRef engine)
void FlutterDesktopPluginRegistrarUnregisterTopLevelWindowProcDelegate(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopWindowProcCallback delegate)
bool FlutterDesktopViewControllerHandleTopLevelWindowProc(FlutterDesktopViewControllerRef ref, HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam, LRESULT *result)
static flutter::FlutterWindowsTextureRegistrar * TextureRegistrarFromHandle(FlutterDesktopTextureRegistrarRef ref)
uint64_t FlutterDesktopEngineProcessMessages(FlutterDesktopEngineRef engine)
static flutter::FlutterWindowsView * ViewFromHandle(FlutterDesktopViewRef ref)
void FlutterDesktopMessengerUnlock(FlutterDesktopMessengerRef messenger)
void FlutterDesktopPluginRegistrarRegisterTopLevelWindowProcDelegate(FlutterDesktopPluginRegistrarRef registrar, FlutterDesktopWindowProcCallback delegate, void *user_data)
static flutter::FlutterWindowsViewController * ViewControllerFromHandle(FlutterDesktopViewControllerRef ref)
FlutterDesktopMessengerRef FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine)
IDXGIAdapter * FlutterDesktopViewGetGraphicsAdapter(FlutterDesktopViewRef view)
FlutterDesktopViewId FlutterDesktopViewControllerGetViewId(FlutterDesktopViewControllerRef ref)
FlutterDesktopEngineRef FlutterDesktopViewControllerGetEngine(FlutterDesktopViewControllerRef ref)
FlutterDesktopTextureRegistrarRef FlutterDesktopRegistrarGetTextureRegistrar(FlutterDesktopPluginRegistrarRef registrar)
FlutterDesktopMessengerRef FlutterDesktopPluginRegistrarGetMessenger(FlutterDesktopPluginRegistrarRef registrar)
void FlutterDesktopEngineSetNextFrameCallback(FlutterDesktopEngineRef engine, VoidCallback callback, void *user_data)
HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view)
void FlutterDesktopMessengerRelease(FlutterDesktopMessengerRef messenger)
FlutterDesktopViewRef FlutterDesktopViewControllerGetView(FlutterDesktopViewControllerRef ref)
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView(FlutterDesktopPluginRegistrarRef registrar)
FlutterDesktopMessengerRef FlutterDesktopMessengerAddRef(FlutterDesktopMessengerRef messenger)
FlutterDesktopViewControllerRef FlutterDesktopEngineCreateViewController(FlutterDesktopEngineRef engine, const FlutterDesktopViewControllerProperties *properties)
void FlutterDesktopViewControllerDestroy(FlutterDesktopViewControllerRef ref)
bool FlutterDesktopEngineRun(FlutterDesktopEngineRef engine, const char *entry_point)
struct FlutterDesktopViewController * FlutterDesktopViewControllerRef
bool(* FlutterDesktopWindowProcCallback)(HWND, UINT, WPARAM, LPARAM, void *, LRESULT *result)
int64_t FlutterDesktopViewId
struct FlutterDesktopView * FlutterDesktopViewRef
FlutterDesktopBinaryReply callback
#define FML_DCHECK(condition)
Definition logging.h:122
G_BEGIN_DECLS FlTextureRegistrar * texture_registrar
UINT GetDpiForHWND(HWND hwnd)
Definition dpi_utils.cc:128
UINT GetDpiForMonitor(HMONITOR monitor)
Definition dpi_utils.cc:132
constexpr FlutterViewId kImplicitViewId
std::shared_ptr< ContextGLES > context
int32_t height
int32_t width
FlutterDesktopMessengerReferenceOwner messenger
FlutterDesktopEngineState * engine
int64_t texture_id
#define SUCCEEDED(hr)
LONG_PTR LRESULT
unsigned int UINT
LONG_PTR LPARAM
UINT_PTR WPARAM