- Updated the README.md with the description of benchmarks (might be
useful to external parties)
- customized a runner for D8
- added a `warmupCount` parameter to `runBenchmarks`, because it's
required for Jetstream3 (a set of benchmarks) that there is no warmup
(they skip it)
- Added a smooth scroll variant of LazyGrid + variants with
LaunchedEffect in grid cells for coroutines usage.
- Added a new class `Config`. Object `Args` is simplified, it's purpose
is to simply parse the arguments and produce a instance of `Config`. The
usages of `Args` were replaced by `Config`, except the parsing in fun
main.
- Renamed Example1 to MultipleComponents
- Also added MultipleComponents-NoVectorGraphics for D8 - it's similar
to MultipleComponents but doesn't use vector icons.
Fixes https://youtrack.jetbrains.com/issue/CMP-6942
Note: it's based on this PR
https://github.com/JetBrains/compose-multiplatform/pull/5275
## Testing
Manually run the benchmarks
## Release Notes
N/A
Replaced legacy handling of the Compose compiler plugin with a new mechanism using `checkComposeCompilerPlugin`. This ensures compatibility with Kotlin 2.0.0+ and eliminates outdated compatibility code, simplifying future maintenance.
Continuation of
https://github.com/JetBrains/compose-multiplatform/pull/5279
```
> Task :composeApp:runRelease
Exception in thread "AWT-EventQueue-0" java.lang.VerifyError: Bad return type
Exception Details:
Location:
kotlinx/coroutines/flow/FlowKt__MergeKt.transformLatest$21dee7bd(Lkotlinx/coroutines/flow/Flow;Lkotlin/jvm/functions/Function3;)Lkotlinx/coroutines/flow/internal/ChannelFlowTransformLatest; @17: areturn
Reason:
Type 'kotlinx/coroutines/flow/Flow' (current frame, stack[0]) is not assignable to 'kotlinx/coroutines/flow/internal/ChannelFlowTransformLatest' (from method signature)
Current Frame:
bci: @17
flags: { }
locals: { 'kotlinx/coroutines/flow/Flow', 'kotlin/jvm/functions/Function3' }
stack: { 'kotlinx/coroutines/flow/Flow' }
Bytecode:
0000000: bb00 0e59 2b2a 0103 0110 1cb7 0012 c000
0000010: 0ab0
at kotlinx.coroutines.flow.FlowKt.mapLatest(Unknown Source)
at kotlinx.coroutines.flow.FlowKt.collectLatest(Unknown Source)
at androidx.compose.foundation.text.SecureTextFieldController.observeHideEvents(BasicSecureTextField.kt:241)
at androidx.compose.foundation.text.BasicSecureTextFieldKt$BasicSecureTextField$1$1.invokeSuspend(BasicSecureTextField.kt:139)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
at androidx.compose.ui.platform.FlushCoroutineDispatcher.flush$lambda$4(FlushCoroutineDispatcher.skiko.kt:96)
at androidx.compose.ui.platform.FlushCoroutineDispatcher.performRun(FlushCoroutineDispatcher.skiko.kt:105)
at androidx.compose.ui.platform.FlushCoroutineDispatcher.flush(FlushCoroutineDispatcher.skiko.kt:83)
at androidx.compose.ui.scene.ComposeSceneRecomposer.performScheduledEffects(ComposeSceneRecomposer.skiko.kt:91)
at androidx.compose.ui.scene.BaseComposeScene.render(BaseComposeScene.skiko.kt:171)
at androidx.compose.ui.scene.ComposeSceneMediator.onRender$lambda$20$lambda$19(ComposeSceneMediator.desktop.kt:600)
at androidx.compose.ui.viewinterop.SwingInteropContainer.postponingExecutingScheduledUpdates(SwingInteropContainer.desktop.kt:251)
at androidx.compose.ui.scene.ComposeSceneMediator.onRender(ComposeSceneMediator.desktop.kt:598)
at org.jetbrains.skiko.SkiaLayer.update$skiko(SkiaLayer.awt.kt:558)
at org.jetbrains.skiko.redrawer.AWTRedrawer.update(AWTRedrawer.kt:54)
at org.jetbrains.skiko.redrawer.Direct3DRedrawer.redrawImmediately(Direct3DRedrawer.kt:74)
at org.jetbrains.skiko.SkiaLayer.tryRedrawImmediately(SkiaLayer.awt.kt:394)
at org.jetbrains.skiko.SkiaLayer.paint(SkiaLayer.awt.kt:367)
at androidx.compose.ui.scene.skia.WindowSkiaLayerComponent$contentComponent$1.paint(WindowSkiaLayerComponent.desktop.kt:64)
at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:961)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1137)
at java.desktop/javax.swing.JLayeredPane.paint(JLayeredPane.java:586)
at androidx.compose.ui.awt.JLayeredPaneWithTransparencyHack.paint(Utils.desktop.kt:121)
at java.desktop/javax.swing.JComponent.paintChildren(JComponent.java:961)
at java.desktop/javax.swing.JComponent.paint(JComponent.java:1137)
at androidx.compose.ui.window.Window_desktopKt.Window$lambda$40$lambda$39(Window.desktop.kt:629)
at androidx.compose.ui.window.AwtWindow_desktopKt.AwtWindow$lambda$7$lambda$6(AwtWindow.desktop.kt:78)
at androidx.compose.ui.util.UpdateEffect_desktopKt.UpdateEffect$lambda$8$lambda$7$performUpdate$lambda$4(UpdateEffect.desktop.kt:59)
at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2496)
at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:460)
at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:244)
at androidx.compose.ui.util.UpdateEffect_desktopKt.UpdateEffect$lambda$8$lambda$7$performUpdate(UpdateEffect.desktop.kt:55)
at androidx.compose.ui.util.UpdateEffect_desktopKt.UpdateEffect$lambda$8$lambda$7(UpdateEffect.desktop.kt:64)
at androidx.compose.runtime.DisposableEffectImpl.onRemembered(Effects.kt:83)
at androidx.compose.runtime.internal.RememberEventDispatcher.dispatchRememberObservers(RememberEventDispatcher.kt:1182)
at androidx.compose.runtime.CompositionImpl.applyChangesInLocked(Composition.kt:1044)
at androidx.compose.runtime.CompositionImpl.applyChanges(Composition.kt:1067)
at androidx.compose.runtime.Recomposer.composeInitial$runtime(Recomposer.kt:1159)
at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:2677)
at androidx.compose.ui.window.Application_desktopKt$awaitApplication$2$1$2.invokeSuspend(Application.desktop.kt:221)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:773)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Suppressed: kotlinx.coroutines.internal.DiagnosticCoroutineContextException: [androidx.compose.ui.scene.ComposeContainer$DesktopCoroutineExceptionHandler@5bbe2373, androidx.compose.runtime.BroadcastFrameClock@3c45d5c5, StandaloneCoroutine{Cancelling}@7b8a1fc6, FlushCoroutineDispatcher@1850cb73]
```
## Release Notes
N/A
Adds serialization to JSON format to collect and analyze the results of
benchmark runs.
Additionally, improve the Gradle build by using version catalogues and
modern APIs.
## Testing
A regular benchmarks execution was set on the CI.
## Release Notes
### Features - Multiple Platforms
- Improve benchmarks build and serialize results into JSON for the
collection and analysis
Benchmarks crash due to the attempt to use a cached scene that was
closed in the previous benchmark.
Create a Surface for each of the benchmarks instead.
## Testing
Testing was done manually.
## Release Notes
N/A
A script for extended CI check to not miss issues like
https://youtrack.jetbrains.com/issue/CMP-7738/Compose-fails-to-sync-in-Bazel
## Testing
```
./gradlew publishComposeJbToMavenLocal
```
```
./check.sh -Dkotlin.version=2.1.0 -Dcompose.version=9999.0.0-SNAPSHOT
```
doesn't fail on the latest jb-main, fails on 1.8.0-alpha04
## Release Notes
N/A
- Replace total CPU time by CPU/GPU/TOTAL average frame time
- Because `Mode.CPU` now measures GPU, rename it to `SIMPLE`
- Because the difference between `FRAMES` and `SIMPLE` is only in vsync,
rename it to `VSYNC_EMULATION`
- Remove `Mode.FRAMES_GPU`, as it affects only output
- Add Compose/Kotlin version, frame/warmup count
- Add writing to CSV on Desktop

