From 8f4204edc9fe4377e4e07fc15521d1eeac2b098a Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Fri, 14 Feb 2025 13:04:52 +1100 Subject: [PATCH 1/2] Use Swift C++ interop to more closely integrate with Flutter engine --- .../Flutter/GeneratedPluginRegistrant.swift | 4 +- Examples/counter/swift/runner.swift | 6 +- Package.swift | 22 ++++-- .../CxxFlutterSwift/flutter-embedded-linux | 2 +- .../CxxFlutterSwift/include/CxxFlutterSwift.h | 11 ++- .../CxxFlutterSwift/include/module.modulemap | 3 + Sources/FlutterSwift/Base/StringHelpers.swift | 19 ++++- .../FlutterSwift/Client/FlutterEngine.swift | 72 +++++++++++++------ .../FlutterSwift/Client/FlutterPlugin.swift | 24 +++---- .../FlutterSwift/Client/FlutterTexture.swift | 21 ++++-- Sources/FlutterSwift/Client/FlutterView.swift | 14 ++-- .../Client/FlutterViewController.swift | 11 ++- .../FlutterSwift/Client/FlutterWindow.swift | 10 ++- .../Messenger/FlutterDesktopMessenger.swift | 69 ++++++++---------- 14 files changed, 184 insertions(+), 104 deletions(-) create mode 100644 Sources/CxxFlutterSwift/include/module.modulemap diff --git a/Examples/counter/macos/Flutter/GeneratedPluginRegistrant.swift b/Examples/counter/macos/Flutter/GeneratedPluginRegistrant.swift index cccf817..15c8774 100644 --- a/Examples/counter/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/Examples/counter/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,4 @@ import FlutterMacOS import Foundation - -func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { -} +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {} diff --git a/Examples/counter/swift/runner.swift b/Examples/counter/swift/runner.swift index bb2b3e9..48b975b 100644 --- a/Examples/counter/swift/runner.swift +++ b/Examples/counter/swift/runner.swift @@ -144,7 +144,11 @@ enum Counter { title: "Counter", appId: "com.example.counter" ) - let window = FlutterWindow(properties: viewProperties, project: dartProject) + let window = FlutterWindow( + properties: viewProperties, + project: dartProject, + enableImpeller: true + ) guard let window else { exit(2) } diff --git a/Package.swift b/Package.swift index 7e261fd..182aae7 100644 --- a/Package.swift +++ b/Package.swift @@ -13,7 +13,7 @@ var targetPluginUsages = [Target.PluginUsage]() var platformCxxSettings: [CXXSetting] = [] var platformSwiftSettings: [SwiftSetting] = [.swiftLanguageMode(.v5)] -func tryGuessSwiftLibRoot() -> String { +func tryGuessSwiftRoot() -> String { let task = Process() task.executableURL = URL(fileURLWithPath: "/bin/sh") task.arguments = ["-c", "which swift"] @@ -22,13 +22,14 @@ func tryGuessSwiftLibRoot() -> String { try task.run() let outputData = (task.standardOutput as! Pipe).fileHandleForReading.readDataToEndOfFile() let path = URL(fileURLWithPath: String(decoding: outputData, as: UTF8.self)) - return path.deletingLastPathComponent().path + "/../lib/swift" + return path.deletingLastPathComponent().deletingLastPathComponent().deletingLastPathComponent() + .path } catch { - return "/usr/lib/swift" + return "" } } -let SwiftLibRoot = tryGuessSwiftLibRoot() +let SwiftRoot = tryGuessSwiftRoot() var FlutterPlatform: String var FlutterUnsafeLinkerFlags: [String] = [] @@ -235,10 +236,19 @@ packageDependencies += [ let FlutterELinuxBackend = FlutterELinuxBackendType.defaultBackend +let CxxIncludeDirs: [String] = [ + "\(SwiftRoot)/usr/include", + "\(SwiftRoot)/usr/lib/swift", + "/usr/include/drm", +] + +let CxxIncludeFlags = CxxIncludeDirs.flatMap { ["-I", $0] } + platformSwiftSettings += [ .define("DISPLAY_BACKEND_TYPE_\(FlutterELinuxBackend.displayBackendType)"), .define("FLUTTER_TARGET_BACKEND_\(FlutterELinuxBackend.flutterTargetBackend)"), .interoperabilityMode(.Cxx), + .unsafeFlags(CxxIncludeFlags), ] targets += [ @@ -404,7 +414,7 @@ targets += [ .headerSearchPath("flutter-embedded-linux/src/third_party/rapidjson/include"), // FIXME: .cxxLanguageStandard breaks Foundation compile // FIXME: include path for swift/bridging.h - .unsafeFlags(["-pthread", "-I", SwiftLibRoot, "-I", "/usr/include/drm", "-std=c++17"]), + .unsafeFlags(["-pthread", "-std=c++17"] + CxxIncludeFlags), ], linkerSettings: [ // .unsafeFlags(["-pthread"]), @@ -446,6 +456,8 @@ platformCxxSettings += [ .headerSearchPath( "../CxxFlutterSwift/flutter-embedded-linux/src/flutter/shell/platform/common/client_wrapper/include" ), + .headerSearchPath("../CxxFlutterSwift/flutter-embedded-linux/src/third_party/rapidjson/include"), + .unsafeFlags(CxxIncludeFlags), ] #else diff --git a/Sources/CxxFlutterSwift/flutter-embedded-linux b/Sources/CxxFlutterSwift/flutter-embedded-linux index a938f2b..aec09f8 160000 --- a/Sources/CxxFlutterSwift/flutter-embedded-linux +++ b/Sources/CxxFlutterSwift/flutter-embedded-linux @@ -1 +1 @@ -Subproject commit a938f2b2064bb25b58c5207f6f5c3dfb9972fadf +Subproject commit aec09f8e11638ac63dd07142a038267339852265 diff --git a/Sources/CxxFlutterSwift/include/CxxFlutterSwift.h b/Sources/CxxFlutterSwift/include/CxxFlutterSwift.h index 10f049e..10f0be5 100644 --- a/Sources/CxxFlutterSwift/include/CxxFlutterSwift.h +++ b/Sources/CxxFlutterSwift/include/CxxFlutterSwift.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2023-2024 PADL Software Pty Ltd +// Copyright (c) 2023-2025 PADL Software Pty Ltd // // Licensed under the Apache License, Version 2.0 (the License); // you may not use this file except in compliance with the License. @@ -21,11 +21,18 @@ #include #include +#include +#include +#include #include -// #include #include #ifdef __cplusplus +#include +#include + +using CxxVectorOfString = std::vector>; + extern "C" { #endif diff --git a/Sources/CxxFlutterSwift/include/module.modulemap b/Sources/CxxFlutterSwift/include/module.modulemap new file mode 100644 index 0000000..d768fcb --- /dev/null +++ b/Sources/CxxFlutterSwift/include/module.modulemap @@ -0,0 +1,3 @@ +module CxxFlutterSwift { + header "CxxFlutterSwift.h" +} diff --git a/Sources/FlutterSwift/Base/StringHelpers.swift b/Sources/FlutterSwift/Base/StringHelpers.swift index 70c71a3..b136008 100644 --- a/Sources/FlutterSwift/Base/StringHelpers.swift +++ b/Sources/FlutterSwift/Base/StringHelpers.swift @@ -10,7 +10,12 @@ // //===----------------------------------------------------------------------===// -#if os(Linux) +#if os(Linux) && canImport(Glibc) + +@_implementationOnly +import CxxFlutterSwift +import CxxStdlib + /// Compute the prefix sum of `seq`. func scan< S: Sequence, U @@ -60,4 +65,16 @@ extension String { return u32.withUnsafeBufferPointer { body($0.baseAddress!) } } } + +extension Array where Element == String { + var cxxVector: CxxVectorOfString { + var tmp = CxxVectorOfString() + + for element in self { + tmp.push_back(std.string(element)) + } + + return tmp + } +} #endif diff --git a/Sources/FlutterSwift/Client/FlutterEngine.swift b/Sources/FlutterSwift/Client/FlutterEngine.swift index 4d613b3..44b0e24 100644 --- a/Sources/FlutterSwift/Client/FlutterEngine.swift +++ b/Sources/FlutterSwift/Client/FlutterEngine.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2023-2024 PADL Software Pty Ltd +// Copyright (c) 2023-2025 PADL Software Pty Ltd // // Licensed under the Apache License, Version 2.0 (the License); // you may not use this file except in compliance with the License. @@ -17,17 +17,18 @@ #if os(Linux) && canImport(Glibc) @_implementationOnly import CxxFlutterSwift +import CxxStdlib public final class FlutterEngine: FlutterPluginRegistry, @unchecked Sendable { - var engine: FlutterDesktopEngineRef! // strong or weak ref var pluginPublications = [String: Any]() let project: DartProject weak var viewController: FlutterViewController? + private var engine: flutter.FlutterELinuxEngine! // strong or weak ref private var _binaryMessenger: FlutterDesktopMessenger! private var ownsEngine = true private var hasBeenRun = false - public init?(project: DartProject) { + public init?(project: DartProject, switches: [String: Any] = [:]) { var properties = FlutterDesktopEngineProperties() debugPrint("Initializing Flutter engine with \(project)") @@ -48,7 +49,9 @@ public final class FlutterEngine: FlutterPluginRegistry, @unchecked Sendable { ) cStrings.withUnsafeMutableBufferPointer { pointer in properties.dart_entrypoint_argv = pointer.baseAddress - self.engine = FlutterDesktopEngineCreate(&properties) + let engine = FlutterDesktopEngineCreate(&properties) + self.engine = unsafeBitCast(engine, to: flutter.FlutterELinuxEngine.self) + setSwitches(switches.map { key, value in "--\(key)=\(String(describing: value))" }) self._binaryMessenger = FlutterDesktopMessenger(engine: self.engine) } } @@ -61,6 +64,10 @@ public final class FlutterEngine: FlutterPluginRegistry, @unchecked Sendable { shutDown() } + private var _handle: FlutterDesktopEngineRef { + unsafeBitCast(engine, to: FlutterDesktopEngineRef.self) + } + // note we can't use public private(set) because we need the type to be FlutterDesktopMessenger! // in order for callbacks to work (otherwise self must be first initialized). But we want to // present a non-optional type to callers. @@ -69,39 +76,31 @@ public final class FlutterEngine: FlutterPluginRegistry, @unchecked Sendable { } public func run(entryPoint: String? = nil) -> Bool { - if hasBeenRun { - debugPrint("Cannot run an engine more than once.") - return false - } - let runSucceeded = FlutterDesktopEngineRun(engine, entryPoint) - if !runSucceeded { - debugPrint("Failed to start engine.") - } - hasBeenRun = true - return runSucceeded + guard !hasBeenRun else { return false } + hasBeenRun = engine.RunWithEntrypoint(entryPoint) + return hasBeenRun } public func shutDown() { pluginPublications.removeAll() - if let engine, ownsEngine { - FlutterDesktopEngineDestroy(engine) + if engine != nil, ownsEngine { + FlutterDesktopEngineDestroy(_handle) } engine = nil } public func processMessages() -> UInt64 { precondition(engine != nil) - return FlutterDesktopEngineProcessMessages(engine) + return FlutterDesktopEngineProcessMessages(_handle) } public func reloadSystemFonts() { - precondition(engine != nil) - FlutterDesktopEngineReloadSystemFonts(engine) + engine.ReloadSystemFonts() } func relinquishEngine() -> FlutterDesktopEngineRef { ownsEngine = false - return engine + return _handle } public func registrar(for pluginKey: String) -> FlutterPluginRegistrar? { @@ -116,5 +115,38 @@ public final class FlutterEngine: FlutterPluginRegistry, @unchecked Sendable { public func valuePublished(by pluginKey: String) -> Any? { pluginPublications[pluginKey] } + + public var isRunning: Bool { + engine.running() + } + + func onVsync(lastFrameTimeNS: UInt64, vsyncIntervalTimeNS: UInt64) { + engine.OnVsync(lastFrameTimeNS, vsyncIntervalTimeNS) + } + + public var isImpellerEnabled: Bool { + engine.IsImpellerEnabled() + } + + public func setSystemSettings(textScalingFactor: Float, enableHighContrast: Bool) { + engine.SetSystemSettings(textScalingFactor, enableHighContrast) + } + + public func setView(_ view: FlutterView) { + engine.SetView(view.view) + } + + public func setSwitches(_ switches: [String]) { + engine.SetSwitches(switches.cxxVector) + } + + func getRegistrar(pluginName: String) -> FlutterDesktopPluginRegistrarRef? { + FlutterDesktopEngineGetPluginRegistrar(_handle, pluginName) + } + + var textureRegistrar: flutter.FlutterELinuxTextureRegistrar! { + engine.texture_registrar() + } } + #endif diff --git a/Sources/FlutterSwift/Client/FlutterPlugin.swift b/Sources/FlutterSwift/Client/FlutterPlugin.swift index 5d52dfe..78e73c2 100644 --- a/Sources/FlutterSwift/Client/FlutterPlugin.swift +++ b/Sources/FlutterSwift/Client/FlutterPlugin.swift @@ -116,22 +116,25 @@ public final class FlutterDesktopPluginRegistrar: FlutterPluginRegistrar { ) { self.engine = engine pluginKey = pluginName - registrar = FlutterDesktopEngineGetPluginRegistrar(engine.engine, pluginName) - FlutterDesktopPluginRegistrarSetDestructionHandlerBlock(registrar!) { _ in - self.registrar = nil + registrar = engine.getRegistrar(pluginName: pluginName) + // FIXME: use std::function + FlutterDesktopPluginRegistrarSetDestructionHandlerBlock(registrar!) { [self] _ in + for (channel, detachFromEngine) in detachFromEngineCallbacks { + try? channel.removeMessageHandler() + detachFromEngine(self) + } + registrar = nil } } public var binaryMessenger: FlutterBinaryMessenger? { guard let registrar else { return nil } - return FlutterDesktopMessenger( - messenger: FlutterDesktopPluginRegistrarGetMessenger(registrar) - ) + return FlutterDesktopMessenger(messenger: registrar.pointee.engine.messenger()) } public var view: FlutterView? { guard let registrar else { return nil } - let view = FlutterDesktopPluginRegistrarGetView(registrar)! + let view = registrar.pointee.engine.view()! return FlutterView(view) } @@ -161,13 +164,6 @@ public final class FlutterDesktopPluginRegistrar: FlutterPluginRegistrar { } } - deinit { - for (channel, detachFromEngine) in detachFromEngineCallbacks { - try? channel.removeMessageHandler() - detachFromEngine(self) - } - } - public func lookupKey(for asset: String) -> String? { guard let bundle = Bundle(path: engine.project.assetsPath) else { return nil diff --git a/Sources/FlutterSwift/Client/FlutterTexture.swift b/Sources/FlutterSwift/Client/FlutterTexture.swift index 5ce8eae..d65f1c6 100644 --- a/Sources/FlutterSwift/Client/FlutterTexture.swift +++ b/Sources/FlutterSwift/Client/FlutterTexture.swift @@ -138,15 +138,23 @@ public enum FlutterTexture { } public struct FlutterDesktopTextureRegistrar { - private let registrar: FlutterDesktopTextureRegistrarRef + private let registrar: flutter.FlutterELinuxTextureRegistrar + + private var _handle: FlutterDesktopTextureRegistrarRef { + unsafeBitCast(registrar, to: FlutterDesktopTextureRegistrarRef.self) + } public init(engine: FlutterEngine) { - registrar = FlutterDesktopEngineGetTextureRegistrar(engine.engine) + registrar = engine.textureRegistrar } init?(plugin: FlutterDesktopPluginRegistrar) { guard let registrar = plugin.registrar else { return nil } - self.registrar = FlutterDesktopRegistrarGetTextureRegistrar(registrar) + let textureRegistrarHandle = FlutterDesktopRegistrarGetTextureRegistrar(registrar) + self.registrar = unsafeBitCast( + textureRegistrarHandle, + to: flutter.FlutterELinuxTextureRegistrar.self + ) } public func registerExternalTexture(_ texture: FlutterTexture) -> Int64 { @@ -166,7 +174,7 @@ public struct FlutterDesktopTextureRegistrar { user_data: Unmanaged.passUnretained(config).toOpaque() ) } - return FlutterDesktopTextureRegistrarRegisterExternalTexture(registrar, &textureInfo) + return registrar.RegisterTexture(&textureInfo) } public func unregisterExternalTexture(texture: FlutterTexture, id textureID: Int64) { @@ -177,8 +185,9 @@ public struct FlutterDesktopTextureRegistrar { case let .eglImageTexture(config): texturePtr = Unmanaged.passUnretained(config).toOpaque() } + // FIXME: use std::function FlutterDesktopTextureRegistrarUnregisterExternalTexture( - registrar, + _handle, textureID, _releaseAnyObject, texturePtr @@ -186,7 +195,7 @@ public struct FlutterDesktopTextureRegistrar { } public func markExternalTextureFrameAvailable(textureID: Int64) { - FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable(registrar, textureID) + registrar.MarkTextureFrameAvailable(textureID) } } diff --git a/Sources/FlutterSwift/Client/FlutterView.swift b/Sources/FlutterSwift/Client/FlutterView.swift index f0f1e6c..d1e54d8 100644 --- a/Sources/FlutterSwift/Client/FlutterView.swift +++ b/Sources/FlutterSwift/Client/FlutterView.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2023-2024 PADL Software Pty Ltd +// Copyright (c) 2023-2025 PADL Software Pty Ltd // // Licensed under the Apache License, Version 2.0 (the License); // you may not use this file except in compliance with the License. @@ -21,7 +21,7 @@ import CxxFlutterSwift let kChannelName = "flutter/platform_views" public struct FlutterView { - let view: FlutterDesktopViewRef + let view: flutter.FlutterELinuxView var platformViewsPluginRegistrar: FlutterPluginRegistrar? var platformViewsHandler: FlutterPlatformViewsPlugin? var viewController: FlutterViewController? { @@ -38,16 +38,20 @@ public struct FlutterView { } } - init(_ view: FlutterDesktopViewRef) { + init(_ view: flutter.FlutterELinuxView) { self.view = view } + init(_ view: FlutterDesktopViewRef) { + self.init(unsafeBitCast(view, to: flutter.FlutterELinuxView.self)) + } + public func dispatchEvent() -> Bool { - FlutterDesktopViewDispatchEvent(view) + view.DispatchEvent() } public var frameRate: Int32 { - FlutterDesktopViewGetFrameRate(view) + view.GetFrameRate() } } #endif diff --git a/Sources/FlutterSwift/Client/FlutterViewController.swift b/Sources/FlutterSwift/Client/FlutterViewController.swift index 7cb6542..1db2370 100644 --- a/Sources/FlutterSwift/Client/FlutterViewController.swift +++ b/Sources/FlutterSwift/Client/FlutterViewController.swift @@ -91,11 +91,16 @@ public final class FlutterViewController { } } - public init?(properties viewProperties: ViewProperties, project: DartProject) { + public init?( + properties viewProperties: ViewProperties, + project: DartProject, + switches: [String: Any] = [:] + ) { var cViewProperties = FlutterDesktopViewProperties() var controller: FlutterDesktopViewControllerRef? - guard let engine = FlutterEngine(project: project) else { return nil } + guard let engine = FlutterEngine(project: project, switches: switches) + else { return nil } self.engine = engine cViewProperties.width = viewProperties.width @@ -145,7 +150,7 @@ public final class FlutterViewController { public var view: FlutterView { didSet { - FlutterDesktopEngineSetView(engine.engine, view.view) + engine.setView(view) } } diff --git a/Sources/FlutterSwift/Client/FlutterWindow.swift b/Sources/FlutterSwift/Client/FlutterWindow.swift index 4b178ea..fb5d67f 100644 --- a/Sources/FlutterSwift/Client/FlutterWindow.swift +++ b/Sources/FlutterSwift/Client/FlutterWindow.swift @@ -27,11 +27,17 @@ public struct FlutterWindow { public init?( properties viewProperties: FlutterViewController.ViewProperties, - project: DartProject + project: DartProject, + enableImpeller: Bool = false ) { + var switches = [String: Any]() + if enableImpeller { + switches["enable-impeller"] = true + } guard let viewController = FlutterViewController( properties: viewProperties, - project: project + project: project, + switches: switches ) else { return nil } diff --git a/Sources/FlutterSwift/Messenger/FlutterDesktopMessenger.swift b/Sources/FlutterSwift/Messenger/FlutterDesktopMessenger.swift index b391afa..9f93a57 100644 --- a/Sources/FlutterSwift/Messenger/FlutterDesktopMessenger.swift +++ b/Sources/FlutterSwift/Messenger/FlutterDesktopMessenger.swift @@ -1,5 +1,5 @@ // -// Copyright (c) 2023-2024 PADL Software Pty Ltd +// Copyright (c) 2023-2025 PADL Software Pty Ltd // // Licensed under the Apache License, Version 2.0 (the License); // you may not use this file except in compliance with the License. @@ -24,50 +24,37 @@ import FoundationEssentials import Foundation #endif -public final class FlutterDesktopMessenger: FlutterBinaryMessenger { - private final class ManagedReference: @unchecked Sendable { - private let messenger: FlutterDesktopMessengerRef - - init(_ messenger: FlutterDesktopMessengerRef) { - self.messenger = messenger - FlutterDesktopMessengerAddRef(messenger) - } - - deinit { - FlutterDesktopMessengerRelease(messenger) - } - - private func withUnsafeRegion( - _ block: (_: FlutterDesktopMessengerRef) throws - -> T - ) throws -> T { - guard FlutterDesktopMessengerIsAvailable(messenger) else { - throw FlutterSwiftError.messengerNotAvailable - } - return try block(messenger) - } - - func withRegion( - _ block: (_: FlutterDesktopMessengerRef) throws - -> T - ) throws -> T { - FlutterDesktopMessengerLock(messenger) - defer { FlutterDesktopMessengerUnlock(messenger) } - return try withUnsafeRegion(block) - } - } - +public final class FlutterDesktopMessenger: FlutterBinaryMessenger, @unchecked Sendable { private let currentMessengerConnection = ManagedAtomic(0) - private let messenger: ManagedReference + private let messenger: FlutterDesktopMessengerRef // : - Initializers init(messenger: FlutterDesktopMessengerRef) { - self.messenger = ManagedReference(messenger) + self.messenger = messenger + } + + convenience init(engine: flutter.FlutterELinuxEngine) { + self.init(messenger: engine.messenger()) + } + + private func withUnsafeMessenger( + _ block: (_: FlutterDesktopMessengerRef) throws + -> T + ) throws -> T { + guard messenger.GetEngine() != nil else { + throw FlutterSwiftError.messengerNotAvailable + } + return try block(messenger) } - init(engine: FlutterDesktopEngineRef) { - messenger = ManagedReference(FlutterDesktopEngineGetMessenger(engine)) + private func withMessenger( + _ block: (_: FlutterDesktopMessengerRef) throws + -> T + ) throws -> T { + FlutterDesktopMessengerLock(messenger) + defer { FlutterDesktopMessengerUnlock(messenger) } + return try withUnsafeMessenger(block) } // MARK: - FlutterDesktopMessenger wrappers @@ -85,7 +72,7 @@ public final class FlutterDesktopMessenger: FlutterBinaryMessenger { _ block: FlutterDesktopBinaryReplyBlock? ) throws { guard try (message ?? Data()).withUnsafeBytes({ bytes in - try messenger.withRegion { messenger in + try withMessenger { messenger in FlutterDesktopMessengerSendWithReplyBlock( messenger, channel, @@ -103,7 +90,7 @@ public final class FlutterDesktopMessenger: FlutterBinaryMessenger { on channel: String, _ block: FlutterDesktopMessageCallbackBlock? ) throws { - try messenger.withRegion { messenger in + try withMessenger { messenger in FlutterDesktopMessengerSetCallbackBlock(messenger, channel, block) } } @@ -122,7 +109,7 @@ public final class FlutterDesktopMessenger: FlutterBinaryMessenger { } // FIXME: do we need to take a lock here? doesn't look like other platforms do - try messenger.withRegion { messenger in + try withMessenger { messenger in (response ?? Data()).withUnsafeBytes { FlutterDesktopMessengerSendResponse( messenger, From 1cb80f8c55ee5d7c19217f5679ec2780a4b62054 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Tue, 4 Mar 2025 12:05:56 +1100 Subject: [PATCH 2/2] disable Impeller --- Examples/counter/swift/runner.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Examples/counter/swift/runner.swift b/Examples/counter/swift/runner.swift index 48b975b..98e7d68 100644 --- a/Examples/counter/swift/runner.swift +++ b/Examples/counter/swift/runner.swift @@ -146,8 +146,7 @@ enum Counter { ) let window = FlutterWindow( properties: viewProperties, - project: dartProject, - enableImpeller: true + project: dartProject ) guard let window else { exit(2)