From fc5bc14e609116513f5dc458d16225910c74e2be Mon Sep 17 00:00:00 2001 From: "auto-submit[bot]" <98614782+auto-submit[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 23:19:48 +0000 Subject: [PATCH 01/32] Reverts "Output .js files as ES6 modules. (#52023)" (#53674) Reverts: flutter/engine#52023 Initiated by: eyebrowsoffire Reason for reverting: Causing issues in engine -> framework roll https://github.com/flutter/flutter/pull/151139 Original PR Author: eyebrowsoffire Reviewed By: {ditman} This change reverts the following previous change: This changes CanvasKit and Skwasm to be compiled and loaded as ES6 modules instead of as vanilla script tags. Currently, the emscripten JS files try to register themselves with require.js or AMD module loading systems. We suspect this is causing issues (https://github.com/flutter/flutter/issues/149565) with DDC's module loading system, which itself uses require.js. This is probably also the fix for https://github.com/flutter/flutter/issues/147731 --- DEPS | 2 +- lib/web_ui/flutter_js/src/canvaskit_loader.js | 33 +++++++---- lib/web_ui/flutter_js/src/skwasm_loader.js | 59 ++++++++++++------- .../src/engine/canvaskit/canvaskit_api.dart | 56 ++++++++++++------ lib/web_ui/lib/src/engine/dom.dart | 6 +- .../does_not_mock_module_exports_test.dart | 7 +++ 6 files changed, 110 insertions(+), 53 deletions(-) diff --git a/DEPS b/DEPS index 21a61f85249c2..3e8f6e46636f2 100644 --- a/DEPS +++ b/DEPS @@ -277,7 +277,7 @@ allowed_hosts = [ ] deps = { - 'src': 'https://github.com/flutter/buildroot.git' + '@' + '6c01dbca494b78e32f9e4aa704514faabfba74e8', + 'src': 'https://github.com/flutter/buildroot.git' + '@' + '8c2d66fa4e6298894425f5bdd0591bc5b1154c53', 'src/flutter/third_party/depot_tools': Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '580b4ff3f5cd0dcaa2eacda28cefe0f45320e8f7', diff --git a/lib/web_ui/flutter_js/src/canvaskit_loader.js b/lib/web_ui/flutter_js/src/canvaskit_loader.js index 4c8e91c7bc175..64dc6734ec273 100644 --- a/lib/web_ui/flutter_js/src/canvaskit_loader.js +++ b/lib/web_ui/flutter_js/src/canvaskit_loader.js @@ -6,11 +6,11 @@ import { createWasmInstantiator } from "./instantiate_wasm.js"; import { joinPathSegments } from "./utils.js"; export const loadCanvasKit = (deps, config, browserEnvironment, canvasKitBaseUrl) => { - window.flutterCanvasKitLoaded = (async () => { - if (window.flutterCanvasKit) { - // The user has set this global variable ahead of time, so we just return that. - return window.flutterCanvasKit; - } + if (window.flutterCanvasKit) { + // The user has set this global variable ahead of time, so we just return that. + return Promise.resolve(window.flutterCanvasKit); + } + window.flutterCanvasKitLoaded = new Promise((resolve, reject) => { const supportsChromiumCanvasKit = browserEnvironment.hasChromiumBreakIterators && browserEnvironment.hasImageCodecs; if (!supportsChromiumCanvasKit && config.canvasKitVariant == "chromium") { throw "Chromium CanvasKit variant specifically requested, but unsupported in this browser"; @@ -25,11 +25,24 @@ export const loadCanvasKit = (deps, config, browserEnvironment, canvasKitBaseUrl canvasKitUrl = deps.flutterTT.policy.createScriptURL(canvasKitUrl); } const wasmInstantiator = createWasmInstantiator(joinPathSegments(baseUrl, "canvaskit.wasm")); - const canvasKitModule = await import(canvasKitUrl); - window.flutterCanvasKit = await canvasKitModule.default({ - instantiateWasm: wasmInstantiator, + const script = document.createElement("script"); + script.src = canvasKitUrl; + if (config.nonce) { + script.nonce = config.nonce; + } + script.addEventListener("load", async () => { + try { + const canvasKit = await CanvasKitInit({ + instantiateWasm: wasmInstantiator, + }); + window.flutterCanvasKit = canvasKit; + resolve(canvasKit); + } catch (e) { + reject(e); + } }); - return window.flutterCanvasKit; - })(); + script.addEventListener("error", reject); + document.head.appendChild(script); + }); return window.flutterCanvasKitLoaded; } diff --git a/lib/web_ui/flutter_js/src/skwasm_loader.js b/lib/web_ui/flutter_js/src/skwasm_loader.js index 01b4fe3cb2375..241f4e8c81e02 100644 --- a/lib/web_ui/flutter_js/src/skwasm_loader.js +++ b/lib/web_ui/flutter_js/src/skwasm_loader.js @@ -5,28 +5,43 @@ import { createWasmInstantiator } from "./instantiate_wasm.js"; import { joinPathSegments } from "./utils.js"; -export const loadSkwasm = async (deps, config, browserEnvironment, baseUrl) => { - let skwasmUrl = joinPathSegments(baseUrl, "skwasm.js"); - if (deps.flutterTT.policy) { - skwasmUrl = deps.flutterTT.policy.createScriptURL(skwasmUrl); - } - const wasmInstantiator = createWasmInstantiator(joinPathSegments(baseUrl, "skwasm.wasm")); - const skwasm = await import(skwasmUrl); - return await skwasm.default({ - instantiateWasm: wasmInstantiator, - locateFile: (fileName, scriptDirectory) => { - // When hosted via a CDN or some other url that is not the same - // origin as the main script of the page, we will fail to create - // a web worker with the .worker.js script. This workaround will - // make sure that the worker JS can be loaded regardless of where - // it is hosted. - const url = scriptDirectory + fileName; - if (url.endsWith('.worker.js')) { - return URL.createObjectURL(new Blob( - [`importScripts('${url}');`], - { 'type': 'application/javascript' })); - } - return url; +export const loadSkwasm = (deps, config, browserEnvironment, baseUrl) => { + return new Promise((resolve, reject) => { + let skwasmUrl = joinPathSegments(baseUrl, "skwasm.js"); + if (deps.flutterTT.policy) { + skwasmUrl = deps.flutterTT.policy.createScriptURL(skwasmUrl); + } + const wasmInstantiator = createWasmInstantiator(joinPathSegments(baseUrl, "skwasm.wasm")); + const script = document.createElement("script"); + script.src = skwasmUrl; + if (config.nonce) { + script.nonce = config.nonce; } + script.addEventListener("load", async () => { + try { + const skwasmInstance = await skwasm({ + instantiateWasm: wasmInstantiator, + locateFile: (fileName, scriptDirectory) => { + // When hosted via a CDN or some other url that is not the same + // origin as the main script of the page, we will fail to create + // a web worker with the .worker.js script. This workaround will + // make sure that the worker JS can be loaded regardless of where + // it is hosted. + const url = scriptDirectory + fileName; + if (url.endsWith(".worker.js")) { + return URL.createObjectURL(new Blob( + [`importScripts("${url}");`], + { "type": "application/javascript" })); + } + return url; + } + }); + resolve(skwasmInstance); + } catch (e) { + reject(e); + } + }); + script.addEventListener("error", reject); + document.head.appendChild(script); }); } diff --git a/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart b/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart index 2e6e8dfc62a6e..c41da41b36aac 100644 --- a/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart +++ b/lib/web_ui/lib/src/engine/canvaskit/canvaskit_api.dart @@ -259,13 +259,12 @@ extension CanvasKitExtension on CanvasKit { ); } -@JS() -@staticInterop -class CanvasKitModule {} +@JS('window.CanvasKitInit') +external JSAny _CanvasKitInit(CanvasKitInitOptions options); -extension CanvasKitModuleExtension on CanvasKitModule { - @JS('default') - external JSPromise defaultExport(CanvasKitInitOptions options); +Future CanvasKitInit(CanvasKitInitOptions options) { + return js_util.promiseToFuture( + _CanvasKitInit(options).toObjectShallow); } typedef LocateFileCallback = String Function(String file, String unusedBase); @@ -3662,11 +3661,11 @@ String canvasKitWasmModuleUrl(String file, String canvasKitBase) => /// Downloads the CanvasKit JavaScript, then calls `CanvasKitInit` to download /// and intialize the CanvasKit wasm. Future downloadCanvasKit() async { - final CanvasKitModule canvasKitModule = await _downloadOneOf(_canvasKitJsUrls); + await _downloadOneOf(_canvasKitJsUrls); - final CanvasKit canvasKit = (await canvasKitModule.defaultExport(CanvasKitInitOptions( + final CanvasKit canvasKit = await CanvasKitInit(CanvasKitInitOptions( locateFile: createLocateFileCallback(canvasKitWasmModuleUrl), - )).toDart) as CanvasKit; + )); if (canvasKit.ParagraphBuilder.RequiresClientICU() && !browserSupportsCanvaskitChromium) { throw Exception( @@ -3682,12 +3681,10 @@ Future downloadCanvasKit() async { /// downloads it. /// /// If none of the URLs can be downloaded, throws an [Exception]. -Future _downloadOneOf(Iterable urls) async { +Future _downloadOneOf(Iterable urls) async { for (final String url in urls) { - try { - return await _downloadCanvasKitJs(url); - } catch (_) { - continue; + if (await _downloadCanvasKitJs(url)) { + return; } } @@ -3701,7 +3698,32 @@ Future _downloadOneOf(Iterable urls) async { /// /// Returns a [Future] that completes with `true` if the CanvasKit JavaScript /// file was successfully downloaded, or `false` if it failed. -Future _downloadCanvasKitJs(String url) async { - final JSAny scriptUrl = createTrustedScriptUrl(url); - return (await importModule(scriptUrl).toDart) as CanvasKitModule; +Future _downloadCanvasKitJs(String url) { + final DomHTMLScriptElement canvasKitScript = + createDomHTMLScriptElement(configuration.nonce); + canvasKitScript.src = createTrustedScriptUrl(url); + + final Completer canvasKitLoadCompleter = Completer(); + + late final DomEventListener loadCallback; + late final DomEventListener errorCallback; + + void loadEventHandler(DomEvent _) { + canvasKitScript.remove(); + canvasKitLoadCompleter.complete(true); + } + void errorEventHandler(DomEvent errorEvent) { + canvasKitScript.remove(); + canvasKitLoadCompleter.complete(false); + } + + loadCallback = createDomEventListener(loadEventHandler); + errorCallback = createDomEventListener(errorEventHandler); + + canvasKitScript.addEventListener('load', loadCallback); + canvasKitScript.addEventListener('error', errorCallback); + + domDocument.head!.appendChild(canvasKitScript); + + return canvasKitLoadCompleter.future; } diff --git a/lib/web_ui/lib/src/engine/dom.dart b/lib/web_ui/lib/src/engine/dom.dart index 14bde5e5def70..32d100df8f114 100644 --- a/lib/web_ui/lib/src/engine/dom.dart +++ b/lib/web_ui/lib/src/engine/dom.dart @@ -3407,16 +3407,16 @@ final DomTrustedTypePolicy _ttPolicy = domWindow.trustedTypes!.createPolicy( /// Converts a String `url` into a [DomTrustedScriptURL] object when the /// Trusted Types API is available, else returns the unmodified `url`. -JSAny createTrustedScriptUrl(String url) { +Object createTrustedScriptUrl(String url) { if (domWindow.trustedTypes != null) { // Pass `url` through Flutter Engine's TrustedType policy. final DomTrustedScriptURL trustedUrl = _ttPolicy.createScriptURL(url); assert(trustedUrl.url != '', 'URL: $url rejected by TrustedTypePolicy'); - return trustedUrl as JSAny; + return trustedUrl; } - return url.toJS; + return url; } DomMessageChannel createDomMessageChannel() => DomMessageChannel(); diff --git a/lib/web_ui/test/canvaskit/initialization/does_not_mock_module_exports_test.dart b/lib/web_ui/test/canvaskit/initialization/does_not_mock_module_exports_test.dart index 96e0c8a6d14d5..b6676f2af4fcf 100644 --- a/lib/web_ui/test/canvaskit/initialization/does_not_mock_module_exports_test.dart +++ b/lib/web_ui/test/canvaskit/initialization/does_not_mock_module_exports_test.dart @@ -18,6 +18,13 @@ void testMain() { // Initialize CanvasKit... await bootstrapAndRunApp(); + // CanvasKitInit should be defined... + expect( + js_util.hasProperty(domWindow, 'CanvasKitInit'), + isTrue, + reason: 'CanvasKitInit should be defined on Window', + ); + // window.exports and window.module should be undefined! expect( js_util.hasProperty(domWindow, 'exports'), From d3c5bd66a78f8563d1697733f507715665b6cb99 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Mon, 1 Jul 2024 23:47:25 -0400 Subject: [PATCH 02/32] Manual roll ICU from 98f2494518c2 to 43953f57b037 (1 revision) (#53675) Manual roll requested by fmil@google.com https://chromium.googlesource.com/chromium/deps/icu.git/+log/98f2494518c2..43953f57b037 2024-06-10 dayeung@chromium.org Fix a crash in locid.cpp. If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/icu-sdk-flutter-engine Please CC fmil@google.com,fuchsia-ui-discuss@google.com,jimgraham@google.com on the revert to ensure that a human is aware of the problem. To file a bug in ICU: https://github.com/unicode-org/icu To file a bug in Flutter Engine: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 3e8f6e46636f2..d4380dec851e1 100644 --- a/DEPS +++ b/DEPS @@ -307,7 +307,7 @@ deps = { Var('chromium_git') + '/external/github.com/google/flatbuffers' + '@' + '0a80646371179f8a7a5c1f42c31ee1d44dcf6709', 'src/flutter/third_party/icu': - Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '98f2494518c2dbb9c488e83e507b070ea5910e95', + Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '43953f57b037778a1b8005564afabe214834f7bd', 'src/flutter/third_party/gtest-parallel': Var('chromium_git') + '/external/github.com/google/gtest-parallel' + '@' + '38191e2733d7cbaeaef6a3f1a942ddeb38a2ad14', From 40c087b3151597f987a536fa0c03fec65fd5243a Mon Sep 17 00:00:00 2001 From: Robert Ancell Date: Tue, 2 Jul 2024 17:18:07 +1200 Subject: [PATCH 03/32] Restore creation of engine before Linux widget is realized. (#53604) Due to changes in the renderer in 6b857de the engine was created once a widget is realized, not when the widget is created. If a Flutter application changed the default my_application.cc template to show the Flutter widget after plugins are run then these plugins would not be able to access the engine. Solved by removing the GdkWindow from the renderer constructor and setting in later when the widget is realized. This works because the renderer is not used until the widget is realized. Fixes https://github.com/flutter/flutter/issues/144873 --- shell/platform/linux/fl_binary_messenger.cc | 38 ++++++------ .../linux/fl_binary_messenger_private.h | 8 +++ .../linux/fl_binary_messenger_test.cc | 2 +- shell/platform/linux/fl_engine.cc | 3 + shell/platform/linux/fl_renderer_gdk.cc | 13 +++- shell/platform/linux/fl_renderer_gdk.h | 13 +++- shell/platform/linux/fl_task_runner.cc | 34 ++++------- shell/platform/linux/fl_texture_registrar.cc | 60 ++++++++++--------- .../linux/fl_texture_registrar_private.h | 8 +++ shell/platform/linux/fl_view.cc | 21 ++++--- shell/platform/linux/fl_view_test.cc | 13 ++++ .../flutter_linux/fl_binary_messenger.h | 2 + .../flutter_linux/fl_texture_registrar.h | 2 + .../linux/testing/mock_binary_messenger.cc | 3 + 14 files changed, 139 insertions(+), 81 deletions(-) diff --git a/shell/platform/linux/fl_binary_messenger.cc b/shell/platform/linux/fl_binary_messenger.cc index 3a1a998e59721..16dcd2b86bbc1 100644 --- a/shell/platform/linux/fl_binary_messenger.cc +++ b/shell/platform/linux/fl_binary_messenger.cc @@ -149,18 +149,6 @@ static void platform_message_handler_free(gpointer data) { g_free(self); } -static void engine_weak_notify_cb(gpointer user_data, - GObject* where_the_object_was) { - FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(user_data); - - // Disconnect any handlers. - // Take the reference in case a handler tries to modify this table. - g_autoptr(GHashTable) handlers = self->platform_message_handlers; - self->platform_message_handlers = g_hash_table_new_full( - g_str_hash, g_str_equal, g_free, platform_message_handler_free); - g_hash_table_remove_all(handlers); -} - static gboolean fl_binary_messenger_platform_message_cb( FlEngine* engine, const gchar* channel, @@ -187,13 +175,6 @@ static gboolean fl_binary_messenger_platform_message_cb( static void fl_binary_messenger_impl_dispose(GObject* object) { FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(object); - { - g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine)); - if (engine) { - g_object_weak_unref(G_OBJECT(engine), engine_weak_notify_cb, self); - } - } - g_weak_ref_clear(&self->engine); g_clear_pointer(&self->platform_message_handlers, g_hash_table_unref); @@ -383,6 +364,17 @@ static void set_warns_on_channel_overflow(FlBinaryMessenger* messenger, set_warns_on_channel_overflow_response_cb, nullptr); } +static void shutdown(FlBinaryMessenger* messenger) { + FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(messenger); + + // Disconnect any handlers. + // Take the reference in case a handler tries to modify this table. + g_autoptr(GHashTable) handlers = self->platform_message_handlers; + self->platform_message_handlers = g_hash_table_new_full( + g_str_hash, g_str_equal, g_free, platform_message_handler_free); + g_hash_table_remove_all(handlers); +} + static void fl_binary_messenger_impl_class_init( FlBinaryMessengerImplClass* klass) { G_OBJECT_CLASS(klass)->dispose = fl_binary_messenger_impl_dispose; @@ -396,6 +388,7 @@ static void fl_binary_messenger_impl_iface_init( iface->send_on_channel_finish = send_on_channel_finish; iface->resize_channel = resize_channel; iface->set_warns_on_channel_overflow = set_warns_on_channel_overflow; + iface->shutdown = shutdown; } static void fl_binary_messenger_impl_init(FlBinaryMessengerImpl* self) { @@ -413,7 +406,6 @@ FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine) { FL_IS_BINARY_MESSENGER_IMPL(self); g_weak_ref_init(&self->engine, G_OBJECT(engine)); - g_object_weak_ref(G_OBJECT(engine), engine_weak_notify_cb, self); fl_engine_set_platform_message_handler( engine, fl_binary_messenger_platform_message_cb, self, NULL); @@ -490,3 +482,9 @@ G_MODULE_EXPORT void fl_binary_messenger_set_warns_on_channel_overflow( return FL_BINARY_MESSENGER_GET_IFACE(self)->set_warns_on_channel_overflow( self, channel, warns); } + +void fl_binary_messenger_shutdown(FlBinaryMessenger* self) { + g_return_if_fail(FL_IS_BINARY_MESSENGER(self)); + + return FL_BINARY_MESSENGER_GET_IFACE(self)->shutdown(self); +} diff --git a/shell/platform/linux/fl_binary_messenger_private.h b/shell/platform/linux/fl_binary_messenger_private.h index ce70c51dc61c6..e444e8f94e31b 100644 --- a/shell/platform/linux/fl_binary_messenger_private.h +++ b/shell/platform/linux/fl_binary_messenger_private.h @@ -22,6 +22,14 @@ G_BEGIN_DECLS */ FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine); +/** + * fl_binary_messenger_shutdown: + * @messenger: an #FlBinaryMessenger. + * + * Shutdown the messenger closing any open channels. + */ +void fl_binary_messenger_shutdown(FlBinaryMessenger* messenger); + G_END_DECLS #endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_BINARY_MESSENGER_PRIVATE_H_ diff --git a/shell/platform/linux/fl_binary_messenger_test.cc b/shell/platform/linux/fl_binary_messenger_test.cc index d27e07d8af9bf..85cbed4de90ba 100644 --- a/shell/platform/linux/fl_binary_messenger_test.cc +++ b/shell/platform/linux/fl_binary_messenger_test.cc @@ -634,7 +634,7 @@ static void kill_handler_notify_cb(gpointer was_called) { TEST(FlBinaryMessengerTest, DeletingEngineClearsHandlers) { FlEngine* engine = make_mock_engine(); - g_autoptr(FlBinaryMessenger) messenger = fl_binary_messenger_new(engine); + FlBinaryMessenger* messenger = fl_engine_get_binary_messenger(engine); gboolean was_killed = FALSE; // Listen for messages from the engine. diff --git a/shell/platform/linux/fl_engine.cc b/shell/platform/linux/fl_engine.cc index 42001f1decae0..ace289a1b08bb 100644 --- a/shell/platform/linux/fl_engine.cc +++ b/shell/platform/linux/fl_engine.cc @@ -399,6 +399,9 @@ static void fl_engine_dispose(GObject* object) { self->aot_data = nullptr; } + fl_binary_messenger_shutdown(self->binary_messenger); + fl_texture_registrar_shutdown(self->texture_registrar); + g_clear_object(&self->project); g_clear_object(&self->renderer); g_clear_object(&self->texture_registrar); diff --git a/shell/platform/linux/fl_renderer_gdk.cc b/shell/platform/linux/fl_renderer_gdk.cc index f48a6c78f132c..2cbb46e37dbd4 100644 --- a/shell/platform/linux/fl_renderer_gdk.cc +++ b/shell/platform/linux/fl_renderer_gdk.cc @@ -39,6 +39,7 @@ static void fl_renderer_gdk_clear_current(FlRenderer* renderer) { gdk_gl_context_clear_current(); } +// Implements FlRenderer::get_refresh_rate. static gdouble fl_renderer_gdk_get_refresh_rate(FlRenderer* renderer) { FlRendererGdk* self = FL_RENDERER_GDK(renderer); GdkDisplay* display = gdk_window_get_display(self->window); @@ -78,14 +79,22 @@ static void fl_renderer_gdk_class_init(FlRendererGdkClass* klass) { static void fl_renderer_gdk_init(FlRendererGdk* self) {} -FlRendererGdk* fl_renderer_gdk_new(GdkWindow* window) { +FlRendererGdk* fl_renderer_gdk_new() { FlRendererGdk* self = FL_RENDERER_GDK(g_object_new(fl_renderer_gdk_get_type(), nullptr)); - self->window = window; return self; } +void fl_renderer_gdk_set_window(FlRendererGdk* self, GdkWindow* window) { + g_return_if_fail(FL_IS_RENDERER_GDK(self)); + + g_assert(self->window == nullptr); + self->window = window; +} + gboolean fl_renderer_gdk_create_contexts(FlRendererGdk* self, GError** error) { + g_return_val_if_fail(FL_IS_RENDERER_GDK(self), FALSE); + self->gdk_context = gdk_window_create_gl_context(self->window, error); if (self->gdk_context == nullptr) { return FALSE; diff --git a/shell/platform/linux/fl_renderer_gdk.h b/shell/platform/linux/fl_renderer_gdk.h index e2b3f7bb1f961..89a8ee212a006 100644 --- a/shell/platform/linux/fl_renderer_gdk.h +++ b/shell/platform/linux/fl_renderer_gdk.h @@ -23,13 +23,22 @@ G_DECLARE_FINAL_TYPE(FlRendererGdk, /** * fl_renderer_gdk_new: - * @window: the window that is being rendered on. * * Creates an object that allows Flutter to render by OpenGL ES. * * Returns: a new #FlRendererGdk. */ -FlRendererGdk* fl_renderer_gdk_new(GdkWindow* window); +FlRendererGdk* fl_renderer_gdk_new(); + +/** + * fl_renderer_gdk_set_window: + * @renderer: an #FlRendererGdk. + * @window: the window that is being rendered on. + * + * Set the window that is being rendered on. This is only called once when the + * window is available. + */ +void fl_renderer_gdk_set_window(FlRendererGdk* renderer, GdkWindow* window); /** * fl_renderer_gdk_create_contexts: diff --git a/shell/platform/linux/fl_task_runner.cc b/shell/platform/linux/fl_task_runner.cc index ce9938915ccda..147550c504d3f 100644 --- a/shell/platform/linux/fl_task_runner.cc +++ b/shell/platform/linux/fl_task_runner.cc @@ -11,7 +11,7 @@ static constexpr int kMillisecondsPerMicrosecond = 1000; struct _FlTaskRunner { GObject parent_instance; - FlEngine* engine; + GWeakRef engine; GMutex mutex; GCond cond; @@ -51,11 +51,14 @@ static void fl_task_runner_process_expired_tasks_locked(FlTaskRunner* self) { g_mutex_unlock(&self->mutex); - l = expired_tasks; - while (l != nullptr && self->engine) { - FlTaskRunnerTask* task = static_cast(l->data); - fl_engine_execute_task(self->engine, &task->task); - l = l->next; + g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine)); + if (engine != nullptr) { + l = expired_tasks; + while (l != nullptr) { + FlTaskRunnerTask* task = static_cast(l->data); + fl_engine_execute_task(engine, &task->task); + l = l->next; + } } g_list_free_full(expired_tasks, g_free); @@ -120,12 +123,6 @@ static void fl_task_runner_tasks_did_change_locked(FlTaskRunner* self) { } } -static void engine_weak_notify_cb(gpointer user_data, - GObject* where_the_object_was) { - FlTaskRunner* self = FL_TASK_RUNNER(user_data); - self->engine = nullptr; -} - void fl_task_runner_dispose(GObject* object) { FlTaskRunner* self = FL_TASK_RUNNER(object); @@ -133,11 +130,7 @@ void fl_task_runner_dispose(GObject* object) { // main thread g_assert(!self->blocking_main_thread); - if (self->engine != nullptr) { - g_object_weak_unref(G_OBJECT(self->engine), engine_weak_notify_cb, self); - self->engine = nullptr; - } - + g_weak_ref_clear(&self->engine); g_mutex_clear(&self->mutex); g_cond_clear(&self->cond); @@ -159,11 +152,10 @@ static void fl_task_runner_init(FlTaskRunner* self) { } FlTaskRunner* fl_task_runner_new(FlEngine* engine) { - FlTaskRunner* res = + FlTaskRunner* self = FL_TASK_RUNNER(g_object_new(fl_task_runner_get_type(), nullptr)); - res->engine = engine; - g_object_weak_ref(G_OBJECT(engine), engine_weak_notify_cb, res); - return res; + g_weak_ref_init(&self->engine, G_OBJECT(engine)); + return self; } void fl_task_runner_post_task(FlTaskRunner* self, diff --git a/shell/platform/linux/fl_texture_registrar.cc b/shell/platform/linux/fl_texture_registrar.cc index 7ef0f85a04fd4..1b373f4d148fc 100644 --- a/shell/platform/linux/fl_texture_registrar.cc +++ b/shell/platform/linux/fl_texture_registrar.cc @@ -23,7 +23,7 @@ struct _FlTextureRegistrarImpl { GObject parent_instance; // Weak reference to the engine this texture registrar is created for. - FlEngine* engine; + GWeakRef engine; // ID to assign to the next new texture. int64_t next_id; @@ -54,20 +54,6 @@ G_DEFINE_TYPE_WITH_CODE( static void fl_texture_registrar_default_init( FlTextureRegistrarInterface* iface) {} -static void engine_weak_notify_cb(gpointer user_data, - GObject* where_the_object_was) { - FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(user_data); - self->engine = nullptr; - - // Unregister any textures. - g_mutex_lock(&self->textures_mutex); - g_autoptr(GHashTable) textures = self->textures; - self->textures = g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr, - g_object_unref); - g_hash_table_remove_all(textures); - g_mutex_unlock(&self->textures_mutex); -} - static void fl_texture_registrar_impl_dispose(GObject* object) { FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(object); @@ -75,10 +61,7 @@ static void fl_texture_registrar_impl_dispose(GObject* object) { g_clear_pointer(&self->textures, g_hash_table_unref); g_mutex_unlock(&self->textures_mutex); - if (self->engine != nullptr) { - g_object_weak_unref(G_OBJECT(self->engine), engine_weak_notify_cb, self); - self->engine = nullptr; - } + g_weak_ref_clear(&self->engine); g_mutex_clear(&self->textures_mutex); G_OBJECT_CLASS(fl_texture_registrar_impl_parent_class)->dispose(object); @@ -94,7 +77,8 @@ static gboolean register_texture(FlTextureRegistrar* registrar, FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar); if (FL_IS_TEXTURE_GL(texture) || FL_IS_PIXEL_BUFFER_TEXTURE(texture)) { - if (self->engine == nullptr) { + g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine)); + if (engine == nullptr) { return FALSE; } @@ -104,7 +88,7 @@ static gboolean register_texture(FlTextureRegistrar* registrar, // https://github.com/flutter/flutter/issues/124009 int64_t id = // self->next_id++; int64_t id = reinterpret_cast(texture); - if (fl_engine_register_external_texture(self->engine, id)) { + if (fl_engine_register_external_texture(engine, id)) { fl_texture_set_id(texture, id); g_mutex_lock(&self->textures_mutex); g_hash_table_insert(self->textures, GINT_TO_POINTER(id), @@ -134,11 +118,12 @@ static gboolean mark_texture_frame_available(FlTextureRegistrar* registrar, FlTexture* texture) { FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar); - if (self->engine == nullptr) { + g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine)); + if (engine == nullptr) { return FALSE; } - return fl_engine_mark_texture_frame_available(self->engine, + return fl_engine_mark_texture_frame_available(engine, fl_texture_get_id(texture)); } @@ -146,12 +131,13 @@ static gboolean unregister_texture(FlTextureRegistrar* registrar, FlTexture* texture) { FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar); - if (self->engine == nullptr) { + g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine)); + if (engine == nullptr) { return FALSE; } - gboolean result = fl_engine_unregister_external_texture( - self->engine, fl_texture_get_id(texture)); + gboolean result = + fl_engine_unregister_external_texture(engine, fl_texture_get_id(texture)); g_mutex_lock(&self->textures_mutex); if (!g_hash_table_remove(self->textures, @@ -163,12 +149,25 @@ static gboolean unregister_texture(FlTextureRegistrar* registrar, return result; } +static void shutdown(FlTextureRegistrar* registrar) { + FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL(registrar); + + // Unregister any textures. + g_mutex_lock(&self->textures_mutex); + g_autoptr(GHashTable) textures = self->textures; + self->textures = g_hash_table_new_full(g_direct_hash, g_direct_equal, nullptr, + g_object_unref); + g_hash_table_remove_all(textures); + g_mutex_unlock(&self->textures_mutex); +} + static void fl_texture_registrar_impl_iface_init( FlTextureRegistrarInterface* iface) { iface->register_texture = register_texture; iface->lookup_texture = lookup_texture; iface->mark_texture_frame_available = mark_texture_frame_available; iface->unregister_texture = unregister_texture; + iface->shutdown = shutdown; } static void fl_texture_registrar_impl_init(FlTextureRegistrarImpl* self) { @@ -213,6 +212,12 @@ G_MODULE_EXPORT gboolean fl_texture_registrar_unregister_texture( texture); } +void fl_texture_registrar_shutdown(FlTextureRegistrar* self) { + g_return_if_fail(FL_IS_TEXTURE_REGISTRAR(self)); + + return FL_TEXTURE_REGISTRAR_GET_IFACE(self)->shutdown(self); +} + FlTextureRegistrar* fl_texture_registrar_new(FlEngine* engine) { FlTextureRegistrarImpl* self = FL_TEXTURE_REGISTRAR_IMPL( g_object_new(fl_texture_registrar_impl_get_type(), nullptr)); @@ -220,8 +225,7 @@ FlTextureRegistrar* fl_texture_registrar_new(FlEngine* engine) { // Added to stop compiler complaining about an unused function. FL_IS_TEXTURE_REGISTRAR_IMPL(self); - self->engine = engine; - g_object_weak_ref(G_OBJECT(engine), engine_weak_notify_cb, self); + g_weak_ref_init(&self->engine, G_OBJECT(engine)); return FL_TEXTURE_REGISTRAR(self); } diff --git a/shell/platform/linux/fl_texture_registrar_private.h b/shell/platform/linux/fl_texture_registrar_private.h index 3f1e69b7fef4b..0ebbf48df438e 100644 --- a/shell/platform/linux/fl_texture_registrar_private.h +++ b/shell/platform/linux/fl_texture_registrar_private.h @@ -33,6 +33,14 @@ FlTextureRegistrar* fl_texture_registrar_new(FlEngine* engine); FlTexture* fl_texture_registrar_lookup_texture(FlTextureRegistrar* registrar, int64_t texture_id); +/** + * fl_texture_registrar_shutdown: + * @registrar: an #FlTextureRegistrar. + * + * Shutdown the registrary and unregister any textures. + */ +void fl_texture_registrar_shutdown(FlTextureRegistrar* registrar); + G_END_DECLS #endif // FLUTTER_SHELL_PLATFORM_LINUX_FL_TEXTURE_REGISTRAR_PRIVATE_H_ diff --git a/shell/platform/linux/fl_view.cc b/shell/platform/linux/fl_view.cc index 854749296b745..150de42b88f24 100644 --- a/shell/platform/linux/fl_view.cc +++ b/shell/platform/linux/fl_view.cc @@ -550,13 +550,8 @@ static gboolean window_state_event_cb(FlView* self, GdkEvent* event) { } static GdkGLContext* create_context_cb(FlView* self) { - self->renderer = - fl_renderer_gdk_new(gtk_widget_get_parent_window(GTK_WIDGET(self))); - self->engine = fl_engine_new(self->project, FL_RENDERER(self->renderer)); - fl_engine_set_update_semantics_handler(self->engine, update_semantics_cb, - self, nullptr); - fl_engine_set_on_pre_engine_restart_handler( - self->engine, on_pre_engine_restart_cb, self, nullptr); + fl_renderer_gdk_set_window(self->renderer, + gtk_widget_get_parent_window(GTK_WIDGET(self))); // Must initialize the keymap before the keyboard. self->keymap = gdk_keymap_get_for_display(gdk_display_get_default()); @@ -654,6 +649,17 @@ static void size_allocate_cb(FlView* self) { handle_geometry_changed(self); } +static void fl_view_constructed(GObject* object) { + FlView* self = FL_VIEW(object); + + self->renderer = fl_renderer_gdk_new(); + self->engine = fl_engine_new(self->project, FL_RENDERER(self->renderer)); + fl_engine_set_update_semantics_handler(self->engine, update_semantics_cb, + self, nullptr); + fl_engine_set_on_pre_engine_restart_handler( + self->engine, on_pre_engine_restart_cb, self, nullptr); +} + static void fl_view_set_property(GObject* object, guint prop_id, const GValue* value, @@ -750,6 +756,7 @@ static gboolean fl_view_key_release_event(GtkWidget* widget, static void fl_view_class_init(FlViewClass* klass) { GObjectClass* object_class = G_OBJECT_CLASS(klass); + object_class->constructed = fl_view_constructed; object_class->set_property = fl_view_set_property; object_class->get_property = fl_view_get_property; object_class->notify = fl_view_notify; diff --git a/shell/platform/linux/fl_view_test.cc b/shell/platform/linux/fl_view_test.cc index c36323cb04aca..db87bf8b2f7a4 100644 --- a/shell/platform/linux/fl_view_test.cc +++ b/shell/platform/linux/fl_view_test.cc @@ -7,6 +7,19 @@ #include "gtest/gtest.h" +TEST(FlViewTest, GetEngine) { + flutter::testing::fl_ensure_gtk_init(); + g_autoptr(FlDartProject) project = fl_dart_project_new(); + g_autoptr(FlView) view = fl_view_new(project); + + // Check the engine is immediately available (i.e. before the widget is + // realized). + FlEngine* engine = fl_view_get_engine(view); + EXPECT_NE(engine, nullptr); + + g_object_ref_sink(view); +} + TEST(FlViewTest, StateUpdateDoesNotHappenInInit) { flutter::testing::fl_ensure_gtk_init(); g_autoptr(FlDartProject) project = fl_dart_project_new(); diff --git a/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h b/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h index 4ac81862ed224..bdff02d40d471 100644 --- a/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h +++ b/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h @@ -104,6 +104,8 @@ struct _FlBinaryMessengerInterface { void (*set_warns_on_channel_overflow)(FlBinaryMessenger* messenger, const gchar* channel, bool warns); + + void (*shutdown)(FlBinaryMessenger* messenger); }; struct _FlBinaryMessengerResponseHandleClass { diff --git a/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h b/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h index 0034d345e902f..291f1644bee21 100644 --- a/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h +++ b/shell/platform/linux/public/flutter_linux/fl_texture_registrar.h @@ -37,6 +37,8 @@ struct _FlTextureRegistrarInterface { gboolean (*unregister_texture)(FlTextureRegistrar* registrar, FlTexture* texture); + + void (*shutdown)(FlTextureRegistrar* registrar); }; /** diff --git a/shell/platform/linux/testing/mock_binary_messenger.cc b/shell/platform/linux/testing/mock_binary_messenger.cc index ac1b05af3386a..8b22f2291bd75 100644 --- a/shell/platform/linux/testing/mock_binary_messenger.cc +++ b/shell/platform/linux/testing/mock_binary_messenger.cc @@ -141,6 +141,8 @@ static void fl_mock_binary_messenger_set_warns_on_channel_overflow( channel, warns); } +static void fl_mock_binary_messenger_shutdown(FlBinaryMessenger* messenger) {} + static void fl_mock_binary_messenger_iface_init( FlBinaryMessengerInterface* iface) { iface->set_message_handler_on_channel = @@ -152,6 +154,7 @@ static void fl_mock_binary_messenger_iface_init( iface->resize_channel = fl_mock_binary_messenger_resize_channel; iface->set_warns_on_channel_overflow = fl_mock_binary_messenger_set_warns_on_channel_overflow; + iface->shutdown = fl_mock_binary_messenger_shutdown; } static void fl_mock_binary_messenger_init(FlMockBinaryMessenger* self) {} From a2c40b46cd811becfa81f763b6ec330986c50e9c Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 2 Jul 2024 01:46:26 -0400 Subject: [PATCH 04/32] Roll Skia from 8375bdc6e191 to d7a9375e86c1 (1 revision) (#53676) https://skia.googlesource.com/skia.git/+log/8375bdc6e191..d7a9375e86c1 2024-07-02 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Dawn from 7a9c12078546 to 49474af63de0 (5 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,robertphillips@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index d4380dec851e1..9eaf33d78031e 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '8375bdc6e191da6e39be965969cab4014bfbc8d1', + 'skia_revision': 'd7a9375e86c11ab200e7cb1561baff6abf209613', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From 3f26068850856bbbc8d024b7f48bc593488eaa36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 05:57:23 +0000 Subject: [PATCH 05/32] Bump google/osv-scanner-action from 1.7.4 to 1.8.1 (#53677) Bumps [google/osv-scanner-action](https://github.com/google/osv-scanner-action) from 1.7.4 to 1.8.1.
Commits
  • 3c399db Merge pull request #29 from google/update-to-v1.8.1
  • 3ea235a Update unified workflow example to point to v1.8.1 reusable workflows
  • 6d2b388 Update reusable workflows to point to v1.8.1 actions
  • cd72c04 Update actions to use v1.8.1 osv-scanner image
  • f0e45d2 Update workflows (#19)
  • f92c263 Update workflows to v1.7.4 (#25)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=google/osv-scanner-action&package-manager=github_actions&previous-version=1.7.4&new-version=1.8.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- .github/workflows/third_party_scan.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/third_party_scan.yml b/.github/workflows/third_party_scan.yml index b87cfebc0763c..81d7c584fd00e 100644 --- a/.github/workflows/third_party_scan.yml +++ b/.github/workflows/third_party_scan.yml @@ -41,7 +41,7 @@ jobs: name: Vulnerability scanning needs: extract-deps - uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@v1.7.4" + uses: "google/osv-scanner-action/.github/workflows/osv-scanner-reusable.yml@v1.8.1" with: # Download the artifact uploaded in extract-deps step download-artifact: osv-lockfile-${{github.sha}} From 37d959c16a7b35e20594878032f6cb9d2444f569 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jul 2024 06:03:22 +0000 Subject: [PATCH 06/32] Bump github/codeql-action from 3.25.10 to 3.25.11 (#53678) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.10 to 3.25.11.
Changelog

Sourced from github/codeql-action's changelog.

CodeQL Action Changelog

See the releases page for the relevant changes to the CodeQL CLI and language packs.

Note that the only difference between v2 and v3 of the CodeQL Action is the node version they support, with v3 running on node 20 while we continue to release v2 to support running on node 16. For example 3.22.11 was the first v3 release and is functionally identical to 2.22.11. This approach ensures an easy way to track exactly which features are included in different versions, indicated by the minor and patch version numbers.

[UNRELEASED]

No user facing changes.

3.25.11 - 28 Jun 2024

  • Avoid failing the workflow run if there is an error while uploading debug artifacts. #2349
  • Update default CodeQL bundle version to 2.17.6. #2352

3.25.10 - 13 Jun 2024

  • Update default CodeQL bundle version to 2.17.5. #2327

3.25.9 - 12 Jun 2024

  • Avoid failing database creation if the database folder already exists and contains some unexpected files. Requires CodeQL 2.18.0 or higher. #2330
  • The init Action will attempt to clean up the database cluster directory before creating a new database and at the end of the job. This will help to avoid issues where the database cluster directory is left in an inconsistent state. #2332

3.25.8 - 04 Jun 2024

  • Update default CodeQL bundle version to 2.17.4. #2321

3.25.7 - 31 May 2024

  • We are rolling out a feature in May/June 2024 that will reduce the Actions cache usage of the Action by keeping only the newest TRAP cache for each language. #2306

3.25.6 - 20 May 2024

  • Update default CodeQL bundle version to 2.17.3. #2295

3.25.5 - 13 May 2024

  • Add a compatibility matrix of supported CodeQL Action, CodeQL CLI, and GitHub Enterprise Server versions to the https://github.com/github/codeql-action/blob/main/README.md. #2273
  • Avoid printing out a warning for a missing on.push trigger when the CodeQL Action is triggered via a workflow_call event. #2274
  • The tools: latest input to the init Action has been renamed to tools: linked. This option specifies that the Action should use the tools shipped at the same time as the Action. The old name will continue to work for backwards compatibility, but we recommend that new workflows use the new name. #2281

3.25.4 - 08 May 2024

  • Update default CodeQL bundle version to 2.17.2. #2270

3.25.3 - 25 Apr 2024

  • Update default CodeQL bundle version to 2.17.1. #2247
  • Workflows running on macos-latest using CodeQL CLI versions before v2.15.1 will need to either upgrade their CLI version to v2.15.1 or newer, or change the platform to an Intel MacOS runner, such as macos-12. ARM machines with SIP disabled, including the newest macos-latest image, are unsupported for CLI versions before 2.15.1. #2261

... (truncated)

Commits
  • b611370 Merge pull request #2357 from github/update-v3.25.11-de945755c
  • 3e6431f Update changelog for v3.25.11
  • de94575 Merge pull request #2352 from github/update-bundle/codeql-bundle-v2.17.6
  • a32d305 Add changelog note
  • 9ccc995 Update default bundle to codeql-bundle-v2.17.6
  • 9b7c22c Merge pull request #2351 from github/dependabot/npm_and_yarn/npm-6791eaa26c
  • 9cf3243 Rebuild
  • 1895b29 Update checked-in dependencies
  • 9dcfde9 Bump the npm group with 2 updates
  • 8723b5b Merge pull request #2350 from github/angelapwen/add-exclude-pr-check-param
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github/codeql-action&package-manager=github_actions&previous-version=3.25.10&new-version=3.25.11)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
--- .github/workflows/scorecards-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index 2cd5bd4eb0465..5eeabcc3e89ad 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -49,6 +49,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@23acc5c183826b7a8a97bce3cecc52db901f8251 + uses: github/codeql-action/upload-sarif@b611370bb5703a7efb587f9d136a52ea24c5c38c with: sarif_file: results.sarif From cc24bbb859c9ef200d537577a608707e4d84e772 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 2 Jul 2024 03:06:32 -0400 Subject: [PATCH 07/32] Roll Skia from d7a9375e86c1 to 4c1856aadb85 (2 revisions) (#53680) https://skia.googlesource.com/skia.git/+log/d7a9375e86c1..4c1856aadb85 2024-07-02 skia-autoroll@skia-public.iam.gserviceaccount.com Roll SK Tool from a06878f25d87 to a4c3d29a3f7c 2024-07-02 skia-autoroll@skia-public.iam.gserviceaccount.com Roll Skia Infra from ca190d337809 to a06878f25d87 (6 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC brianosman@google.com,jimgraham@google.com,rmistry@google.com,robertphillips@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 9eaf33d78031e..5051ea5c64968 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': 'd7a9375e86c11ab200e7cb1561baff6abf209613', + 'skia_revision': '4c1856aadb85ad6c7593458cf1d4248c2e9f64a6', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 3087654137624..7e56f071e5821 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 2856c45f73ed1da0f00d150abb3fcc36 +Signature: 0378bad4f6da99ea3ee2c19f9bb4bcbc ==================================================================================================== LIBRARY: etc1 From 8b1e1725e0724ea8efe5ed6beab9cbb0bb8f3a8f Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 2 Jul 2024 05:22:15 -0400 Subject: [PATCH 08/32] Roll Skia from 4c1856aadb85 to 7881ad4aae92 (1 revision) (#53681) https://skia.googlesource.com/skia.git/+log/4c1856aadb85..7881ad4aae92 2024-07-02 skia-autoroll@skia-public.iam.gserviceaccount.com Roll ANGLE from 4f23429a1f09 to d8700dc951b6 (3 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC aaclarke@google.com,brianosman@google.com,rmistry@google.com,robertphillips@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 5051ea5c64968..0bd98aa0194be 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '4c1856aadb85ad6c7593458cf1d4248c2e9f64a6', + 'skia_revision': '7881ad4aae92dee1915cc255f8687b5e5b159814', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From 7dbb09f0dfcb7933b1b31172b149747f9cd5c5cf Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 2 Jul 2024 06:03:22 -0400 Subject: [PATCH 09/32] Roll Fuchsia Linux SDK from LkXpxHsQlkPT4mmJ7... to x5Sccm0dUoMVbnyed... (#53682) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/fuchsia-linux-sdk-flutter-engine Please CC aaclarke@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_fuchsia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 0bd98aa0194be..696c6e6ab6b1d 100644 --- a/DEPS +++ b/DEPS @@ -969,7 +969,7 @@ deps = { 'packages': [ { 'package': 'fuchsia/sdk/core/linux-amd64', - 'version': 'LkXpxHsQlkPT4mmJ7i9vS0-GQmceOV-FpTF-9wxfMFUC' + 'version': 'x5Sccm0dUoMVbnyedBRmQ1bm8LjrmDyFDf_3pdUUiAUC' } ], 'condition': 'download_fuchsia_deps and not download_fuchsia_sdk', diff --git a/ci/licenses_golden/licenses_fuchsia b/ci/licenses_golden/licenses_fuchsia index 370f75a0225af..f283872731a05 100644 --- a/ci/licenses_golden/licenses_fuchsia +++ b/ci/licenses_golden/licenses_fuchsia @@ -1,4 +1,4 @@ -Signature: d94be6f5460ab5223d58b2c2defd09d8 +Signature: 902fb049be78edf94ee91b97911dc652 ==================================================================================================== LIBRARY: fuchsia_sdk From 433d360eee1129e499332b8a39828b576943257c Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 2 Jul 2024 07:19:41 -0400 Subject: [PATCH 10/32] Roll Skia from 7881ad4aae92 to 7f2094d4cf43 (1 revision) (#53683) https://skia.googlesource.com/skia.git/+log/7881ad4aae92..7f2094d4cf43 2024-07-02 skia-autoroll@skia-public.iam.gserviceaccount.com Roll vulkan-deps from bbcdf62c225f to 5faad80a00af (5 revisions) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC aaclarke@google.com,brianosman@google.com,rmistry@google.com,robertphillips@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DEPS b/DEPS index 696c6e6ab6b1d..6d8410608dd19 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '7881ad4aae92dee1915cc255f8687b5e5b159814', + 'skia_revision': '7f2094d4cf437d689ace5df2201b8192dfebcd44', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. From ad80c4e828ff674243924e83f7e114bb0d240d40 Mon Sep 17 00:00:00 2001 From: skia-flutter-autoroll Date: Tue, 2 Jul 2024 12:23:19 -0400 Subject: [PATCH 11/32] Roll Skia from 7f2094d4cf43 to 42fad315c162 (1 revision) (#53684) https://skia.googlesource.com/skia.git/+log/7f2094d4cf43..42fad315c162 2024-07-02 johnstiles@google.com Avoid emitting unnecessary stack_rewind SkRP ops. If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/skia-flutter-autoroll Please CC aaclarke@google.com,brianosman@google.com,rmistry@google.com,robertphillips@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Skia: https://bugs.chromium.org/p/skia/issues/entry To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md --- DEPS | 2 +- ci/licenses_golden/licenses_skia | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DEPS b/DEPS index 6d8410608dd19..67d00715a27ba 100644 --- a/DEPS +++ b/DEPS @@ -14,7 +14,7 @@ vars = { 'flutter_git': 'https://flutter.googlesource.com', 'skia_git': 'https://skia.googlesource.com', 'llvm_git': 'https://llvm.googlesource.com', - 'skia_revision': '7f2094d4cf437d689ace5df2201b8192dfebcd44', + 'skia_revision': '42fad315c16270b2eea9af833ea33fdb1040e8f9', # WARNING: DO NOT EDIT canvaskit_cipd_instance MANUALLY # See `lib/web_ui/README.md` for how to roll CanvasKit to a new version. diff --git a/ci/licenses_golden/licenses_skia b/ci/licenses_golden/licenses_skia index 7e56f071e5821..c4b3e4f4cf279 100644 --- a/ci/licenses_golden/licenses_skia +++ b/ci/licenses_golden/licenses_skia @@ -1,4 +1,4 @@ -Signature: 0378bad4f6da99ea3ee2c19f9bb4bcbc +Signature: 1a4a7521c5a0536e7f69b43f0b1b0350 ==================================================================================================== LIBRARY: etc1 From 5be433c65b2a42c0ab242a29bb332af25995cd24 Mon Sep 17 00:00:00 2001 From: Kaylee Lubick Date: Tue, 2 Jul 2024 12:44:02 -0400 Subject: [PATCH 12/32] [skia] Use more GNI file lists (#53685) In http://review.skia.org/862177 (and to a lesser extent, http://review.skia.org/862416), Skia added more .gni file lists for code in src/ports. This updates Flutter to use those lists instead of hard-coding those file paths directly, making it easier for upstream changes in Skia (e.g. file renames or relocations) to be pulled into Flutter without a Flutter-side change. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide] and the [C++, Objective-C, Java style guides]. - [ ] I listed at least one issue that this PR fixes in the description above. - [x] I added new tests to check the change I am making or feature I am adding, or the PR is [test-exempt]. See [testing the engine] for instructions on writing and running engine tests. - [ ] I updated/added relevant documentation (doc comments with `///`). - [x] I signed the [CLA]. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. [Contributor Guide]: https://github.com/flutter/flutter/wiki/Tree-hygiene#overview [Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene [test-exempt]: https://github.com/flutter/flutter/wiki/Tree-hygiene#tests [Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style [testing the engine]: https://github.com/flutter/flutter/wiki/Testing-the-engine [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/wiki/Chat --- skia/BUILD.gn | 70 ++++++++++++++++++--------------------------------- 1 file changed, 24 insertions(+), 46 deletions(-) diff --git a/skia/BUILD.gn b/skia/BUILD.gn index 31956cf645f84..e3cd3698f440f 100644 --- a/skia/BUILD.gn +++ b/skia/BUILD.gn @@ -218,12 +218,8 @@ optional("fontmgr_android") { ":typeface_freetype", "//flutter/third_party/expat", ] - public = [ "$_skia_root/include/ports/SkFontMgr_android.h" ] - sources = [ - "$_skia_root/src/ports/SkFontMgr_android.cpp", - "$_skia_root/src/ports/SkFontMgr_android_parser.cpp", - "$_skia_root/src/ports/SkFontMgr_android_parser.h", - ] + public = skia_ports_fontmgr_android_public + sources = skia_ports_fontmgr_android_sources } optional("fontmgr_custom") { @@ -232,8 +228,7 @@ optional("fontmgr_custom") { skia_enable_fontmgr_custom_embedded || skia_enable_fontmgr_custom_empty deps = [ ":typeface_freetype" ] - public = [ "$_skia_root/src/ports/SkFontMgr_custom.h" ] - sources = [ "$_skia_root/src/ports/SkFontMgr_custom.cpp" ] + sources = skia_ports_fontmgr_custom_sources } optional("fontmgr_custom_directory") { @@ -243,8 +238,8 @@ optional("fontmgr_custom_directory") { ":fontmgr_custom", ":typeface_freetype", ] - public = [ "$_skia_root/include/ports/SkFontMgr_directory.h" ] - sources = [ "$_skia_root/src/ports/SkFontMgr_custom_directory.cpp" ] + public = skia_ports_fontmgr_directory_public + sources = skia_ports_fontmgr_directory_sources } optional("fontmgr_custom_embedded") { @@ -255,7 +250,7 @@ optional("fontmgr_custom_embedded") { ":fontmgr_custom", ":typeface_freetype", ] - sources = [ "$_skia_root/src/ports/SkFontMgr_custom_embedded.cpp" ] + sources = skia_ports_fontmgr_embedded_sources } optional("fontmgr_custom_empty") { @@ -266,8 +261,8 @@ optional("fontmgr_custom_empty") { ":fontmgr_custom", ":typeface_freetype", ] - public = [ "$_skia_root/include/ports/SkFontMgr_empty.h" ] - sources = [ "$_skia_root/src/ports/SkFontMgr_custom_empty.cpp" ] + public = skia_ports_fontmgr_empty_public + sources = skia_ports_fontmgr_empty_sources } optional("fontmgr_fontconfig") { @@ -276,9 +271,9 @@ optional("fontmgr_fontconfig") { # The public header includes fontconfig.h and uses FcConfig* public_deps = [ "//third_party:fontconfig" ] - public = [ "$_skia_root/include/ports/SkFontMgr_fontconfig.h" ] + public = skia_ports_fontmgr_fontconfig_public deps = [ ":typeface_freetype" ] - sources = [ "$_skia_root/src/ports/SkFontMgr_fontconfig.cpp" ] + sources = skia_ports_fontmgr_fontconfig_sources } optional("fontmgr_fuchsia") { @@ -292,8 +287,8 @@ optional("fontmgr_fuchsia") { } else { deps = [ "//sdk/fidl/fuchsia.fonts" ] } - public = [ "$_skia_root/src/ports/SkFontMgr_fuchsia.h" ] - sources = [ "$_skia_root/src/ports/SkFontMgr_fuchsia.cpp" ] + public = skia_ports_fontmgr_fuchsia_public + sources = skia_ports_fontmgr_fuchsia_sources } optional("fontmgr_mac_ct") { @@ -303,17 +298,8 @@ optional("fontmgr_mac_ct") { "SK_TYPEFACE_FACTORY_CORETEXT", "SK_FONTMGR_CORETEXT_AVAILABLE", ] - public = [ - "$_skia_root/include/ports/SkFontMgr_mac_ct.h", - "$_skia_root/include/ports/SkTypeface_mac.h", - ] - sources = [ - "$_skia_root/src/ports/SkFontMgr_mac_ct.cpp", - "$_skia_root/src/ports/SkScalerContext_mac_ct.cpp", - "$_skia_root/src/ports/SkScalerContext_mac_ct.h", - "$_skia_root/src/ports/SkTypeface_mac_ct.cpp", - "$_skia_root/src/ports/SkTypeface_mac_ct.h", - ] + public = skia_ports_fontmgr_coretext_public + sources = skia_ports_fontmgr_coretext_sources if (is_mac) { frameworks = [ @@ -342,14 +328,8 @@ optional("fontmgr_win") { "SK_TYPEFACE_FACTORY_DIRECTWRITE", "SK_FONTMGR_DIRECTWRITE_AVAILABLE", ] - public = [ "$_skia_root/include/ports/SkTypeface_win.h" ] - sources = [ - "$_skia_root/src/ports/SkFontMgr_win_dw.cpp", - "$_skia_root/src/ports/SkScalerContext_win_dw.cpp", - "$_skia_root/src/ports/SkScalerContext_win_dw.h", - "$_skia_root/src/ports/SkTypeface_win_dw.cpp", - "$_skia_root/src/ports/SkTypeface_win_dw.h", - ] + public = skia_ports_windows_fonts_public + sources = skia_ports_windows_fonts_sources if (skia_dwritecore_sdk != "") { defines = [ "DWRITE_CORE" ] if (is_win && is_clang) { @@ -377,7 +357,9 @@ optional("gpu_shared") { public_deps = [] frameworks = [] - sources = skia_shared_gpu_sources + skia_sksl_gpu_sources + sources = skia_shared_gpu_sources + sources += skia_sksl_pipeline_sources + sources += skia_sksl_codegen_sources if (skia_use_vulkan) { public_defines += [ "SK_VULKAN" ] @@ -565,11 +547,7 @@ optional("typeface_freetype") { public_defines = [ "SK_TYPEFACE_FACTORY_FREETYPE" ] deps = [ "//flutter/third_party/freetype2" ] - sources = [ - "$_skia_root/src/ports/SkFontHost_FreeType.cpp", - "$_skia_root/src/ports/SkFontHost_FreeType_common.cpp", - "$_skia_root/src/ports/SkFontHost_FreeType_common.h", - ] + sources = skia_ports_freetype_sources } optional("webp_decode") { @@ -663,7 +641,9 @@ skia_component("skia") { sources += skia_codec_core sources += skia_codec_decode_bmp sources += skia_encode_srcs - sources += skia_sksl_sources + sources += skia_sksl_core_sources + sources += skia_sksl_default_module_sources + sources += skia_ports_sources sources += [ "$_skia_root/src/android/SkAndroidFrameworkUtils.cpp", "$_skia_root/src/android/SkAnimatedImage.cpp", @@ -673,9 +653,7 @@ skia_component("skia") { "$_skia_root/src/codec/SkParseEncodedOrigin.cpp", "$_skia_root/src/codec/SkSampledCodec.cpp", "$_skia_root/src/ports/SkDiscardableMemory_none.cpp", - "$_skia_root/src/ports/SkGlobalInitialization_default.cpp", "$_skia_root/src/ports/SkMemory_malloc.cpp", - "$_skia_root/src/ports/SkOSFile_stdio.cpp", "$_skia_root/src/sfnt/SkOTTable_name.cpp", "$_skia_root/src/sfnt/SkOTUtils.cpp", ] @@ -694,10 +672,10 @@ skia_component("skia") { } if (is_win) { + sources += skia_ports_windows_sources sources += [ "$_skia_root/src/ports/SkDebug_win.cpp", "$_skia_root/src/ports/SkImageGeneratorWIC.cpp", - "$_skia_root/src/ports/SkOSFile_win.cpp", "$_skia_root/src/ports/SkOSLibrary_win.cpp", ] libs += [ From 0409cc5866511019a4b04aa92adcaa5b0d2cf6b8 Mon Sep 17 00:00:00 2001 From: Jia Hao Date: Wed, 3 Jul 2024 01:02:06 +0800 Subject: [PATCH 13/32] Revert "[web] switch from .didGain/LoseAccessibilityFocus to .focus" (#53679) Reverts flutter/engine#53360 Breaking google3 in b/350131288. There is a test that does something like the following, to check if a radio button is selected. ```dart // Send a bunch of tabs to focus on the correct radio button await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.pump(); await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.pump(); await tester.sendKeyEvent(LogicalKeyboardKey.tab); await tester.pump(); // Toggle the radio button with space await tester.sendKeyEvent(LogicalKeyboardKey.space); await tester.pump(); final selectedRadio = tester.widget>(find.byType(Radio).at(1)); expect(selectedRadio.value, isTrue); ``` After this commit, the above test fails. See the linked bug above for more details. --- lib/ui/semantics.dart | 3 - lib/web_ui/lib/src/engine/dom.dart | 24 - .../lib/src/engine/semantics/focusable.dart | 17 +- .../lib/src/engine/semantics/semantics.dart | 2 + .../lib/src/engine/semantics/text_field.dart | 258 +++++-- .../src/engine/text_editing/text_editing.dart | 24 +- .../test/engine/semantics/semantics_test.dart | 94 ++- .../engine/semantics/semantics_tester.dart | 4 - .../engine/semantics/text_field_test.dart | 729 ++++++++++++++---- 9 files changed, 898 insertions(+), 257 deletions(-) diff --git a/lib/ui/semantics.dart b/lib/ui/semantics.dart index 481c9c3cbc525..57bc1fa30726d 100644 --- a/lib/ui/semantics.dart +++ b/lib/ui/semantics.dart @@ -220,9 +220,6 @@ class SemanticsAction { /// must immediately become editable, opening a virtual keyboard, if needed. /// Buttons must respond to tap/click events from the keyboard. /// - /// Widget reaction to this action must be idempotent. It is possible to - /// receive this action more than once, or when the widget is already focused. - /// /// Focus behavior is specific to the platform and to the assistive technology /// used. Typically on desktop operating systems, such as Windows, macOS, and /// Linux, moving accessibility focus will also move the input focus. On diff --git a/lib/web_ui/lib/src/engine/dom.dart b/lib/web_ui/lib/src/engine/dom.dart index 32d100df8f114..b81bba41245f2 100644 --- a/lib/web_ui/lib/src/engine/dom.dart +++ b/lib/web_ui/lib/src/engine/dom.dart @@ -2753,30 +2753,6 @@ DomCompositionEvent createDomCompositionEvent(String type, } } -/// This is a pseudo-type for DOM elements that have the boolean `disabled` -/// property. -/// -/// This type cannot be part of the actual type hierarchy because each DOM type -/// defines its `disabled` property ad hoc, without inheriting it from a common -/// type, e.g. [DomHTMLInputElement] and [DomHTMLTextAreaElement]. -/// -/// To use, simply cast any element known to have the `disabled` property to -/// this type using `as DomElementWithDisabledProperty`, then read and write -/// this property as normal. -@JS() -@staticInterop -class DomElementWithDisabledProperty extends DomHTMLElement {} - -extension DomElementWithDisabledPropertyExtension on DomElementWithDisabledProperty { - @JS('disabled') - external JSBoolean? get _disabled; - bool? get disabled => _disabled?.toDart; - - @JS('disabled') - external set _disabled(JSBoolean? value); - set disabled(bool? value) => _disabled = value?.toJS; -} - @JS() @staticInterop class DomHTMLInputElement extends DomHTMLElement {} diff --git a/lib/web_ui/lib/src/engine/semantics/focusable.dart b/lib/web_ui/lib/src/engine/semantics/focusable.dart index 331e1cd50c061..35fff64a50158 100644 --- a/lib/web_ui/lib/src/engine/semantics/focusable.dart +++ b/lib/web_ui/lib/src/engine/semantics/focusable.dart @@ -81,6 +81,9 @@ typedef _FocusTarget = ({ /// The listener for the "focus" DOM event. DomEventListener domFocusListener, + + /// The listener for the "blur" DOM event. + DomEventListener domBlurListener, }); /// Implements accessibility focus management for arbitrary elements. @@ -132,6 +135,7 @@ class AccessibilityFocusManager { semanticsNodeId: semanticsNodeId, element: previousTarget.element, domFocusListener: previousTarget.domFocusListener, + domBlurListener: previousTarget.domBlurListener, ); return; } @@ -144,12 +148,14 @@ class AccessibilityFocusManager { final _FocusTarget newTarget = ( semanticsNodeId: semanticsNodeId, element: element, - domFocusListener: createDomEventListener((_) => _didReceiveDomFocus()), + domFocusListener: createDomEventListener((_) => _setFocusFromDom(true)), + domBlurListener: createDomEventListener((_) => _setFocusFromDom(false)), ); _target = newTarget; element.tabIndex = 0; element.addEventListener('focus', newTarget.domFocusListener); + element.addEventListener('blur', newTarget.domBlurListener); } /// Stops managing the focus of the current element, if any. @@ -164,9 +170,10 @@ class AccessibilityFocusManager { } target.element.removeEventListener('focus', target.domFocusListener); + target.element.removeEventListener('blur', target.domBlurListener); } - void _didReceiveDomFocus() { + void _setFocusFromDom(bool acquireFocus) { final _FocusTarget? target = _target; if (target == null) { @@ -177,7 +184,9 @@ class AccessibilityFocusManager { EnginePlatformDispatcher.instance.invokeOnSemanticsAction( target.semanticsNodeId, - ui.SemanticsAction.focus, + acquireFocus + ? ui.SemanticsAction.didGainAccessibilityFocus + : ui.SemanticsAction.didLoseAccessibilityFocus, null, ); } @@ -220,7 +229,7 @@ class AccessibilityFocusManager { // a dialog, and nothing else in the dialog is focused. The Flutter // framework expects that the screen reader will focus on the first (in // traversal order) focusable element inside the dialog and send a - // SemanticsAction.focus action. Screen readers on the web do not do + // didGainAccessibilityFocus action. Screen readers on the web do not do // that, and so the web engine has to implement this behavior directly. So // the dialog will look for a focusable element and request focus on it, // but now there may be a race between this method unsetting the focus and diff --git a/lib/web_ui/lib/src/engine/semantics/semantics.dart b/lib/web_ui/lib/src/engine/semantics/semantics.dart index 0918ef49c3ff7..c48851d9836a2 100644 --- a/lib/web_ui/lib/src/engine/semantics/semantics.dart +++ b/lib/web_ui/lib/src/engine/semantics/semantics.dart @@ -2218,6 +2218,8 @@ class EngineSemantics { 'mousemove', 'mouseleave', 'mouseup', + 'keyup', + 'keydown', ]; if (pointerEventTypes.contains(event.type)) { diff --git a/lib/web_ui/lib/src/engine/semantics/text_field.dart b/lib/web_ui/lib/src/engine/semantics/text_field.dart index 3618306d37829..bb79ea1df52d9 100644 --- a/lib/web_ui/lib/src/engine/semantics/text_field.dart +++ b/lib/web_ui/lib/src/engine/semantics/text_field.dart @@ -2,8 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:async'; import 'package:ui/ui.dart' as ui; +import 'package:ui/ui_web/src/ui_web.dart' as ui_web; +import '../browser_detection.dart' show isIosSafari; import '../dom.dart'; import '../platform_dispatcher.dart'; import '../text_editing/text_editing.dart'; @@ -120,10 +123,7 @@ class SemanticsTextEditingStrategy extends DefaultTextEditingStrategy { // Android). // Otherwise, the keyboard stays on screen even when the user navigates to // a different screen (e.g. by hitting the "back" button). - // Keep this consistent with how DefaultTextEditingStrategy does it. As of - // right now, the only difference is that semantic text fields do not - // participate in form autofill. - DefaultTextEditingStrategy.scheduleFocusFlutterView(activeDomElement, activeDomElementView); + domElement?.blur(); domElement = null; activeTextField = null; _queuedStyle = null; @@ -162,7 +162,7 @@ class SemanticsTextEditingStrategy extends DefaultTextEditingStrategy { if (hasAutofillGroup) { placeForm(); } - activeDomElement.focus(preventScroll: true); + activeDomElement.focus(); } @override @@ -207,40 +207,69 @@ class SemanticsTextEditingStrategy extends DefaultTextEditingStrategy { /// [EngineSemanticsOwner.gestureMode]. However, in Chrome on Android it ignores /// browser gestures when in pointer mode. In Safari on iOS pointer events are /// used to detect text box invocation. This is because Safari issues touch -/// events even when VoiceOver is enabled. +/// events even when Voiceover is enabled. class TextField extends PrimaryRoleManager { TextField(SemanticsObject semanticsObject) : super.blank(PrimaryRole.textField, semanticsObject) { - _initializeEditableElement(); + _setupDomElement(); } - /// The element used for editing, e.g. ``, `