10#include <shared_mutex>
43static std::chrono::nanoseconds SnapToNextTick(
44 std::chrono::nanoseconds
value,
45 std::chrono::nanoseconds tick_phase,
46 std::chrono::nanoseconds tick_interval) {
47 std::chrono::nanoseconds offset = (tick_phase -
value) % tick_interval;
48 if (offset != std::chrono::nanoseconds::zero())
49 offset = offset + tick_interval;
50 return value + offset;
63 if (!
host->egl_manager()) {
66 return host->egl_manager()->render_context()->MakeCurrent();
70 if (!
host->egl_manager()) {
73 return host->egl_manager()->render_context()->ClearCurrent();
82 const char* what) ->
void* {
83 return reinterpret_cast<void*
>(eglGetProcAddress(what));
87 if (!
host->egl_manager()) {
90 return host->egl_manager()->resource_context()->MakeCurrent();
96 if (!
host->texture_registrar()) {
114 [](
void*
user_data,
const void* allocation,
size_t row_bytes,
136FlutterLocale CovertToFlutterLocale(
const LanguageInfo& info) {
140 if (!info.region.empty()) {
143 if (!info.script.empty()) {
153 std::shared_ptr<WindowsProcTable> windows_proc_table)
155 windows_proc_table_(
std::move(windows_proc_table)),
156 aot_data_(nullptr, nullptr),
158 if (windows_proc_table_ ==
nullptr) {
159 windows_proc_table_ = std::make_shared<WindowsProcTable>();
168 std::make_unique<TaskRunner>(
172 <<
"Cannot post an engine task when engine is not running.";
176 FML_LOG(ERROR) <<
"Failed to post an engine task.";
183 messenger_->SetEngine(
this);
184 plugin_registrar_ = std::make_unique<FlutterDesktopPluginRegistrar>();
185 plugin_registrar_->engine =
this;
188 std::make_unique<BinaryMessengerImpl>(messenger_->ToRef());
189 message_dispatcher_ =
190 std::make_unique<IncomingMessageDispatcher>(messenger_->ToRef());
193 std::make_unique<FlutterWindowsTextureRegistrar>(
this, gl_);
196 auto& switches = project_->GetSwitches();
197 bool enable_impeller =
true;
199 enable_impeller =
true;
201 enable_impeller =
false;
203 for (
const auto& env_switch : switches) {
204 if (env_switch ==
"--enable-impeller" ||
205 env_switch ==
"--enable-impeller=true") {
206 enable_impeller =
true;
207 }
else if (env_switch ==
"--enable-impeller=false") {
208 enable_impeller =
false;
211 enable_impeller_ = enable_impeller;
215 window_proc_delegate_manager_ = std::make_unique<WindowProcDelegateManager>();
217 display_manager_ = std::make_shared<DisplayManagerWin32>(
this);
219 window_proc_delegate_manager_->RegisterTopLevelWindowProcDelegate(
223 FlutterWindowsEngine* that =
224 static_cast<FlutterWindowsEngine*
>(
user_data);
227 if (that->display_manager_->HandleWindowMessage(hwnd, msg, wpar, lpar,
234 that->lifecycle_manager_->WindowProc(hwnd, msg, wpar, lpar, result);
238 auto message_result =
239 that->window_manager_->HandleMessage(hwnd, msg, wpar, lpar);
240 if (message_result) {
241 *result = *message_result;
246 static_cast<void*
>(
this));
251 internal_plugin_registrar_ =
252 std::make_unique<PluginRegistrar>(plugin_registrar_.get());
254 accessibility_plugin_ = std::make_unique<AccessibilityPlugin>(
this);
256 accessibility_plugin_.get());
259 std::make_unique<CursorHandler>(messenger_wrapper_.get(),
this);
261 std::make_unique<PlatformHandler>(messenger_wrapper_.get(),
this);
262 window_manager_ = std::make_unique<WindowManager>(
this);
263 settings_plugin_ = std::make_unique<SettingsPlugin>(messenger_wrapper_.get(),
267FlutterWindowsEngine::~FlutterWindowsEngine() {
268 messenger_->SetEngine(
nullptr);
276void FlutterWindowsEngine::SetSwitches(
277 const std::vector<std::string>& switches) {
281bool FlutterWindowsEngine::Run() {
285bool FlutterWindowsEngine::Run(std::string_view entrypoint) {
286 if (!project_->HasValidPaths()) {
287 FML_LOG(ERROR) <<
"Missing or unresolvable paths to assets.";
290 std::string assets_path_string =
fml::PathToUtf8(project_->assets_path());
292 if (embedder_api_.RunsAOTCompiledDartCode()) {
293 aot_data_ = project_->LoadAotData(embedder_api_);
295 FML_LOG(ERROR) <<
"Unable to start engine without AOT data.";
303 std::string executable_name = GetExecutableName();
304 std::vector<const char*>
argv = {executable_name.c_str()};
305 std::vector<std::string> switches = project_->GetSwitches();
306 if (enable_impeller_) {
307 if (std::find(switches.begin(), switches.end(),
308 "--impeller-use-sdfs=true") == switches.end() &&
309 std::find(switches.begin(), switches.end(),
310 "--impeller-use-sdfs=false") == switches.end()) {
311 switches.push_back(
"--impeller-use-sdfs=true");
313 if (std::find(switches.begin(), switches.end(),
"--enable-impeller") ==
315 std::find(switches.begin(), switches.end(),
"--enable-impeller=true") ==
319 switches.push_back(
"--enable-impeller");
321 }
else if (project_->impeller_switch() == FlutterImpellerSwitch::Disabled) {
322 if (std::find(switches.begin(), switches.end(),
323 "--enable-impeller=false") == switches.end()) {
326 switches.push_back(
"--enable-impeller=false");
330 switches.begin(), switches.end(), std::back_inserter(
argv),
331 [](
const std::string& arg) ->
const char* { return arg.c_str(); });
333 const std::vector<std::string>& entrypoint_args =
334 project_->dart_entrypoint_arguments();
335 std::vector<const char*> entrypoint_argv;
337 entrypoint_args.begin(), entrypoint_args.end(),
338 std::back_inserter(entrypoint_argv),
339 [](
const std::string& arg) ->
const char* { return arg.c_str(); });
344 platform_task_runner.
user_data = task_runner_.get();
350 uint64_t target_time_nanos,
359 &WindowsPlatformThreadPrioritySetter;
361 if (project_->ui_thread_policy() !=
362 FlutterUIThreadPolicy::RunOnSeparateThread) {
365 FML_LOG(WARNING) <<
"Running with unmerged platform and UI threads. This "
366 "will be removed in future.";
371 args.shutdown_dart_vm_when_done =
true;
372 args.assets_path = assets_path_string.c_str();
373 args.icu_data_path = icu_path_string.c_str();
374 args.command_line_argc =
static_cast<int>(
argv.size());
375 args.command_line_argv =
argv.empty() ? nullptr :
argv.data();
376 args.engine_id =
reinterpret_cast<int64_t
>(
this);
384 if (!project_->dart_entrypoint().empty() && !entrypoint.empty() &&
385 project_->dart_entrypoint() != entrypoint) {
386 FML_LOG(ERROR) <<
"Conflicting entrypoints were specified in "
387 "FlutterDesktopEngineProperties.dart_entrypoint and "
388 "FlutterDesktopEngineRun(engine, entry_point). ";
391 if (!entrypoint.empty()) {
392 args.custom_dart_entrypoint = entrypoint.data();
393 }
else if (!project_->dart_entrypoint().empty()) {
394 args.custom_dart_entrypoint = project_->dart_entrypoint().c_str();
396 args.dart_entrypoint_argc =
static_cast<int>(entrypoint_argv.size());
397 args.dart_entrypoint_argv =
398 entrypoint_argv.empty() ? nullptr : entrypoint_argv.data();
399 args.platform_message_callback =
403 return host->HandlePlatformMessage(engine_message);
405 args.vsync_callback = [](
void*
user_data, intptr_t baton) ->
void {
407 host->OnVsync(baton);
411 host->OnPreEngineRestart();
422 auto accessibility_bridge =
view->accessibility_bridge().lock();
423 if (!accessibility_bridge) {
429 accessibility_bridge->AddFlutterSemanticsNodeUpdate(*node);
434 accessibility_bridge->AddFlutterSemanticsCustomActionUpdate(*
action);
437 accessibility_bridge->CommitUpdates();
441 if (
host->root_isolate_create_callback_) {
442 host->root_isolate_create_callback_();
449 std::string channel_name(update->channel);
450 host->OnChannelUpdate(std::move(channel_name),
454 args.view_focus_change_request_callback =
457 host->OnViewFocusChangeRequest(request);
460 args.custom_task_runners = &custom_task_runners;
462 if (!platform_view_plugin_) {
463 platform_view_plugin_ = std::make_unique<PlatformViewPlugin>(
464 messenger_wrapper_.get(), task_runner_.get());
467 auto resolver = [](
const char*
name) ->
void* {
468 return reinterpret_cast<void*
>(::eglGetProcAddress(
name));
474 std::make_unique<CompositorOpenGL>(
this, resolver, enable_impeller_);
476 compositor_ = std::make_unique<CompositorSoftware>();
481 compositor.user_data =
this;
482 compositor.create_backing_store_callback =
487 return host->compositor_->CreateBackingStore(*config, backing_store_out);
490 compositor.collect_backing_store_callback =
494 return host->compositor_->CollectBackingStore(backing_store);
497 compositor.present_view_callback =
501 return host->Present(info);
503 args.compositor = &compositor;
506 args.aot_data = aot_data_.get();
511 FML_DCHECK(!egl_manager_ || !egl_manager_->HasContextCurrent());
515 if (enable_impeller_) {
519 FML_LOG(ERROR) <<
"Could not create surface manager. Impeller backend "
520 "does not support software rendering.";
523 renderer_config = GetOpenGLRendererConfig();
526 egl_manager_ ? GetOpenGLRendererConfig() : GetSoftwareRendererConfig();
530 &
args,
this, &engine_);
531 if (result !=
kSuccess || engine_ ==
nullptr) {
532 FML_LOG(ERROR) <<
"Failed to start Flutter engine: error " << result;
536 display_manager_->UpdateDisplays();
540 settings_plugin_->StartWatching();
541 settings_plugin_->SendSettings();
543 InitializeKeyboard();
548bool FlutterWindowsEngine::Stop() {
550 window_manager_->OnEngineShutdown();
551 for (
const auto& [
callback, registrar] :
552 plugin_registrar_destruction_callbacks_) {
562std::unique_ptr<FlutterWindowsView> FlutterWindowsEngine::CreateView(
563 std::unique_ptr<WindowBindingHandler>
window,
564 bool is_sized_to_content,
568 auto view = std::make_unique<FlutterWindowsView>(
569 view_id,
this, std::move(
window), is_sized_to_content, box_constraints,
570 sizing_delegate, windows_proc_table_);
572 view->CreateRenderSurface();
573 view->UpdateSemanticsEnabled(semantics_enabled_);
580 std::unique_lock write_lock(views_mutex_);
585 if (!
view->IsImplicitView()) {
592 Captures captures = {};
602 Captures* captures =
reinterpret_cast<Captures*
>(result->user_data);
603 captures->added = result->added;
604 captures->latch.Signal();
610 <<
"Starting the add view operation failed. FlutterEngineAddView "
611 "returned an unexpected result: "
612 << result <<
". This indicates a bug in the Windows embedder.";
622 captures.latch.Wait();
624 if (!captures.added) {
628 FML_LOG(ERROR) <<
"FlutterEngineAddView failed to add view";
629 std::unique_lock write_lock(views_mutex_);
635 return std::move(
view);
649 Captures captures = {};
659 Captures* captures =
reinterpret_cast<Captures*
>(result->user_data);
660 captures->removed = result->removed;
661 captures->latch.Signal();
666 FML_LOG(ERROR) <<
"Starting the remove view operation failed. "
667 "FlutterEngineRemoveView "
668 "returned an unexpected result: "
670 <<
". This indicates a bug in the Windows embedder.";
680 captures.latch.Wait();
682 if (!captures.removed) {
685 FML_LOG(ERROR) <<
"FlutterEngineRemoveView failed to remove view";
693 std::unique_lock write_lock(views_mutex_);
699 if (text_input_plugin_) {
700 text_input_plugin_->OnViewRemoved(
view_id);
707void FlutterWindowsEngine::OnVsync(intptr_t baton) {
708 std::chrono::nanoseconds current_time =
709 std::chrono::nanoseconds(embedder_api_.GetCurrentTime());
710 std::chrono::nanoseconds frame_interval = FrameInterval();
711 auto next = SnapToNextTick(current_time, start_time_, frame_interval);
712 embedder_api_.OnVsync(engine_, baton, next.count(),
713 (next + frame_interval).count());
716std::chrono::nanoseconds FlutterWindowsEngine::FrameInterval() {
717 if (frame_interval_override_.has_value()) {
718 return frame_interval_override_.value();
720 uint64_t interval = 16600000;
722 DWM_TIMING_INFO timing_info = {};
723 timing_info.cbSize =
sizeof(timing_info);
724 HRESULT result = DwmGetCompositionTimingInfo(NULL, &timing_info);
725 if (result == S_OK && timing_info.rateRefresh.uiDenominator > 0 &&
726 timing_info.rateRefresh.uiNumerator > 0) {
727 interval =
static_cast<double>(timing_info.rateRefresh.uiDenominator *
729 static_cast<double>(timing_info.rateRefresh.uiNumerator);
732 return std::chrono::nanoseconds(interval);
736 std::shared_lock read_lock(views_mutex_);
738 auto iterator = views_.find(
view_id);
739 if (iterator == views_.end()) {
743 return iterator->second;
748 return plugin_registrar_.get();
751void FlutterWindowsEngine::AddPluginRegistrarDestructionCallback(
754 plugin_registrar_destruction_callbacks_[
callback] = registrar;
757void FlutterWindowsEngine::UpdateDisplay(
758 const std::vector<FlutterEngineDisplay>&
displays) {
760 embedder_api_.NotifyDisplayUpdate(engine_,
766void FlutterWindowsEngine::SendWindowMetricsEvent(
769 embedder_api_.SendWindowMetricsEvent(engine_, &event);
775 embedder_api_.SendPointerEvent(engine_, &event, 1);
787void FlutterWindowsEngine::SendViewFocusEvent(
790 embedder_api_.SendViewFocusEvent(engine_, &event);
794bool FlutterWindowsEngine::SendPlatformMessage(
797 const size_t message_size,
801 if (reply !=
nullptr &&
user_data !=
nullptr) {
803 embedder_api_.PlatformMessageCreateResponseHandle(
804 engine_, reply,
user_data, &response_handle);
806 FML_LOG(ERROR) <<
"Failed to create response handle";
820 embedder_api_.SendPlatformMessage(engine_, &platform_message);
821 if (response_handle !=
nullptr) {
822 embedder_api_.PlatformMessageReleaseResponseHandle(engine_,
828void FlutterWindowsEngine::SendPlatformMessageResponse(
831 size_t data_length) {
832 embedder_api_.SendPlatformMessageResponse(engine_, handle,
data, data_length);
835void FlutterWindowsEngine::HandlePlatformMessage(
838 FML_LOG(ERROR) <<
"Invalid message size received. Expected: "
846 message_dispatcher_->HandleMessage(
message, [
this] {}, [
this] {});
849void FlutterWindowsEngine::ReloadSystemFonts() {
850 embedder_api_.ReloadSystemFonts(engine_);
853void FlutterWindowsEngine::ScheduleFrame() {
854 embedder_api_.ScheduleFrame(engine_);
858 next_frame_callback_ = std::move(
callback);
860 embedder_api_.SetNextFrameCallback(
868 self->task_runner_->PostTask(std::move(
self->next_frame_callback_));
873HCURSOR FlutterWindowsEngine::GetCursorByName(
874 const std::string& cursor_name)
const {
875 static auto* cursors =
new std::map<std::string, const wchar_t*>{
876 {
"allScroll", IDC_SIZEALL},
877 {
"basic", IDC_ARROW},
879 {
"forbidden", IDC_NO},
881 {
"move", IDC_SIZEALL},
884 {
"precise", IDC_CROSS},
885 {
"progress", IDC_APPSTARTING},
887 {
"resizeColumn", IDC_SIZEWE},
888 {
"resizeDown", IDC_SIZENS},
889 {
"resizeDownLeft", IDC_SIZENESW},
890 {
"resizeDownRight", IDC_SIZENWSE},
891 {
"resizeLeft", IDC_SIZEWE},
892 {
"resizeLeftRight", IDC_SIZEWE},
893 {
"resizeRight", IDC_SIZEWE},
894 {
"resizeRow", IDC_SIZENS},
895 {
"resizeUp", IDC_SIZENS},
896 {
"resizeUpDown", IDC_SIZENS},
897 {
"resizeUpLeft", IDC_SIZENWSE},
898 {
"resizeUpRight", IDC_SIZENESW},
899 {
"resizeUpLeftDownRight", IDC_SIZENWSE},
900 {
"resizeUpRightDownLeft", IDC_SIZENESW},
903 const wchar_t* idc_name = IDC_ARROW;
904 auto it = cursors->find(cursor_name);
905 if (it != cursors->end()) {
906 idc_name = it->second;
908 return windows_proc_table_->LoadCursor(
nullptr, idc_name);
913 std::shared_lock read_lock(views_mutex_);
914 auto const iterator =
915 std::find_if(views_.begin(), views_.end(), [hwnd](
auto const& pair) {
916 FlutterWindowsView* const view = pair.second;
917 return GetAncestor(view->GetWindowHandle(), GA_ROOT) == hwnd;
919 if (iterator != views_.end()) {
920 return iterator->second;
925void FlutterWindowsEngine::SendSystemLocales() {
926 std::vector<LanguageInfo> languages =
928 std::vector<FlutterLocale> flutter_locales;
929 flutter_locales.reserve(languages.size());
930 for (
const auto& info : languages) {
931 flutter_locales.push_back(CovertToFlutterLocale(info));
934 std::vector<const FlutterLocale*> flutter_locale_list;
935 flutter_locale_list.reserve(flutter_locales.size());
936 std::transform(flutter_locales.begin(), flutter_locales.end(),
937 std::back_inserter(flutter_locale_list),
938 [](
const auto& arg) ->
const auto* { return &arg; });
939 embedder_api_.UpdateLocales(engine_, flutter_locale_list.data(),
940 flutter_locale_list.size());
943void FlutterWindowsEngine::InitializeKeyboard() {
944 auto internal_plugin_messenger = internal_plugin_registrar_->messenger();
945 KeyboardKeyEmbedderHandler::GetKeyStateHandler get_key_state = GetKeyState;
946 KeyboardKeyEmbedderHandler::MapVirtualKeyToScanCode map_vk_to_scan =
948 return MapVirtualKey(virtual_key,
949 extended ? MAPVK_VK_TO_VSC_EX : MAPVK_VK_TO_VSC);
951 keyboard_key_handler_ = std::move(CreateKeyboardKeyHandler(
952 internal_plugin_messenger, get_key_state, map_vk_to_scan));
954 std::move(CreateTextInputPlugin(internal_plugin_messenger));
957std::unique_ptr<KeyboardHandlerBase>
958FlutterWindowsEngine::CreateKeyboardKeyHandler(
962 auto keyboard_key_handler = std::make_unique<KeyboardKeyHandler>(messenger);
963 keyboard_key_handler->AddDelegate(
964 std::make_unique<KeyboardKeyEmbedderHandler>(
969 get_key_state, map_vk_to_scan));
970 keyboard_key_handler->AddDelegate(
971 std::make_unique<KeyboardKeyChannelHandler>(messenger));
972 keyboard_key_handler->InitKeyboardChannel();
973 return keyboard_key_handler;
976std::unique_ptr<TextInputPlugin> FlutterWindowsEngine::CreateTextInputPlugin(
978 return std::make_unique<TextInputPlugin>(messenger,
this);
981bool FlutterWindowsEngine::RegisterExternalTexture(int64_t
texture_id) {
982 return (embedder_api_.RegisterExternalTexture(engine_,
texture_id) ==
986bool FlutterWindowsEngine::UnregisterExternalTexture(int64_t
texture_id) {
987 return (embedder_api_.UnregisterExternalTexture(engine_,
texture_id) ==
991bool FlutterWindowsEngine::MarkExternalTextureFrameAvailable(
993 return (embedder_api_.MarkExternalTextureFrameAvailable(
1001 auto captures =
new Captures();
1002 captures->callback = std::move(
callback);
1003 if (embedder_api_.PostRenderThreadTask(
1006 auto captures = reinterpret_cast<Captures*>(opaque);
1007 captures->callback();
1017bool FlutterWindowsEngine::DispatchSemanticsAction(
1028 .data_length =
data.GetSize(),
1030 return (embedder_api_.SendSemanticsAction(engine_, &info));
1033void FlutterWindowsEngine::UpdateSemanticsEnabled(
bool enabled) {
1034 if (engine_ && semantics_enabled_ != enabled) {
1035 std::shared_lock read_lock(views_mutex_);
1037 semantics_enabled_ = enabled;
1038 embedder_api_.UpdateSemanticsEnabled(engine_, enabled);
1039 for (
auto iterator = views_.begin(); iterator != views_.end(); iterator++) {
1040 iterator->second->UpdateSemanticsEnabled(enabled);
1045void FlutterWindowsEngine::OnPreEngineRestart() {
1047 InitializeKeyboard();
1050std::string FlutterWindowsEngine::GetExecutableName()
const {
1053 const std::string& executable_path = result.second;
1054 size_t last_separator = executable_path.find_last_of(
"/\\");
1055 if (last_separator == std::string::npos ||
1056 last_separator == executable_path.size() - 1) {
1057 return executable_path;
1059 return executable_path.substr(last_separator + 1);
1064void FlutterWindowsEngine::UpdateAccessibilityFeatures() {
1065 UpdateHighContrastMode();
1068void FlutterWindowsEngine::UpdateHighContrastMode() {
1069 high_contrast_enabled_ = windows_proc_table_->GetHighContrastEnabled();
1071 SendAccessibilityFeatures();
1072 settings_plugin_->UpdateHighContrastMode(high_contrast_enabled_);
1075void FlutterWindowsEngine::SendAccessibilityFeatures() {
1078 if (high_contrast_enabled_) {
1083 embedder_api_.UpdateAccessibilityFeatures(
1087void FlutterWindowsEngine::RequestApplicationQuit(HWND hwnd,
1091 platform_handler_->RequestAppExit(hwnd, wparam, lparam, exit_type, 0);
1094void FlutterWindowsEngine::OnQuit(std::optional<HWND> hwnd,
1095 std::optional<WPARAM> wparam,
1096 std::optional<LPARAM> lparam,
1098 lifecycle_manager_->Quit(hwnd, wparam, lparam, exit_code);
1101void FlutterWindowsEngine::OnDwmCompositionChanged() {
1102 if (display_manager_) {
1103 display_manager_->UpdateDisplays();
1106 std::shared_lock read_lock(views_mutex_);
1107 for (
auto iterator = views_.begin(); iterator != views_.end(); iterator++) {
1108 iterator->second->OnDwmCompositionChanged();
1112void FlutterWindowsEngine::OnWindowStateEvent(HWND hwnd,
1114 lifecycle_manager_->OnWindowStateEvent(hwnd, event);
1117std::optional<LRESULT> FlutterWindowsEngine::ProcessExternalWindowMessage(
1122 if (lifecycle_manager_) {
1123 return lifecycle_manager_->ExternalWindowMessage(hwnd,
message, wparam,
1126 return std::nullopt;
1129void FlutterWindowsEngine::UpdateFlutterCursor(
1130 const std::string& cursor_name)
const {
1131 SetFlutterCursor(GetCursorByName(cursor_name));
1134void FlutterWindowsEngine::SetFlutterCursor(HCURSOR cursor)
const {
1135 windows_proc_table_->SetCursor(cursor);
1138void FlutterWindowsEngine::OnChannelUpdate(std::string
name,
bool listening) {
1139 if (
name ==
"flutter/platform" && listening) {
1140 lifecycle_manager_->BeginProcessingExit();
1141 }
else if (
name ==
"flutter/lifecycle" && listening) {
1142 lifecycle_manager_->BeginProcessingLifecycle();
1146void FlutterWindowsEngine::OnViewFocusChangeRequest(
1148 std::shared_lock read_lock(views_mutex_);
1150 auto iterator = views_.find(request->
view_id);
1151 if (iterator == views_.end()) {
1163 std::shared_lock read_lock(views_mutex_);
1165 auto iterator = views_.find(info->
view_id);
1166 if (iterator == views_.end()) {
1170 FlutterWindowsView*
view = iterator->second;
1175bool FlutterWindowsEngine::HandleDisplayMonitorMessage(HWND hwnd,
1180 if (!display_manager_) {
1184 return display_manager_->HandleWindowMessage(hwnd,
message, wparam, lparam,
static void SetUp(BinaryMessenger *binary_messenger, AccessibilityPlugin *plugin)
FlutterWindowsEngine(const FlutterProjectBundle &project, std::shared_ptr< WindowsProcTable > windows_proc_table=nullptr)
void SetSwitches(const std::vector< std::string > &switches)
std::function< SHORT(UINT, bool)> MapVirtualKeyToScanCode
std::function< SHORT(int)> GetKeyStateHandler
static std::unique_ptr< Manager > Create(GpuPreference gpu_preference)
static std::shared_ptr< ProcTable > Create()
A Mapping like NonOwnedMapping, but uses Free as its release proc.
FlutterEngineResult FlutterEngineGetProcAddresses(FlutterEngineProcTable *table)
Gets the table of engine function pointers.
FlutterAccessibilityFeature
@ kFlutterAccessibilityFeatureHighContrast
Request that UI be rendered with darker colors.
@ kFlutterEngineDisplaysUpdateTypeStartup
void(* FlutterKeyEventCallback)(bool, void *)
#define FLUTTER_ENGINE_VERSION
#define SAFE_ACCESS(pointer, member, default_value)
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_BEGIN_DECLS FlutterViewId view_id
static FlutterDesktopMessage ConvertToDesktopMessage(const FlutterPlatformMessage &engine_message)
void(* FlutterDesktopBinaryReply)(const uint8_t *data, size_t data_size, void *user_data)
void(* FlutterDesktopOnPluginRegistrarDestroyed)(FlutterDesktopPluginRegistrarRef)
static constexpr char kAccessibilityChannelName[]
FlutterDesktopBinaryReply callback
#define FML_LOG(severity)
#define FML_UNREACHABLE()
#define FML_DCHECK(condition)
static constexpr FlutterViewId kImplicitViewId
WindowStateEvent
An event representing a change in window state that may update the.
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service host
std::vector< LanguageInfo > GetPreferredLanguageInfo()
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
std::pair< bool, std::string > GetExecutablePath()
std::string PathToUtf8(const std::filesystem::path &path)
std::function< void()> closure
FlutterAddViewCallback add_view_callback
FlutterViewId view_id
The identifier for the view to add. This must be unique.
const FlutterWindowMetricsEvent * view_metrics
An update to whether a message channel has a listener set or not.
void(* thread_priority_setter)(FlutterThreadPriority)
const FlutterTaskRunnerDescription * ui_task_runner
const FlutterTaskRunnerDescription * platform_task_runner
size_t struct_size
The size of this struct. Must be sizeof(FlutterCustomTaskRunners).
Function-pointer-based versions of the APIs above.
size_t struct_size
The size of this struct. Must be sizeof(FlutterEngineProcs).
FlutterEngineGetCurrentTimeFnPtr GetCurrentTime
FlutterEngineRunTaskFnPtr RunTask
const char * language_code
size_t struct_size
This size of this struct. Must be sizeof(FlutterLocale).
const char * country_code
ProcResolver gl_proc_resolver
BoolCallback make_current
size_t struct_size
The size of this struct. Must be sizeof(FlutterOpenGLRendererConfig).
TextureFrameCallback gl_external_texture_frame_callback
bool fbo_reset_after_present
BoolCallback make_resource_current
UIntFrameInfoCallback fbo_with_frame_info_callback
BoolCallback clear_current
size_t layers_count
The count of layers.
FlutterViewId view_id
The identifier of the target view.
const FlutterLayer ** layers
The layers that should be composited onto the view.
size_t struct_size
The size of this struct. Must be sizeof(FlutterProjectArgs).
FlutterRemoveViewCallback remove_view_callback
FlutterSoftwareRendererConfig software
FlutterOpenGLRendererConfig open_gl
A batch of updates to semantics nodes and custom actions.
size_t node_count
The number of semantics node updates.
size_t custom_action_count
The number of semantics custom action updates.
FlutterSemanticsNode2 ** nodes
FlutterSemanticsCustomAction2 ** custom_actions
size_t struct_size
The size of this struct. Must be sizeof(FlutterSoftwareRendererConfig).
SoftwareSurfacePresentCallback surface_present_callback
size_t struct_size
The size of this struct. Must be sizeof(FlutterTaskRunnerDescription).
BoolCallback runs_task_on_current_thread_callback
FlutterTaskRunnerPostTaskCallback post_task_callback
FlutterViewId view_id
The identifier of the view that received the focus event.
#define BASE_DCHECK(condition)