Repository navigation
Run Flutter widget code on Codename One - #5883
Conversation
Flutter vs Codename OneSame application, built both ways: Flutter's AOT compile of the gallery, and the identical Dart source transpiled to Java on Codename One. Lower is better for every metric, so a ratio above 1.00x means Codename One is ahead by that factor. android9 interleaved rounds; host load 0.6, 2.1, 1.7
Compute -- the VM workloads (
Gate: within tolerance against
javascript9 interleaved rounds; host load 1.71, 0.92, 0.38
Compute -- the VM workloads (
Gate: within tolerance against
linux9 interleaved rounds; host load 0.17, 2.85, 2.43
Compute -- the VM workloads (
Gate: within tolerance against
windows9 interleaved rounds
Compute -- the VM workloads (
Gate: within tolerance against
Codename One wins 18 of 18 measured metrics across 4 platform(s). |
|
Compared 12 screenshots: 12 matched. |
Native fidelity (Android, Material 3)54 pairs compared -- median 95.6%, worst 91.3% ( Distribution --
Geometry vs native (bbox offset / size ratio / center offset / corner radius) -- gated separately from the visual score
Side-by-side comparisons (worst first)
|
✅ Continuous Quality ReportTest & Coverage
Static Analysis
Generated automatically by the PR CI workflow. |
Cloudflare Preview
|
|
Compared 185 screenshots: 185 matched. Benchmark ResultsDetailed Performance Metrics
ParparVM vs HotSpot (JDK 25): Windows x64Runner CPU: AMD64 Family 26 Model 2 Stepping 1, AuthenticAMD (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
Result: no regression |
|
Compared 170 screenshots: 170 matched. Native Android coverage
✅ Native Android screenshot tests passed. Native Android coverage
Benchmark ResultsDetailed Performance Metrics
|
|
Compared 185 screenshots: 185 matched. Benchmark ResultsDetailed Performance Metrics
|
|
Compared 185 screenshots: 185 matched. ParparVM vs HotSpot (JDK 25): Linux x64Runner CPU: AMD EPYC 9V74 80-Core Processor (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
Result: no regression |
|
Compared 185 screenshots: 185 matched. ParparVM vs HotSpot (JDK 25): Linux arm64Runner CPU: Neoverse-N2 (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
Result: no regression |
|
Compared 185 screenshots: 185 matched. Benchmark ResultsDetailed Performance Metrics
ParparVM vs HotSpot (JDK 25): Windows arm64Runner CPU: ARMv8 (64-bit) Family 8 Model D49 Revision 0, MICROSOFT CORPORATION (baseline Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
Result: no regression |
|
Developer Guide build artifacts are available for download from this workflow run:
Developer Guide quality checks: |
✅ ByteCodeTranslator Quality ReportTest & Coverage
Benchmark Results
Static Analysis
Generated automatically by the PR CI workflow. |
|
Compared 206 screenshots: 206 matched. |
Native fidelity (ios-27-metal)68 pairs compared -- median 94.6%, worst 74.5% ( Distribution --
Geometry vs native (bbox offset / size ratio / center offset / corner radius) -- gated separately from the visual score
Side-by-side comparisons (worst first)
|
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f2af86e5ba
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Native fidelity (iOS Modern, Metal)68 pairs compared -- median 95.0%, worst 83.5% ( Distribution --
Geometry vs native (bbox offset / size ratio / center offset / corner radius) -- gated separately from the visual score
Side-by-side comparisons (worst first)
|
|
Compared 163 screenshots: 163 matched. |
|
Compared 236 screenshots: 236 matched. |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9bd3a88194
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 311de5406f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9808bc8c30
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Compared 179 screenshots: 179 matched. Benchmark Results
Detailed Performance Metrics
ParparVM vs HotSpot (JDK 25): macOS arm64Runner CPU: Apple M1 (Virtual) (baseline 1 performance regression:
1 improvement past the baseline, which fails until rebaselined:
Ratios are ParparVM / JDK 25: below 1.00x ParparVM is faster (time) or smaller (RAM). Median of 5 interleaved, paired rounds; every run's output was verified. A ratio more than 15% (time) / 15% (RAM) away from its baseline in
A change that moves performance ON PURPOSE records the new baseline in Result: performance regression |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: fb065ce701
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ream finishes, dialog replacement over the base page, TextFormField formatters and reset - dart-runtime: Set.identity()'s iterator is checked like every DartSet's (shared checkedIterator), so removing its last element mid-loop throws ConcurrentModificationError. - dart-runtime: a stream finished by its producer (close/endOfStream) runs its cancel hook once the last listener has its done event -- at once, or when a paused listener drains or discards it -- so StreamController.onCancel and an event channel's StreamHandler.onCancel run; never-listened streams run nothing. - flutter-runtime: pushReplacementNamed with a dialog over the base page replaces the dialog and leaves the base beneath (canPop stays true). - flutter-runtime: TextFormField forwards inputFormatters and TextFieldRenderElement applies them, in order, to every user edit before the field, controller and onChanged see it; reset restores an external controller's text from creation instead of blanking it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ca289c96ef
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…/asset collisions on import, theme pruning scans library jars, top-level runtime dependency check - developer-guide-docs.yml installs dart-runtime and flutter-runtime (the job is on JDK 17), which docs/demos/common now depends on. - cn1:import-flutter-project never lets an asset overwrite a file copied from lib/ at the same flattened path; the source is kept on every import and the clash is reported (Result.assetCollisions, warned by the mojo). - Native-theme pruning (Android, iOS, native macOS) also scans the application's library jars, listed right after the app is unzipped and before the port's archives land beside them, so a theme a library selects or opens is kept. - FlutterPomUpdater counts the runtime as wired only when it is in the project's top-level <dependencies>; a dependencyManagement entry puts nothing on the classpath. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3feb61ed5c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…esult delivered after the way back is committed, Duration minimum, failed restorable presentations - Navigator.push registers the route before mounting its page (rolled back if mounting fails): the first build is synchronous, and an in-canvas AppBar's automaticallyImplyLeading asked canPop() while the first pushed route was not yet on the stack, so it drew no back button. - Navigator.pop completes the popped route's future last, after returningTo and the return transition are set up, so a callback that pushes at once starts from the page beneath, not the page being popped. - Duration.toString splits before taking magnitudes: the minimum duration printed negative components (Dart: -2562047788:00:54.775808). - RestorableRouteFuture.present stays inactive when nothing was pushed, so isPresent() cannot stick at true with no route to complete it. - RasterDisplay (test support) installs a display lock, so Form.show runs under it. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1a066f9cbb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…tion Motion, setState after dispose, disabled form fields, viewportFraction above one - dart-transpiler: `await f` on a Future<T>? lowers through awaitAny, so a null future awaits to null as in Dart instead of throwing TypeError. - core: a Motion given to a transition with setMotion() is reset for each run (new package-private Motion.resetForReuse); copies share it, and the first run left it finished so every later run completed at once. - flutter-runtime: setState on a disposed State reports a FlutterError and does not run the closure. - flutter-runtime: a disabled FormField/TextFormField is not validated automatically (an explicit validate() still runs). - flutter-runtime: any positive viewportFraction is kept; above one a page is wider than the viewport and rests centred, offset by half the overflow, as Flutter's initial page offset does. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 527252fe2e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…xLength cap, counted headless repeats, popUntil over dialogs, directional insets and radii
- CommonTransitionsTest gets the Codename One header (touched last round,
so the diff-scoped header gate checked it).
- dart-runtime: Uri.queryParameters ignores a component with an empty key
("?=admin"), as Dart's splitQueryString does.
- flutter-runtime: no UTF-16 native cap on a TextField with maxLength; it
cut a valid grapheme with many combining marks short, and userEdited
already enforces the grapheme-aware limit after the formatters.
- flutter-runtime: repeat(count: n) completes headless, running its finite
legs synchronously like any headless run.
- flutter-runtime: popUntil evaluates and pops an open dialog (as an
unnamed DialogRoute) before the page beneath it.
- flutter-runtime: adding two EdgeInsetsDirectional stays directional;
BorderRadiusDirectional.resolve/BorderRadius.of, used by ClipRRect (with
the ambient direction) and the uniform-radius readers (button shapes,
box decorations, OutlineInputBorder), which treated a directional radius
as none.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 828dd15c99
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…esources, Metal frame sequence on texture rebuild, nested app themes, integral map keys - flutter-runtime: runApp's two start-up collections are requested on a background thread; on the JVM and ART an explicit GC blocks its caller, and on the EDT it stalled every app after its first frame. - build-engine: native-theme pruning also scans the application's own .res files (listed at app unzip, before any port theme lands): an @OverlayThemes property names a theme only there. - MacPort METALView: replacing or dropping screenTexture bumps the frame sequence, so a command buffer from before a resize cannot mark the new texture volatile while it is still being initialised. - flutter-runtime: a nested MaterialApp hands the global theme back to the enclosing app (and refreshes its form) when it unmounts. - dart-runtime: Integer, Short and Byte map/set keys are the same Dart int as the Long transpiled code uses (every integral twin is probed). - SimpleDateFormat.sameZone keeps its comparison, with the reason in a comment: no Codename One API builds a zone whose rules differ from its ID's. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1ee07ef800
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…eam after synchronous derived-stream cancellation, image scale in the source key, restorable controller disposal - flutter-runtime: popping a displayed dialog disposes the native dialog first and completes its future after, so an `await showDialog` continuation that pops the page beneath no longer runs while the dialog is current (whose disposal then resurrected the popped route). - dart-runtime: Stream.map/where cancel the upstream subscription right after listen() returns when the derived stream has already lost its listeners (a synchronous emit into a throwing transform with cancelOnError), so the source gets its cancel hook. - flutter-runtime: a NetworkImage/MemoryImage scale is part of the image source key; a scale-only rebuild kept the old intrinsic size. - flutter-runtime: RestorableTextEditingController.dispose disposes the controller it owns. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1a1d64671f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…ed route's result, rootNavigator, two-way channel handlers, byte[] as Uint8List - RasterDisplay (test support) installs Display's Graphics wrapper as Display.init does: Dialog.showPacked flushes the EDT and paints, and CI's test order reached that paint with no graphics (NPE in dart-flutter-tests). - Navigator.pushReplacementNamed completes the removed route's future only after the replacement is pushed (pop split into popPage + complete), so a callback that pushes at once lands above the replacement. - Navigator.of(context, rootNavigator: true) binds to the root app's navigator position, so named routes resolve against the root table. - FlutterChannelRegistry keeps the Dart side's and the platform side's method handlers apart; a channel carrying calls both ways no longer has one registration replace the other. - toDart converts byte[] (also nested in lists and maps) to a Uint8List (new Uint8List.fromBytes), as Flutter's standard codec does. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ilation # Conflicts: # maven/core-unittests/src/test/java/com/codename1/ui/ComboBoxPopupTestSupport.java
…4 translator) #5984 (merged) rebaselines the same two rows from the same values, which the baseline checker rejects. Its rows stay; this PR's getCallers memory improvement on those two runners is re-measured on top of both from the next CI run. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>




















































































































































































































































































































































































Compiles Dart widget source to Java at build time and runs it on Codename One's own renderer. There is no Dart VM in the result, no embedded engine and no platform view — a Dart screen becomes ordinary Codename One components, so it inherits the theme, the event thread, the accessibility tree and the native build.
Two entry points, which are the two things a user actually wants to do:
FlutterUI.wrap(widget)returns aContainerthat goes anywhere an ordinary component does, for putting one Dart screen inside an existing app. It deliberately does not install the Material base theme, so it will not restyle the screen around it.FlutterUI.runApp(widget)mounts the tree as the whole UI, and does install it.The build wiring is the archetype's own: the
transcode-fluttergoal is already bound and is a silent no-op untilsrc/main/flutterexists. No Dart SDK is involved — the transpiler is Java and the Dart is input, never executed.Benchmark
scripts/flutter-benchbuilds one application two ways — the Flutter toolchain's release build, and the identical Dart source transpiled by Codename One — and publishes size, start-up and idle memory per platform to the PR and to port status.Neither application is vendored.
prepare.shtakes the gallery from the Flutter SDK CI clones and copies the same 159 files into both trees, so the comparison cannot drift: there is no second copy for an edit to land on. An earlier round of this work compared two different galleries and every number it produced was meaningless. The Codename One side is generated from the shipping archetype with the runtime dependency enabled — the two steps the guide tells a user to take — so a change that breaks the documented wiring breaks the benchmark too.Three measurement decisions, each because the obvious alternative flattered us:
FIRSTCONTENTis a UI-thread callback that runs before that frame is rasterised, while ourFIRSTFRAMEfires once the form is on screen. Comparing them charges one runtime for rasterising its first screen and not the other — which is what the harness this replaces did. Flutter's figure is reported as a range and the ratio uses the end least favourable to us.Runneris a thin launcher and the Dart image sits inFrameworks/App.framework. Sizing the executable compared our whole runtime against their stub.And two refusals rather than a substituted number:
Nothing contacts the build server: the
*-sourceandlocal-*targets build on the runner. Only our own numbers are gated, so a Flutter SDK upgrade that grows their build cannot turn ours red.Fidelity work in this PR
RoundBorderdraws itself when there is no shadow and nouiidmode, instead of going through a component-sized offscreen image. The cache hides the cost for a static shape; for one that animates its size it does not — a circle growing to 1618×1618 threw away a 10MB surface per frame.Component.paintInternalImplclips every component to its own rectangle, soFractionalTranslationdrew most of itself into the discarded region — the feature-discovery circle rendered as a quadrant with two straight edges meeting at its centre.FittedBoxwas a pass-through. Flutter lays its child out unbounded and scales the result, which is why text inside one shrinks instead of wrapping.Cardrebuilt its border every time, andRoundRectBordercaches its shadow against the border instance, so every rebuild re-rendered it with a gaussian blur. With the cache off it also translates the liveGraphicsby the shadow offset and never undoes it, so cards drifted 9px down and 4px across, accumulating down the page.Verification
/demo/card14.98% → 2.30%,/demo/grid-lists26.30% → 0.32%prepare.shverified end to end; the generated project builds 563 Java files from 159 Dart files, which also exercises the documented user pathNot yet proven
No benchmark platform adapter has been exercised end to end —
run_bench.py --listreports that rather than implying otherwise, and the first CI run is the thing to review. The native compile steps (xcodebuild, gradle, clang-cl, GTK3) have not run on a runner.This is also the first mention of the feature in
docs/, which has carried none until now.