Example of output into console:
```
Running emulating 120 FPS
# AnimatedVisibility
Version: 1.7.1 (Kotlin 2.1.0)
1000 frames (warmup 100)
CPU average frame time: 268.626us
GPU average frame time: 1.383332ms
TOTAL average frame time: 1.651958ms
Worst p1 CPU (ms): 2.017518ms
Worst p2 CPU (ms): 1.566880ms
Worst p5 CPU (ms): 1.188572ms
Worst p10 CPU (ms): 982.504us
Worst p25 CPU (ms): 753.478us
Worst p50 CPU (ms): 592.363us
Worst p1 GPU (ms): 5.945218ms
Worst p10 GPU (ms): 2.379730ms
Worst p50 GPU (ms): 1.909719ms
Missed frames (no buffering):
- count: 3
- ratio: 0.003
Missed frames (double buffering):
- count: 3
- ratio: 0.003
Results saved to D:\Work\compose-multiplatform\benchmarks\multiplatform\benchmarks\build\benchmarks\AnimatedVisibility.csv
# LazyGrid
...
```
## Release Notes
N/A
Fixes
https://youtrack.jetbrains.com/issue/CMP-7744/Desktop-Execution-failed-for-task-composeAppproguardReleaseJars-when-upgrade-to-CMP-1.8.0-alpha03
Also added `-dontnote androidx.**` to remove unnecessary notes about
Compose and other androidx libraries, which users can't fix themselves:
```
Note: androidx.lifecycle.ClassesInfoCache calls 'Method.getAnnotation'
Note: androidx.compose.ui.text.platform.ReflectionUtil$findAssignableField$result$1 calls 'Field.getType'
Note: androidx.compose.ui.text.platform.AwtFontUtils: can't find dynamically referenced class sun.font.CFont
Note: androidx.lifecycle.viewmodel.internal.JvmViewModelProviders accesses a declared constructor '<init>()' dynamically
```
## Testing
- `DesktopApplicationTest.proguard` fails before the fix, success after
## Release Notes
### Fixes - Desktop
- Fix `Execution failed for task ':composeApp:proguardReleaseJars'` when
`material3` is included in the project
This PR fixes compose resources for native macOS app (see currently
broken chat app using runDebugExecutableMacosArm64).
This PR also adds support for embedding resources into native macOS
framework. Similar to how it works on iOS. This allows using the macOS
compose code in an Xcode project. Just like iOS, using kotlin code as
framwork. Then call the main function from the Xcode project to run the
compose app.
https://github.com/JetBrains/compose-multiplatform/pull/5219https://github.com/JetBrains/compose-multiplatform/pull/5169
## Testing
- For executable: run chat app using runDebugExecutableMacosArm64
- For framework: Tested by adding macOS support to the iOS Xcode project
in chat app (not in this PR). Can add the sample app if needed. There
were also tests added to verify this.
## Release Notes
N/A
Treat it as a feature rather than a fix.
Example of a performance improvement:
https://github.com/JetBrains/compose-multiplatform-core/pull/1863
Alternative A - treat it as a fix, not a feature:
```
- Highlights # major features, performance improvements
- Features # minor features
- Fixes # bug fixes, undefined behavior changes, performance improvements
```
Alternative B - refer Fixes in Highlights:
```
- Highlights # major features and fixes
- Features # minor features
- Fixes # bug fixes, undefined behavior changes, performance improvements
```
## Release Notes
N/A
Fixes
https://youtrack.jetbrains.com/issue/CMP-7409/Add-a-CI-check-for-PR-containing-Release-Notes
- Add a GitHub workflow that checks Release Notes are correctly added.
Runs automatically on creation and description change
- Move the guide into one file from the PR templates
- Parse categories for the script instead of hardcoding them (to have a
single source of truth in the guide)
- Don't do network requests to avoid rate limit (60 requests per hour),
read the description from the workflow variable
Also added to
[compose-multiplatform-core](https://github.com/JetBrains/compose-multiplatform-core/pull/1900)
## Testing
1. Change Release Notes in this PR
2. CI successes with correct Release Notes
3. CI fails with incorrect ones
(Replace RR by R, otherwise the check picks a wrong section, I think no
need to write additional logic just for this PR)
Correct N/A:
```
## RRelease Notes
N/A
```
Correct change:
```
## RRelease Notes
### Features - iOS
- Simple feature
```
Release notes missing:
```
```
Title is incorrect:
```
## RRelease Note
### Features - iOS
- Simple feature
```
Section isn't standard:
```
## RRelease Notes
### Features - Compose
- Simple feature
```
Items are missing:
```
## RRelease Notes
### Features - iOS
```
Sections are missing:
```
## RRelease Notes
- Simple feature
```
## Testing
Tested for injections
1. For script injection
```
"; echo QQ > prDescription.txt #
```
2. For workflow injection
```
q
run: |
echo "QQ"
```
3. Verified that injection into `changelog.main.kts` isn't possible, as
it doesn't execute anything parsed (including links)
## Release Notes
N/A