diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ffe3800b52..c48fb88983 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -19,8 +19,8 @@ Optional, if omitted - won't be included in the changelog Sections: - Highlights -- Known issues -- Breaking changes +- Known Issues +- Breaking Changes - Features - Fixes @@ -29,6 +29,7 @@ Subsections: - iOS - Desktop - Web +- Android - Resources - Gradle Plugin --> diff --git a/.github/workflows/gradle-plugin.yml b/.github/workflows/gradle-plugin.yml index 53a51f7196..f81dac64a1 100644 --- a/.github/workflows/gradle-plugin.yml +++ b/.github/workflows/gradle-plugin.yml @@ -17,8 +17,8 @@ jobs: fail-fast: false matrix: os: [ubuntu-20.04, macos-14, windows-2022] - gradle: [7.4, 8.8] - agp: [8.1.0, 8.5.0] + gradle: [7.4, 8.10.2] + agp: [8.1.0, 8.5.0, 8.8.0-alpha08] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 @@ -33,7 +33,7 @@ jobs: ./gradlew assemble ./gradlew --continue :preview-rpc:test :compose:test ':compose:test-Gradle(${{ matrix.gradle }})-Agp(${{ matrix.agp }})' - name: Upload Reports - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: Test-Reports path: gradle-plugins/compose/build/reports diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ad7671eca..98becb896a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,639 @@ +# 1.8.0-alpha01 (November 2024) + +_Changes since 1.7.1_ + +## Highlights + +### iOS + +- [LocalUIViewController moved to the `androidx.compose.ui.uikit` module](https://github.com/JetBrains/compose-multiplatform-core/pull/1608) +- [Update `AccessibilitySyncOptions` and remove `AccessibilityDebugLogger` from public API](https://github.com/JetBrains/compose-multiplatform-core/pull/1604) +- [ComposeUIViewControllerDelegate marked as deprecated](https://github.com/JetBrains/compose-multiplatform-core/pull/1651). Use parent view controller to override the methods of the UIViewController class +- [Remove experimental flag from `fun enableTraceOSLog()`](https://github.com/JetBrains/compose-multiplatform-core/pull/1652) +- [Remove obsolete Canvas Layers mode on iOS](https://github.com/JetBrains/compose-multiplatform-core/pull/1680) + +## Breaking Changes + +### Multiple Platforms + +- [Tests that relied on `waitForIdle`, `awaitIdle` or `runOnIdle`](https://github.com/JetBrains/compose-multiplatform-core/pull/1550) (whether explicit or implicit) executing `delay`-ed coroutines will no longer work correctly. To fix this advance the test time via `mainClock` manually, as needed + For example, tests that previously did something like: + ``` + var updateText by mutableStateOf(false) + var text by mutableStateOf("0") + setContent { + LaunchedEffect(updateText) { + if (updateText) { + delay(1000) + text = "1" + } + } + } + updateText = true + waitForIdle() + assertEquals("1", text) + ``` + will need to add `mainClock.advanceTimeBy(1000)` after `waitForIdle()`, because `waitForIdle` no longer waits for the `delay`-ed coroutine to complete +- [Tests that advance the test clock](https://github.com/JetBrains/compose-multiplatform-core/pull/1550) (via `mainClock.advanceTimeBy`) may see different behavior with regards to the amount and timing of recomposition, layout, drawing and effects +- [`runOnIdle` will now execute `action` on the UI thread](https://github.com/JetBrains/compose-multiplatform-core/pull/1601) +- [`runOnIdle` will no longer call `waitForIdle` after executing the action](https://github.com/JetBrains/compose-multiplatform-core/pull/1601) +- [Advancing `mainClock` such that it doesn't reach the next frame, will no longer cause a recomposition](https://github.com/JetBrains/compose-multiplatform-core/pull/1618) + +### Desktop + +- [Deprecated/experimental `Modifier.onExternalDrag` has been removed - common `Modifier.dragAndDropTarget` API should be used instead](https://github.com/JetBrains/compose-multiplatform-core/pull/1606) + +## Features + +### Multiple Platforms + +- [Support configurable vertical text centering via `LineHeightStyle.Alignment`](https://github.com/JetBrains/compose-multiplatform-core/pull/1569) +- [Support Variable Fonts In All Platforms](https://github.com/JetBrains/compose-multiplatform-core/pull/1623) + +### iOS + +- [Add localised string for VoiceOver accessibility support](https://github.com/JetBrains/compose-multiplatform-core/pull/1441) +- [Support state announcements for scrollable lists in VoiceOver](https://github.com/JetBrains/compose-multiplatform-core/pull/1644) +- [Support for accessibility gestures for left-to-right languages](https://github.com/JetBrains/compose-multiplatform-core/pull/1663) + +### Desktop + +- [Compose plugin for IntelliJ IDEA now supports K2 mode](https://github.com/JetBrains/compose-multiplatform/pull/5138) + +### Resources + +- [Add new API to preload and cache font and image resources on web targets: `preloadFont`, `preloadImageBitmap`, `preloadImageVector`](https://github.com/JetBrains/compose-multiplatform/pull/5159) + +### Gradle Plugin + +- [Support compose resources in `androidLibrary` target](https://github.com/JetBrains/compose-multiplatform/pull/5157) + +### Navigation + +- [Basic support a navigation by deep links](https://github.com/JetBrains/compose-multiplatform-core/pull/1610) +- [Commonize `navController.navigate(Uri)` method](https://github.com/JetBrains/compose-multiplatform-core/pull/1617) +- [Implemented non-android `navController.handleDeepLink(NavDeepLinkRequest)` method](https://github.com/JetBrains/compose-multiplatform-core/pull/1617) +- [New API to configure browser navigation buttons and the address line](https://github.com/JetBrains/compose-multiplatform-core/pull/1621) +- [Navigation via a browser address field](https://github.com/JetBrains/compose-multiplatform-core/pull/1640) + +## Fixes + +### Multiple Platforms + +- [`waitForIdle`, `awaitIdle` and `runOnIdle` no longer consider Compose to be non-idle when coroutines launched in a composition scope call `delay`](https://github.com/JetBrains/compose-multiplatform-core/pull/1550). This prevents tests with an infinite loop with `delay` in a `LaunchedEffect` from hanging +- [Tests that advance the test clock](https://github.com/JetBrains/compose-multiplatform-core/pull/1550) (via `mainClock.advanceTimeBy`) will now correctly (re)compose/layout/draw/effects each virtual frame as needed +- [`runOnIdle` will now execute `action` on the UI thread, as Android behaves](https://github.com/JetBrains/compose-multiplatform-core/pull/1601) +- [`runOnIdle` will no longer call `waitForIdle` after executing the action, as Android behaves](https://github.com/JetBrains/compose-multiplatform-core/pull/1601) +- [The overhead for running an empty test has been significantly reduced](https://github.com/JetBrains/compose-multiplatform-core/pull/1615) + +### iOS + +- [Deprecate defaultUIKitMain()](https://github.com/JetBrains/compose-multiplatform-core/pull/1585) +- [Fixed visibility of `androidx.compose.material3.internal.formatWithSkeleton` that was accidently marked as public](https://github.com/JetBrains/compose-multiplatform-core/pull/1609) +- [Fix a bug where the accessibility tree did not reload when VoiceOver was enabled](https://github.com/JetBrains/compose-multiplatform-core/pull/1656) +- [Fix Display Cutout Padding when rotating the device](https://github.com/JetBrains/compose-multiplatform-core/pull/1645) + +### Desktop + +- [Fix drag-and-drop when the list of supported actions doesn't include `Move`](https://github.com/JetBrains/compose-multiplatform-core/pull/1683) +- [Fix accessibility focus when using `compose.swing.render.on.graphics=true`](https://github.com/JetBrains/compose-multiplatform-core/pull/1688) +- [Fix "Context menu on desktop shows incorrect items after the second showing"](https://github.com/JetBrains/compose-multiplatform-core/pull/1693) + +### Resources + +- [Read `android:autoMirrored="true"` property and pass it to ImageVector builder](https://github.com/JetBrains/compose-multiplatform/pull/5140) + +### Navigation + +- [Fixed `No destination with ID 0 is on the NavController's back stack` crash on iOS](https://github.com/JetBrains/compose-multiplatform-core/pull/1596) + +## Dependencies + +- Gradle Plugin `org.jetbrains.compose`, version `1.8.0-alpha01`. Based on Jetpack Compose libraries: + - [Runtime 1.8.0-alpha03](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.8.0-alpha03) + - [UI 1.8.0-alpha03](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.8.0-alpha03) + - [Foundation 1.8.0-alpha03](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.8.0-alpha03) + - [Material 1.8.0-alpha03](https://developer.android.com/jetpack/androidx/releases/compose-material#1.8.0-alpha03) + - [Material3 1.4.0-alpha01](https://developer.android.com/jetpack/androidx/releases/compose-material3#1.4.0-alpha01) + +- Lifecycle libraries `org.jetbrains.androidx.lifecycle:lifecycle-*:2.9.0-alpha01`. Based on [Jetpack Lifecycle 2.9.0-alpha03](https://developer.android.com/jetpack/androidx/releases/lifecycle#2.9.0-alpha03) +- Navigation libraries `org.jetbrains.androidx.navigation:navigation-*:2.8.0-alpha11`. Based on [Jetpack Navigation 2.8.0](https://developer.android.com/jetpack/androidx/releases/navigation#2.8.0) +- Material3 Adaptive libraries `org.jetbrains.compose.material3.adaptive:adaptive*:1.1.0-alpha01`. Based on [Jetpack Material3 Adaptive 1.1.0-alpha04](https://developer.android.com/jetpack/androidx/releases/compose-material3-adaptive#1.1.0-alpha04) + +--- + +# 1.7.1 (November 2024) + +_Changes since 1.7.0_ + +## Fixes + +### Multiple Platforms + +- [Fixed `Modifier.clickable` binary compatibility with 1.6 on non-JVM targets](https://github.com/JetBrains/compose-multiplatform-core/pull/1647) +- [Fixed `Modifier.toggleable` and `Modifier.selectable` binary compatibility with 1.6 on non-JVM targets](https://github.com/JetBrains/compose-multiplatform-core/pull/1649) +- [Fix issue where `DateRangePicker` doesn't show confirmation button on iOS and Desktop](https://github.com/JetBrains/compose-multiplatform-core/pull/1666) +- [Fix Skia paragraph caching performance degradation](https://github.com/JetBrains/compose-multiplatform-core/pull/1676) + +### iOS + +- [Fling animation works correctly for fast scrolling gestures](https://github.com/JetBrains/compose-multiplatform-core/pull/1616) +- [Fix HorizontalPager snapping on iOS](https://github.com/JetBrains/compose-multiplatform-core/pull/1661) +- [Fixed double recomposition on the first screen](https://github.com/JetBrains/compose-multiplatform-core/pull/1668) +- [Fix Accessibility Items availability inside dialogs](https://github.com/JetBrains/compose-multiplatform-core/pull/1678) +- [Memory leak due to Compose view controller never GCed](https://github.com/JetBrains/compose-multiplatform-core/pull/1660) + +### Desktop + +- [Fix for excessive garbage generation from redrawing on Swing](https://github.com/JetBrains/compose-multiplatform-core/pull/1657) + +## Dependencies + +- Gradle Plugin `org.jetbrains.compose`, version `1.7.1`. Based on Jetpack Compose libraries: + - [Runtime 1.7.5](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.7.5) + - [UI 1.7.5](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.5) + - [Foundation 1.7.5](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.7.5) + - [Material 1.7.5](https://developer.android.com/jetpack/androidx/releases/compose-material#1.7.5) + - [Material3 1.3.1](https://developer.android.com/jetpack/androidx/releases/compose-material3#1.3.1) + +- Lifecycle libraries `org.jetbrains.androidx.lifecycle:lifecycle-*:2.8.4`. Based on [Jetpack Lifecycle 2.8.5](https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.5) +- Navigation libraries `org.jetbrains.androidx.navigation:navigation-*:2.8.0-alpha10`. Based on [Jetpack Navigation 2.8.0](https://developer.android.com/jetpack/androidx/releases/navigation#2.8.0) +- Material3 Adaptive libraries `org.jetbrains.compose.material3.adaptive:adaptive*:1.0.1`. Based on [Jetpack Material3 Adaptive 1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-material3-adaptive#1.0.0) + +--- + +# 1.7.0 (October 2024) + +_Changes since 1.6.11_ + +## Highlights + +## Resources + +- [Compose Multiplatform resources are stored in the android assets now. This fixes Android Studio Preview and cases such as a rendering resource files in WebViews or Media Players](https://github.com/JetBrains/compose-multiplatform/pull/4965) + +### Navigation + +- [Shared Element Transitions](https://developer.android.com/develop/ui/compose/animation/shared-elements) +- [Safe Args in Navigation Compose](https://developer.android.com/guide/navigation/design/type-safety) + +### Web + +- [`skiko.js` is redundant in case of K/Wasm Compose Multiplatform for web applications and it can be removed from index.html files to not load redundant files](https://github.com/JetBrains/compose-multiplatform/pull/5134). `skiko.js` will be removed from the k/wasm distribution in the future releases. `skiko.js` is still needed in case of K/JS Compose Multiplatform for web apps + +## Breaking changes + +### iOS + +- [`UIKitView` and `UIKitViewController` in `package androidx.compose.ui.interop` are deprecated](https://github.com/JetBrains/compose-multiplatform-core/pull/1494). New API are mentioned in deprecation message. Deprecated invocations should work fine unless custom `onResize` is used, it is disallowed now and will print a warning. +- [Actual of expected `InteropView` on iOS is `UIResponder` now instead of `UIView`](https://github.com/JetBrains/compose-multiplatform-core/pull/1489). It's the first common ancestor for `UIViewController` and `UIView`, both of which can be integrated using iOS interop APIs +- [The app will crash by default, if `CADisableMinimumFrameDurationOnPhone` is not set to true in `Info.plist`](https://github.com/JetBrains/compose-multiplatform-core/pull/1451). Use newly added `ComposeUIViewControllerConfiguration.enforceStrictPlistSanityCheck` to opt-out of this behavior + +### Desktop + +- [`Modifier.onExternalDrag` has been deprecated in favor of the new `Modifier.dragAndDropTarget`](https://github.com/JetBrains/compose-multiplatform-core/pull/1528) + +### Android + +- [Minimal supported AGP raised to 8.1.0](https://github.com/JetBrains/compose-multiplatform/pull/4840) + +### Resources + +- [Deprecate resources in `compose.ui` in favour of the new resource library](https://github.com/JetBrains/compose-multiplatform-core/pull/1457) + +## Features + +### Multiple Platforms +- [The `clickable` modifier now responds to NumPadEnter and Spacebar, too, in addition to Enter](https://github.com/JetBrains/compose-multiplatform-core/pull/1464) +- [`LocalLifecycleOwner` moved from Compose UI to `lifecycle-runtime-compose` so that its Compose-based helper APIs can be used outside of Compose UI](https://github.com/JetBrains/compose-multiplatform-core/pull/1449) +- [Skia is updated to m126](https://github.com/JetBrains/compose-multiplatform-core/pull/1486) +- [Commonized `org.jetbrains.compose.material3:material3-window-size-class` module](https://github.com/JetBrains/compose-multiplatform-core/pull/1466) +- [Commonized `org.jetbrains.compose.material3.adaptive:adaptive*` modules](https://github.com/JetBrains/compose-multiplatform-core/pull/1468) +- [New multiplatform module "material-navigation" (in beta status)](https://github.com/JetBrains/compose-multiplatform-core/pull/1504) +- [`material3-adaptive-navigation-suite` is multiplatform now](https://github.com/JetBrains/compose-multiplatform-core/pull/1539) +- [Support Kotlin 1.9.25](https://github.com/JetBrains/compose-multiplatform/pull/5141) + +### iOS + +- [Initial iOS floating cursor support](https://github.com/JetBrains/compose-multiplatform-core/pull/1312) +- [Added `accessibilityEnabled: Boolean = true` argument to `UIKitView` and `UIKitViewController`](https://github.com/JetBrains/compose-multiplatform-core/pull/1350) +- [`preferredStatusBarStyle`, `preferredStatysBarAnimation` and `prefersStatusBarHidden` are added to `ComposeUIViewControllerDelegate` to allow status bar appearance modification](https://github.com/JetBrains/compose-multiplatform-core/pull/1378) +- [Improvements in touches processing to detect if touches were meant to be delivered to interop views, or should be processed by Compose](https://github.com/JetBrains/compose-multiplatform-core/pull/1440) +- [New `UIKitView` and `UIKitViewController` API in `package androidx.compose.ui.viewinterop`](https://github.com/JetBrains/compose-multiplatform-core/pull/1494). Support of `onReset` to reuse the interop composable emitted node and avoid excessive native views reallocations, fine-grain touches strategy control (cooperative with explicit time delay, non-cooperative where no touches are received by Compose, ignoring touches) +- [Basic support for `BasicTextField(TextFieldState, ...)` on iOS](https://github.com/JetBrains/compose-multiplatform-core/pull/1540) + +### Desktop + +- [Add constructor with `RenderSettings` to `ComposePanel`. Added a class `RenderSettings` with `val isVsyncEnabled: Boolean?`. When set to `true` gives a hint to renderer implementation of the particular `ComposePanel` to reduce the latency between the input and visual changes in exchange for possible screen tearing](https://github.com/JetBrains/compose-multiplatform-core/pull/1377) +- [Add public `moveEnabled` and `positionPercentage` setters in `SplitPaneState`](https://github.com/JetBrains/compose-multiplatform/pull/3974) +- [Implemented Drag-and-Drop from AOSP: `Modifier.dragAndDropSource` and `Modifier.dragAndDropTarget`](https://github.com/JetBrains/compose-multiplatform-core/pull/1433) +- [Added support for input methods (languages such as Chinese, Korean, Arabic) to BasicTextField(TextFieldState, ...)](https://github.com/JetBrains/compose-multiplatform-core/pull/1496) +- [Add dynamic Drag&Drop target indication](https://github.com/JetBrains/compose-multiplatform-core/pull/1510) (🚫 icon under cursor if currently there is no valid drop target under it) +- [The thickness of border resizers in undecorated windows and dialogs can now be controlled by passing a new `decoration` argument](https://github.com/JetBrains/compose-multiplatform-core/pull/1505) + +### Resources + +- [Speed resources web rendering up by the reading a cached value instantly](https://github.com/JetBrains/compose-multiplatform/pull/4893) +- [If there is no resource with suitable density, use resource with the most suitable density, otherwise use default (similar to the Android logic)](https://github.com/JetBrains/compose-multiplatform/pull/4969) +- [Add a customization for resources directories. Now it is possible to use e.g downloaded resources](https://github.com/JetBrains/compose-multiplatform/pull/5016) +- [Now the gradle plugin generates resources map to find a resource by a string ID](https://github.com/JetBrains/compose-multiplatform/pull/5068) +- [To avoid constant reading raw font bytes on each Font usage on non-android targets, there was added the font cache. Android has own font cache inside the platform implementation](https://github.com/JetBrains/compose-multiplatform/pull/5109) +- [Added utility functions to decode `Bitmap ByteArray as ImageVector` and `XML ByteArray as ImageVector` in the common code and `SVG ByteArray as Painter` in the non-android code](https://github.com/JetBrains/compose-multiplatform/pull/5098) +- [Added support of test resources in Compose Multiplatform projects](https://github.com/JetBrains/compose-multiplatform/pull/5122) +- [Added support of multi-module resources in JVM-only projects](https://github.com/JetBrains/compose-multiplatform/pull/5122) + +### Gradle Plugin + +- [New `compose.material3AdaptiveNavigationSuite` shortcut in the gradle plugin](https://github.com/JetBrains/compose-multiplatform/pull/5133) + +## Fixes + +### Multiple Platforms + +- [Fix "ComposePanel. Focus moves to child after focusing/unfocusing the main window"](https://github.com/JetBrains/compose-multiplatform-core/pull/1398) +- [Don't show code completion for non-existenst API in `commonMain` that fails on Android with `NoSuchMethodException`](https://github.com/JetBrains/compose-multiplatform-core/pull/1328) +- [Fix order of interop elements in some cases](https://github.com/JetBrains/compose-multiplatform-core/pull/1340) +- [Fixed `Popup` jerking during ripple effect animation](https://github.com/JetBrains/compose-multiplatform-core/pull/1385) +- [Fix applying `ShaderBrush` to part of `AnnotatedString`](https://github.com/JetBrains/compose-multiplatform-core/pull/1389) +- [Fix text `brush` animation and optimized updating some visual text properties (applying time is reduced up to 40%)](https://github.com/JetBrains/compose-multiplatform-core/pull/1395) +- [Fix initial cursor position in the empty `TextField` with explicitly set `TextAlignment`](https://github.com/JetBrains/compose-multiplatform-core/pull/1354) +- [Fix focus for editable `TextField` inside `ExposedDropdownMenuBox`](https://github.com/JetBrains/compose-multiplatform-core/pull/1423) +- [Fix changing `FontRenderingSettings` is not reflected until composition restarts](https://github.com/JetBrains/compose-multiplatform-core/pull/1595) + +### iOS + +- [Pressing directional keys on a physical keyboard connected to iOS device doesn't cause a crash](https://github.com/JetBrains/compose-multiplatform-core/pull/1383) +- [Dismissing popup or dialogue within a very short timespan after its creation doesn't cause a crash](https://github.com/JetBrains/compose-multiplatform-core/pull/1384) +- [Fix missing invalidations during native view resize](https://github.com/JetBrains/compose-multiplatform-core/pull/1387) +- [Fixed a memory spike when continuously resizing the `ComposeUIViewController` (such as when used in modal sheet presentation context with different detents)](https://github.com/JetBrains/compose-multiplatform-core/pull/1390) +- [visibility of selection handles in single-line textfields with LTR + RTL text in iOS](https://github.com/JetBrains/compose-multiplatform-core/pull/1331) +- [Interop views are now correctly clipped when their measured clipped and unclipped bounding boxes don't match](https://github.com/JetBrains/compose-multiplatform-core/pull/1430) +- [Touches inside interop views are not exclusive to them and are processed on Compose side as well.](https://github.com/JetBrains/compose-multiplatform-core/pull/1426) +- [Fix `material3.ModalBottomSheet` safe area usage](https://github.com/JetBrains/compose-multiplatform-core/pull/1438) +- [Fix hiding interop element during quick scroll](https://github.com/JetBrains/compose-multiplatform-core/pull/1425) +- [Fixed the keyboard appearing when selecting from SelectionContainer](https://github.com/JetBrains/compose-multiplatform-core/pull/1448) +- [Fix status bar padding on iPad devices](https://github.com/JetBrains/compose-multiplatform-core/pull/1442) +- [VoiceOver doesn't allow to perform a11y actions (scrolling, activate, customActions) when disabled() semantics is present in affected element](https://github.com/JetBrains/compose-multiplatform-core/pull/1446) +- [Fix frame drops when dragging scrollable content on iOS](https://github.com/JetBrains/compose-multiplatform-core/pull/1503) +- [A new approach to implementation of `platformLayers`.](https://github.com/JetBrains/compose-multiplatform-core/pull/1515) Now extra layers (such as Dialogs and Popups) drawing is merged into a single screen size canvas. No jittering and crashes should happen with those anymore. +- [`Dialog`s and `Popup`s now have their insets calculated correctly even when the frame of `ComposeUIViewController` spawning them doesn't intersect any safe areas](https://github.com/JetBrains/compose-multiplatform-core/pull/1515) +- [Fix offset issues with keyboard and `TextField`](https://github.com/JetBrains/compose-multiplatform-core/pull/1523) +- [Fix "Incorrect `imePadding` and high cpu usage when repeatedly opening and closing `Keyboard` on iOS"](https://github.com/JetBrains/compose-multiplatform-core/pull/1523) +- [Fix "Selection handlers in wrong positions in a fullscreen TextField"](https://github.com/JetBrains/compose-multiplatform-core/pull/1523) +- [Fix keyboard closing while scrolling content with Text Fields](https://github.com/JetBrains/compose-multiplatform-core/pull/1558) +- [Fix "UriHandler.openUri no longer works on iOS 18"](https://github.com/JetBrains/compose-multiplatform-core/pull/1595) + +### Desktop + +- [Fix possible `UninitializedPropertyAccessException` in `desktopTest`](https://github.com/JetBrains/compose-multiplatform-core/pull/1343) +- [Fixed `ComposePanel.requestFocus()`, making it correctly assign focus to the first focusable child](https://github.com/JetBrains/compose-multiplatform-core/pull/1352) +- [When using `ComposePanel` inside a Swing application on macOS, VoiceOver will now correctly go into the `ComposePanel` when traversing accessible elements](https://github.com/JetBrains/compose-multiplatform-core/pull/1362) +- [When using `ComposePanel` inside a Swing application on Windows with NVDA turned on, focus will now correctly go into the `ComposePanel` when traversing with (ctrl)-shift-tab](https://github.com/JetBrains/compose-multiplatform-core/pull/1363) +- [Correctly save `WindowState` with unspecified `size` instead of crashing](https://github.com/JetBrains/compose-multiplatform-core/pull/1394) +- [Fix `IndexOutOfBoundsException` crash on Windows when traversing a11y elements](https://github.com/JetBrains/compose-multiplatform-core/pull/1415) +- [Fix scrolling non-same direction nested scrolls with trackpad](https://github.com/JetBrains/compose-multiplatform-core/pull/1434) +- [Fix fling velocity for precise wheel scroll](https://github.com/JetBrains/compose-multiplatform-core/pull/1402) +- [[macOS] Fix crash when right-clicking an empty `SelectionContainer` or on the padding of a `Text` inside a `SelectionContainer`](https://github.com/JetBrains/compose-multiplatform-core/pull/1439) +- [Fix bounds of `ComposePanel` in IntelliJ on macOs](https://github.com/JetBrains/compose-multiplatform-core/pull/1571) +- [Fix UI glitch when resizing a Compose window via its `WindowState`](https://github.com/JetBrains/compose-multiplatform-core/pull/1565) + +### Web + +- [Process `keydown` and `keyup` keys for identified keys from virtual keyboard](https://github.com/JetBrains/compose-multiplatform-core/pull/1380) +- [Allow preloading the fallback fonts. This enables the usage of emojis and other unicode characters without manually composing the Text with AnnotatedString](https://github.com/JetBrains/compose-multiplatform-core/pull/1400) +- [Make sure the web app distribution doesn't contain a duplicate `skiko.wasm`](https://github.com/JetBrains/compose-multiplatform/pull/4958) +- [Prevent a crash on mobile web when selecting some text in `SelectionContainer`](https://github.com/JetBrains/compose-multiplatform-core/pull/1551) + +### Resources + +- [Delete `contextClassLoader` usage on JVM targets](https://github.com/JetBrains/compose-multiplatform/pull/4895) +- [Create an empty resource dir with "podspec" task instead "podInstall"](https://github.com/JetBrains/compose-multiplatform/pull/4900) +- [Fix resource accessors escaping. Now it is possible to use resources with names: "package", "is", "item_$xxx" etc](https://github.com/JetBrains/compose-multiplatform/pull/4901) +- [Read exactly requested count of bytes from InputStream on jvm platforms](https://github.com/JetBrains/compose-multiplatform/pull/4943) +- [Now drawables from upper DPIs will be downscalled to the expected size. (the same behavior as on Android)](https://github.com/JetBrains/compose-multiplatform/pull/5101) + +### Gradle Plugin + +- [Make sure tryGetSkikoRuntimeIfNeeded is executed only during the task execution](https://github.com/JetBrains/compose-multiplatform/pull/4918) +- [Delete outdated build services](https://github.com/JetBrains/compose-multiplatform/pull/4959) +- [Support project isolation](https://github.com/JetBrains/compose-multiplatform/pull/5120) +- [Fix a gradle project misconfiguration when KSP and Room are used](https://github.com/JetBrains/compose-multiplatform/pull/5129) + +## Dependencies + +- Gradle Plugin `org.jetbrains.compose`, version `1.7.0`. Based on Jetpack Compose libraries: + - [Runtime 1.7.1](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.7.1) + - [UI 1.7.1](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.1) + - [Foundation 1.7.1](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.7.1) + - [Material 1.7.1](https://developer.android.com/jetpack/androidx/releases/compose-material#1.7.1) + - [Material3 1.3.0](https://developer.android.com/jetpack/androidx/releases/compose-material3#1.3.0) + +- Lifecycle libraries `org.jetbrains.androidx.lifecycle:lifecycle-*:2.8.3`. Based on [Jetpack Lifecycle 2.8.5](https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.5) +- Navigation libraries `org.jetbrains.androidx.navigation:navigation-*:2.8.0-alpha10`. Based on [Jetpack Navigation 2.8.0](https://developer.android.com/jetpack/androidx/releases/navigation#2.8.0) +- Material3 Adaptive libraries `org.jetbrains.compose.material3.adaptive:adaptive*:1.0.0`. Based on [Jetpack Material3 Adaptive 1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-material3-adaptive#1.0.0) + +--- + +# 1.7.0-rc01 (September 2024) + +_Changes since 1.7.0-beta02_ + +## Highlights + +### Web + +- [`skiko.js` is redundant in case of K/Wasm Compose Multiplatform for web applications and it can be removed from index.html files to not load redundant files](https://github.com/JetBrains/compose-multiplatform/pull/5134). `skiko.js` will be removed from the k/wasm distribution in the future releases. `skiko.js` is still needed in case of K/JS Compose Multiplatform for web apps + +## Features + +### Multiple Platforms + +- [Support Kotlin 1.9.25](https://github.com/JetBrains/compose-multiplatform/pull/5141) + +### Desktop + +- _(prerelease fix)_ [The `decoration` parameter added to `Window` and `DialogWindow` and the APIs related to it are now marked as experimental](https://github.com/JetBrains/compose-multiplatform-core/pull/1561) + +### Gradle Plugin + +- [New `compose.material3AdaptiveNavigationSuite` shortcut in the gradle plugin](https://github.com/JetBrains/compose-multiplatform/pull/5133) + +## Fixes + +### Multiple Platforms + +- _(prerelease fix)_ [Fix possible infinity invalidation loop triggered by `GraphicsLayer.record`](https://github.com/JetBrains/compose-multiplatform-core/pull/1555) +- [Fix changing `FontRenderingSettings` is not reflected until composition restarts](https://github.com/JetBrains/compose-multiplatform-core/pull/1595) + +### iOS + +- _(prerelease fix)_ [Fix "`ListDetailPaneScaffold` from material3-adaptive throws ArrayIndexOutOfBoundsException"](https://github.com/JetBrains/compose-multiplatform-core/pull/1548) +- _(prerelease fix)_ [Fix "White bars on sides on some devices"](https://github.com/JetBrains/compose-multiplatform-core/pull/1547) +- [Fix offset issues with keyboard and `TextField`](https://github.com/JetBrains/compose-multiplatform-core/pull/1523) +- [Fix "Incorrect `imePadding` and high cpu usage when repeatedly opening and closing `Keyboard` on iOS"](https://github.com/JetBrains/compose-multiplatform-core/pull/1523) +- [Fix "Selection handlers in wrong positions in a fullscreen TextField"](https://github.com/JetBrains/compose-multiplatform-core/pull/1523) +- [Fix keyboard closing while scrolling content with Text Fields](https://github.com/JetBrains/compose-multiplatform-core/pull/1558) +- _(prerelease fix)_ [Fix missing interop views with new `onReset` argument and placing inside more complex reusable layout inside `Lazy*` lists](https://github.com/JetBrains/compose-multiplatform-core/pull/1560) +- _(prerelease fix)_ [Fix selection handlers height for `BasicTextField` on iOS](https://github.com/JetBrains/compose-multiplatform-core/pull/1587) +- _(prerelease fix)_ [To avoid `Symbol not found: _objc_release_x8` crash on iOS 15 simulators, skia has been re-built with downgraded Xcode](https://github.com/JetBrains/compose-multiplatform-core/pull/1595) (13.1) +- [Fix "UriHandler.openUri no longer works on iOS 18"](https://github.com/JetBrains/compose-multiplatform-core/pull/1595) + +### Desktop + +- [Fix bounds of `ComposePanel` in IntelliJ on macOs](https://github.com/JetBrains/compose-multiplatform-core/pull/1571) +- [Fix UI glitch when resizing a Compose window via its `WindowState`](https://github.com/JetBrains/compose-multiplatform-core/pull/1565) + +### Web + +- [Prevent a crash on mobile web when selecting some text in `SelectionContainer`](https://github.com/JetBrains/compose-multiplatform-core/pull/1551) + +### Android + +- _(prerelease fix)_ [Fix "Compose UI test error on android: No static method forceEnableAppTracing"](https://github.com/JetBrains/compose-multiplatform-core/pull/1564) +- _(prerelease fix)_ [Fix "Android target depends on prerelease versions"](https://github.com/JetBrains/compose-multiplatform-core/pull/1564) + +### Navigation + +- _(prerelease fix)_ [Fix `IllegalArgumentException` on putting lists into `savedStateHandle`](https://github.com/JetBrains/compose-multiplatform-core/pull/1546) + +## Dependencies + +- Gradle Plugin `org.jetbrains.compose`, version `1.7.0-rc01`. Based on Jetpack Compose libraries: + - [Runtime 1.7.0](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.7.0) + - [UI 1.7.0](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.0) + - [Foundation 1.7.0](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.7.0) + - [Material 1.7.0](https://developer.android.com/jetpack/androidx/releases/compose-material#1.7.0) + - [Material3 1.3.0](https://developer.android.com/jetpack/androidx/releases/compose-material3#1.3.0) + +- Lifecycle libraries `org.jetbrains.androidx.lifecycle:lifecycle-*:2.8.2`. Based on [Jetpack Lifecycle 2.8.4](https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4) +- Navigation libraries `org.jetbrains.androidx.navigation:navigation-*:2.8.0-alpha10`. Based on [Jetpack Navigation 2.8.0-rc01](https://developer.android.com/jetpack/androidx/releases/navigation#2.8.0-rc01) +- Material3 Adaptive libraries `org.jetbrains.compose.material3.adaptive:adaptive*:1.0.0-rc01`. Based on [Jetpack Material3 Adaptive 1.0.0](https://developer.android.com/jetpack/androidx/releases/compose-material3-adaptive#1.0.0) + +--- + +# 1.7.0-beta02 (September 2024) + +_Changes since 1.7.0-beta01_ + +## Breaking changes +### Desktop +- [`Modifier.onExternalDrag` has been deprecated in favor of the new `Modifier.dragAndDropTarget`](https://github.com/JetBrains/compose-multiplatform-core/pull/1528) + +### Resources +- [Deprecate resources in `compose.ui` in favour of the new resource library](https://github.com/JetBrains/compose-multiplatform-core/pull/1457) + +## Features +### Multiple Platforms +- [`material3-adaptive-navigation-suite` is multiplatform now](https://github.com/JetBrains/compose-multiplatform-core/pull/1539) + +### iOS +- [Basic support for BasicTextField(TextFieldState, ...) on iOS](https://github.com/JetBrains/compose-multiplatform-core/pull/1540) + +### Desktop +- [The thickness of border resizers in undecorated windows and dialogs can now be controlled by passing a new `decoration` argument](https://github.com/JetBrains/compose-multiplatform-core/pull/1505) + +## Fixes +### Multiple Platforms +- _(prerelease fix)_ [Fix `GraphicsLayer` perspective matrix calculation and missing invalidations](https://github.com/JetBrains/compose-multiplatform-core/pull/1541) +- _(prerelease fix)_ [Fix Wasm/Native ArrayIndexOutOfBoundsException exception in adaptive-layout module](https://github.com/JetBrains/compose-multiplatform-core/pull/1545) + +### iOS +- [A new approach to implementation of `platformLayers`.](https://github.com/JetBrains/compose-multiplatform-core/pull/1515) Now extra layers (such as Dialogs and Popups) drawing is merged into a single screen size canvas. No jittering and crashes should happen with those anymore. +- [`Dialog`s and `Popup`s now have their insets calculated correctly even when the frame of `ComposeUIViewController` spawning them doesn't intersect any safe areas](https://github.com/JetBrains/compose-multiplatform-core/pull/1515) + +### Desktop +- _(prerelease fix)_ [Fix "Moving after initiating a click cancels it"](https://github.com/JetBrains/compose-multiplatform-core/pull/1534) + +### Resources +- _(prerelease fix)_ [Fix Cocoapods resources integration which leaded to a lack resources in iOS apps](https://github.com/JetBrains/compose-multiplatform/pull/5128) + +### Gradle Plugin +- [Fix a gradle project misconfiguration when KSP and Room are used](https://github.com/JetBrains/compose-multiplatform/pull/5129) + +### Lifecycle +- Lifecycle 2.8.2 depends on Compose 1.6.11 (Lifecycle 2.8.1 accidentaly made dependent on Compose 1.7.0-beta01) + +### Navigation +- _(prerelease fix)_ [Fix saving state for nested `NavHostController`](https://github.com/JetBrains/compose-multiplatform-core/pull/1508) +- _(prerelease fix)_ [Fixed missing commonization for type-safe version of `SavedStateHandle.toRoute`](https://github.com/JetBrains/compose-multiplatform-core/pull/1521) + +## Dependencies +- Gradle Plugin `org.jetbrains.compose`, version `1.7.0-beta02`. Based on Jetpack Compose libraries: + - [Runtime 1.7.0-rc01](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.7.0-rc01) + - [UI 1.7.0-rc01](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.0-rc01) + - [Foundation 1.7.0-rc01](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.7.0-rc01) + - [Material 1.7.0-rc01](https://developer.android.com/jetpack/androidx/releases/compose-material#1.7.0-rc01) + - [Material3 1.3.0-rc01](https://developer.android.com/jetpack/androidx/releases/compose-material3#1.3.0-rc01) + +- Lifecycle libraries `org.jetbrains.androidx.lifecycle:lifecycle-*:2.8.2`. Based on [Jetpack Lifecycle 2.8.4](https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4) +- Navigation libraries `org.jetbrains.androidx.navigation:navigation-*:2.8.0-alpha10`. Based on [Jetpack Navigation 2.8.0-rc01](https://developer.android.com/jetpack/androidx/releases/navigation#2.8.0-rc01) +- Material3 Adaptive libraries `org.jetbrains.compose.material3.adaptive:adaptive*:1.0.0-alpha03`. Based on [Jetpack Material3 Adaptive 1.0.0-rc01](https://developer.android.com/jetpack/androidx/releases/compose-material3-adaptive#1.0.0-rc01) + +--- + +# 1.7.0-beta01 (September 2024) + +_Changes since 1.7.0-alpha03_ + +## Breaking changes +### iOS +- [`UIKitView` and `UIKitViewController` in `package androidx.compose.ui.interop` are deprecated](https://github.com/JetBrains/compose-multiplatform-core/pull/1494). New API are mentioned in deprecation message. Deprecated invocations should work fine unless custom `onResize` is used, it is disallowed now and will print a warning. +- [Actual of expected `InteropView` on iOS is `UIResponder` now instead of `UIView`](https://github.com/JetBrains/compose-multiplatform-core/pull/1489). It's the first common ancestor for `UIViewController` and `UIView`, both of which can be integrated using iOS interop APIs +- [The app will crash by default, if `CADisableMinimumFrameDurationOnPhone` is not set to true in `Info.plist`](https://github.com/JetBrains/compose-multiplatform-core/pull/1451). Use newly added `ComposeUIViewControllerConfiguration.enforceStrictPlistSanityCheck` to opt-out of this behavior + +## Features +### Multiple Platforms +- [New multiplatform module "material-navigation" (in beta status)](https://github.com/JetBrains/compose-multiplatform-core/pull/1504) + +### iOS +- [New `UIKitView` and `UIKitViewController` API in `package androidx.compose.ui.viewinterop`](https://github.com/JetBrains/compose-multiplatform-core/pull/1494). Support of `onReset` to reuse the interop composable emitted node and avoid excessive native views reallocations, fine-grain touches strategy control (cooperative with explicit time delay, non-cooperative where no touches are received by Compose, ignoring touches) + +### Desktop +- [Added support for input methods (languages such as Chinese, Korean, Arabic) to BasicTextField(TextFieldState, ...)](https://github.com/JetBrains/compose-multiplatform-core/pull/1496) +- [Add dynamic Drag&Drop target indication](https://github.com/JetBrains/compose-multiplatform-core/pull/1510) (🚫 icon under cursor if currently there is no valid drop target under it) + +### Resources +- [Added support of test resources in Compose Multiplatform projects](https://github.com/JetBrains/compose-multiplatform/pull/5122) +- [Added support of multi-module resources in JVM-only projects](https://github.com/JetBrains/compose-multiplatform/pull/5122) + +## Fixes +### Multiple Platforms +- _(prerelease fix)_ [Fix redirect on android artifacts for "window-core" module](https://github.com/JetBrains/compose-multiplatform-core/pull/1506) + +### iOS +- [Fix frame drops when dragging scrollable content on iOS](https://github.com/JetBrains/compose-multiplatform-core/pull/1503) + +### Desktop +- _(prerelease fix)_ [Fixed drag-and-drop not working after a popup is displayed in the window](https://github.com/JetBrains/compose-multiplatform-core/pull/1493) + +### Resources +- _(prerelease fix)_ [Fix a resource reading on iOS 12](https://github.com/JetBrains/compose-multiplatform/pull/5123) +- _(prerelease fix)_ [Fix resource reading on Java 11](https://github.com/JetBrains/compose-multiplatform/pull/5125) + +### Gradle Plugin +- [Support project isolation](https://github.com/JetBrains/compose-multiplatform/pull/5120) + +## Dependencies +- Gradle Plugin `org.jetbrains.compose`, version `1.7.0-beta01`. Based on Jetpack Compose libraries: + - [Runtime 1.7.0-rc01](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.7.0-rc01) + - [UI 1.7.0-rc01](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.0-rc01) + - [Foundation 1.7.0-rc01](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.7.0-rc01) + - [Material 1.7.0-rc01](https://developer.android.com/jetpack/androidx/releases/compose-material#1.7.0-rc01) + - [Material3 1.3.0-rc01](https://developer.android.com/jetpack/androidx/releases/compose-material3#1.3.0-rc01) + +- Lifecycle libraries `org.jetbrains.androidx.lifecycle:lifecycle-*:2.8.1`. Based on [Jetpack Lifecycle 2.8.4](https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.4) +- Navigation libraries `org.jetbrains.androidx.navigation:navigation-*:2.8.0-alpha09`. Based on [Jetpack Navigation 2.8.0-beta05](https://developer.android.com/jetpack/androidx/releases/navigation#2.8.0-beta05) +- Material3 Adaptive libraries `org.jetbrains.compose.material3.adaptive:adaptive*:1.0.0-alpha02`. Based on [Jetpack Material3 Adaptive 1.0.0-rc01](https://developer.android.com/jetpack/androidx/releases/compose-material3-adaptive#1.0.0-rc01) + +--- + +# 1.7.0-alpha03 (August 2024) + +_Changes since 1.7.0-alpha02_ + +## Features +### Multiple Platforms +- [Skia is updated to m126](https://github.com/JetBrains/compose-multiplatform-core/pull/1486) +- [Commonized `org.jetbrains.compose.material3:material3-window-size-class` module](https://github.com/JetBrains/compose-multiplatform-core/pull/1466) +- [Commonized `org.jetbrains.compose.material3.adaptive:adaptive*` modules](https://github.com/JetBrains/compose-multiplatform-core/pull/1468) + +### Resources +- [Added utility functions to decode `Bitmap ByteArray as ImageVector` and `XML ByteArray as ImageVector` in the common code and `SVG ByteArray as Painter` in the non-android code](https://github.com/JetBrains/compose-multiplatform/pull/5098) + +## Fixes +### Desktop +- [[macOS] Fix crash when right-clicking an empty `SelectionContainer` or on the padding of a `Text` inside a `SelectionContainer`](https://github.com/JetBrains/compose-multiplatform-core/pull/1439) +- [_(prerelease fix)_ Fix input methods position on the screen and `NullPointerException: Cannot read field`](https://github.com/JetBrains/compose-multiplatform-core/pull/1491) + +### iOS +- [_(prerelease fix)_ Fix the bug where only the changed touches were sent Compose, while all tracked touches were expected](https://github.com/JetBrains/compose-multiplatform-core/pull/1477) + +### Gradle Plugin +- [_(prerelease fix)_ Fix broken configuration cache due Android Studio + AGP issues. Now Android Studio previews require latest AGP versions (8.5.2, 8.6.0-rc01, 8.7.0-alpha04): https://issuetracker.google.com/issues/348208777](https://github.com/JetBrains/compose-multiplatform/pull/5118) + +## Dependencies +- Gradle Plugin `org.jetbrains.compose`, version `1.7.0-alpha03`. Based on Jetpack Compose libraries: + - [Runtime 1.7.0-beta06](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.7.0-beta06) + - [UI 1.7.0-beta06](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.0-beta06) + - [Foundation 1.7.0-beta06](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.7.0-beta06) + - [Material 1.7.0-beta06](https://developer.android.com/jetpack/androidx/releases/compose-material#1.7.0-beta06) + - [Material3 1.3.0-beta05](https://developer.android.com/jetpack/androidx/releases/compose-material3#1.3.0-beta05) + +- Lifecycle libraries `org.jetbrains.androidx.lifecycle:lifecycle-*:2.8.0`. Based on [Jetpack Lifecycle 2.8.0](https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.0) +- Navigation libraries `org.jetbrains.androidx.navigation:navigation-*:2.8.0-alpha09`. Based on [Jetpack Navigation 2.8.0-beta05](https://developer.android.com/jetpack/androidx/releases/navigation#2.8.0-beta05) +- Material3 Adaptive libraries `org.jetbrains.compose.material3.adaptive:adaptive*:1.0.0-alpha01`. Based on [Jetpack Material3 Adaptive 1.0.0-beta04](https://developer.android.com/jetpack/androidx/releases/compose-material3-adaptive#1.0.0-beta04) + +To use Material3 Adaptive add the dependencies for the artifacts you need in the `build.gradle` file for your app or module: +```Kotlin +dependencies { + implementation("org.jetbrains.compose.material3.adaptive:adaptive:1.0.0-alpha01") + implementation("org.jetbrains.compose.material3.adaptive:adaptive-layout:1.0.0-alpha01") + implementation("org.jetbrains.compose.material3.adaptive:adaptive-navigation:1.0.0-alpha01") +} +``` + +___ + +# 1.7.0-alpha02 (July 2024) + +_Changes since 1.7.0-alpha01_ + +## Features + +### Multiple Platforms +- [The `clickable` modifier now responds to NumPadEnter and Spacebar, too, in addition to Enter](https://github.com/JetBrains/compose-multiplatform-core/pull/1464) +- [`LocalLifecycleOwner` moved from Compose UI to `lifecycle-runtime-compose` so that its Compose-based helper APIs can be used outside of Compose UI](https://github.com/JetBrains/compose-multiplatform-core/pull/1449) + +### iOS +- [Improvements in touches processing to detect if touches were meant to be delivered to interop views, or should be processed by Compose](https://github.com/JetBrains/compose-multiplatform-core/pull/1440) + +### Desktop +- [Implemented Drag-and-Drop from AOSP: `Modifier.dragAndDropSource` and `Modifier.dragAndDropTarget`](https://github.com/JetBrains/compose-multiplatform-core/pull/1433) + +### Resources +- [Now the gradle plugin generates resources map to find a resource by a string ID](https://github.com/JetBrains/compose-multiplatform/pull/5068) +- [To avoid constant reading raw font bytes on each Font usage on non-android targets, there was added the font cache. Android has own font cache inside the platform implementation](https://github.com/JetBrains/compose-multiplatform/pull/5109) + +## Fixes + +### Multiple Platforms +- [_(prerelease fix)_ Restore missing `SearchBar` changes from `material3` 1.3](https://github.com/JetBrains/compose-multiplatform-core/pull/1455) + +### iOS +- [Interop views are now correctly clipped when their measured clipped and unclipped bounding boxes don't match](https://github.com/JetBrains/compose-multiplatform-core/pull/1430) +- [Touches inside interop views are not exclusive to them and are processed on Compose side as well.](https://github.com/JetBrains/compose-multiplatform-core/pull/1426) +- [Fix `material3.ModalBottomSheet` safe area usage](https://github.com/JetBrains/compose-multiplatform-core/pull/1438) +- [Fix hiding interop element during quick scroll](https://github.com/JetBrains/compose-multiplatform-core/pull/1425) +- [_(prerelease fix)_ Fixed floating cursor isn't working](https://github.com/JetBrains/compose-multiplatform-core/pull/1443) +- [Fixed the keyboard appearing when selecting from SelectionContainer](https://github.com/JetBrains/compose-multiplatform-core/pull/1448) +- [Fix status bar padding on iPad devices](https://github.com/JetBrains/compose-multiplatform-core/pull/1442) +- [VoiceOver doesn't allow to perform a11y actions (scrolling, activate, customActions) when disabled() semantics is present in affected element](https://github.com/JetBrains/compose-multiplatform-core/pull/1446) + +### Desktop +- [Fix scrolling non-same direction nested scrolls with trackpad](https://github.com/JetBrains/compose-multiplatform-core/pull/1434) +- [Fix fling velocity for precise wheel scroll](https://github.com/JetBrains/compose-multiplatform-core/pull/1402) +- [_(prerelease fix)_ Fix remaining focus indication after a click](https://github.com/JetBrains/compose-multiplatform-core/pull/1467) + +### Resources +- [_(prerelease fix)_ Fix an android app compose resources packaging broken after introduction AS previews](https://github.com/JetBrains/compose-multiplatform/pull/5090) +- [Now drawables from upper DPIs will be downscalled to the expected size. (the same behavior as on Android)](https://github.com/JetBrains/compose-multiplatform/pull/5101) + +### Gradle plugin +- [_(prerelease fix)_ Fix "InvalidUserDataException: Cannot change hierarchy of dependency configuration" on Gradle sync](https://github.com/JetBrains/compose-multiplatform/pull/5076) + +## Dependencies +- Gradle Plugin `org.jetbrains.compose`, version `1.7.0-alpha02`. Based on Jetpack Compose libraries: + - [Runtime 1.7.0-beta05](https://developer.android.com/jetpack/androidx/releases/compose-runtime#1.7.0-beta05) + - [UI 1.7.0-beta05](https://developer.android.com/jetpack/androidx/releases/compose-ui#1.7.0-beta05) + - [Foundation 1.7.0-beta05](https://developer.android.com/jetpack/androidx/releases/compose-foundation#1.7.0-beta05) + - [Material 1.7.0-beta05](https://developer.android.com/jetpack/androidx/releases/compose-material#1.7.0-beta05) + - [Material3 1.3.0-beta03](https://developer.android.com/jetpack/androidx/releases/compose-material3#1.3.0-beta03) + +- Lifecycle libraries `org.jetbrains.androidx.lifecycle:lifecycle-*:2.8.0`. Based on [Jetpack Lifecycle 2.8.0](https://developer.android.com/jetpack/androidx/releases/lifecycle#2.8.0) +- Navigation libraries `org.jetbrains.androidx.navigation:navigation-*:2.8.0-alpha08`. Based on [Jetpack Navigation 2.8.0-beta03](https://developer.android.com/jetpack/androidx/releases/navigation#2.8.0-beta03) + +___ + # 1.7.0-alpha01 (July 2024) _Changes since 1.6.11_ diff --git a/README.md b/README.md index fffb8fd8e8..6206fbbdd1 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ For example, you can share UIs between iOS and Android or Windows and MacOS. > iOS support is in Beta. It is feature complete, and migration issues should be minimal. You may still encounter bugs, performance and developer experience issues, but not as much as in the Alpha stage. > We would appreciate your feedback on it in the public Slack channel [#compose-ios](https://kotlinlang.slack.com/archives/C0346LWVBJ4/p1678888063176359). -> If you face any issues, please report them on [GitHub](https://github.com/JetBrains/compose-multiplatform/issues). +> If you face any issues, please report them on [YouTrack](https://youtrack.jetbrains.com/newIssue?project=CMP). Compose Multiplatform shares most of its API with Jetpack Compose, the Android UI framework developed by Google. You can use the same APIs to build user interfaces for both Android and iOS. @@ -57,7 +57,7 @@ It has desktop extensions for menus, keyboard shortcuts, window manipulation, an > Web support is in Alpha. It may change incompatibly and require manual migration in the future. > We would appreciate your feedback on it in the public Slack channel [#compose-web](https://kotlinlang.slack.com/archives/C01F2HV7868/p1678887590205449). -> If you face any issues, please report them on [GitHub](https://github.com/JetBrains/compose-multiplatform/issues). +> If you face any issues, please report them on [YouTrack](https://youtrack.jetbrains.com/newIssue?project=CMP). You can experiment with sharing your mobile or desktop UIs with the web. Compose for Web is based on [Kotlin/Wasm](https://kotl.in/wasm), the newest target for Kotlin Multiplatform projects. It allows Kotlin developers to run their code in the browser with diff --git a/benchmarks/ios/README.md b/benchmarks/ios/README.md index c75a8dc4fa..d3e6cb10dd 100644 --- a/benchmarks/ios/README.md +++ b/benchmarks/ios/README.md @@ -1 +1 @@ -Collection of test compose multiplatfom applications used for evaluating performance of Compose for iOS. \ No newline at end of file +### Moved to [multiplatform](https://github.com/JetBrains/compose-multiplatform/tree/master/benchmarks/multiplatform) \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/.gitignore b/benchmarks/ios/animation-from-template/.gitignore deleted file mode 100644 index 6e5f30477c..0000000000 --- a/benchmarks/ios/animation-from-template/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea -.DS_Store -build/ -/captures -.externalNativeBuild -.cxx -iosApp/Podfile.lock -iosApp/Pods/* -iosApp/iosApp.xcworkspace/* -iosApp/iosApp.xcodeproj/* -!iosApp/iosApp.xcodeproj/project.pbxproj -shared/shared.podspec diff --git a/benchmarks/ios/animation-from-template/.run/desktopApp.run.xml b/benchmarks/ios/animation-from-template/.run/desktopApp.run.xml deleted file mode 100644 index 95395e11ee..0000000000 --- a/benchmarks/ios/animation-from-template/.run/desktopApp.run.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - true - true - false - - - \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/LICENSE.txt b/benchmarks/ios/animation-from-template/LICENSE.txt deleted file mode 100644 index 244380c242..0000000000 --- a/benchmarks/ios/animation-from-template/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2020-2021 JetBrains s.r.o. and and respective authors and developers. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/benchmarks/ios/animation-from-template/README.md b/benchmarks/ios/animation-from-template/README.md deleted file mode 100644 index 40718c389c..0000000000 --- a/benchmarks/ios/animation-from-template/README.md +++ /dev/null @@ -1 +0,0 @@ -Infinite animation based on: https://github.com/JetBrains/compose-multiplatform-template \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/androidApp/build.gradle.kts b/benchmarks/ios/animation-from-template/androidApp/build.gradle.kts deleted file mode 100644 index b86596b317..0000000000 --- a/benchmarks/ios/animation-from-template/androidApp/build.gradle.kts +++ /dev/null @@ -1,38 +0,0 @@ -plugins { - kotlin("multiplatform") - id("com.android.application") - id("org.jetbrains.compose") -} - -kotlin { - android() - sourceSets { - val androidMain by getting { - dependencies { - implementation(project(":shared")) - } - } - } -} - -android { - compileSdk = (findProperty("android.compileSdk") as String).toInt() - namespace = "com.myapplication" - - sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") - - defaultConfig { - applicationId = "com.myapplication.MyApplication" - minSdk = (findProperty("android.minSdk") as String).toInt() - targetSdk = (findProperty("android.targetSdk") as String).toInt() - versionCode = 1 - versionName = "1.0" - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - kotlin { - jvmToolchain(11) - } -} diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/AndroidManifest.xml b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/AndroidManifest.xml deleted file mode 100644 index bc7e861696..0000000000 --- a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/kotlin/com/myapplication/MainActivity.kt b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/kotlin/com/myapplication/MainActivity.kt deleted file mode 100644 index fd6e831ceb..0000000000 --- a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/kotlin/com/myapplication/MainActivity.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.myapplication - -import MainView -import android.os.Bundle -import androidx.activity.compose.setContent -import androidx.appcompat.app.AppCompatActivity - -class MainActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - setContent { - MainView() - } - } -} \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 2b068d1146..0000000000 --- a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/drawable/ic_launcher_background.xml b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 07d5da9cbf..0000000000 --- a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index eca70cfe52..0000000000 --- a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index eca70cfe52..0000000000 --- a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index a571e60098..0000000000 Binary files a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index 61da551c55..0000000000 Binary files a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c41dd28531..0000000000 Binary files a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index db5080a752..0000000000 Binary files a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 6dba46dab1..0000000000 Binary files a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index da31a871c8..0000000000 Binary files a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 15ac681720..0000000000 Binary files a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index b216f2d313..0000000000 Binary files a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index f25a419744..0000000000 Binary files a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index e96783ccce..0000000000 Binary files a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/values/strings.xml b/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/values/strings.xml deleted file mode 100644 index 592270bf53..0000000000 --- a/benchmarks/ios/animation-from-template/androidApp/src/androidMain/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - My application - \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/build.gradle.kts b/benchmarks/ios/animation-from-template/build.gradle.kts deleted file mode 100644 index b7e1d5d26a..0000000000 --- a/benchmarks/ios/animation-from-template/build.gradle.kts +++ /dev/null @@ -1,8 +0,0 @@ -plugins { - // this is necessary to avoid the plugins to be loaded multiple times - // in each subproject's classloader - kotlin("multiplatform").apply(false) - id("com.android.application").apply(false) - id("com.android.library").apply(false) - id("org.jetbrains.compose").apply(false) -} diff --git a/benchmarks/ios/animation-from-template/cleanup.sh b/benchmarks/ios/animation-from-template/cleanup.sh deleted file mode 100755 index 62f9391b86..0000000000 --- a/benchmarks/ios/animation-from-template/cleanup.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -rm -rf .idea -./gradlew clean -rm -rf .gradle -rm -rf build -rm -rf */build -rm -rf iosApp/iosApp.xcworkspace -rm -rf iosApp/Pods -rm -rf iosApp/iosApp.xcodeproj/project.xcworkspace -rm -rf iosApp/iosApp.xcodeproj/xcuserdata diff --git a/benchmarks/ios/animation-from-template/desktopApp/build.gradle.kts b/benchmarks/ios/animation-from-template/desktopApp/build.gradle.kts deleted file mode 100644 index 931f3467a2..0000000000 --- a/benchmarks/ios/animation-from-template/desktopApp/build.gradle.kts +++ /dev/null @@ -1,30 +0,0 @@ -import org.jetbrains.compose.desktop.application.dsl.TargetFormat - -plugins { - kotlin("multiplatform") - id("org.jetbrains.compose") -} - -kotlin { - jvm() - sourceSets { - val jvmMain by getting { - dependencies { - implementation(compose.desktop.currentOs) - implementation(project(":shared")) - } - } - } -} - -compose.desktop { - application { - mainClass = "MainKt" - - nativeDistributions { - targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) - packageName = "KotlinMultiplatformComposeDesktopApplication" - packageVersion = "1.0.0" - } - } -} diff --git a/benchmarks/ios/animation-from-template/desktopApp/src/jvmMain/kotlin/main.kt b/benchmarks/ios/animation-from-template/desktopApp/src/jvmMain/kotlin/main.kt deleted file mode 100644 index 5ffada98e1..0000000000 --- a/benchmarks/ios/animation-from-template/desktopApp/src/jvmMain/kotlin/main.kt +++ /dev/null @@ -1,8 +0,0 @@ -import androidx.compose.ui.window.Window -import androidx.compose.ui.window.application - -fun main() = application { - Window(onCloseRequest = ::exitApplication) { - MainView() - } -} \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/gradle.properties b/benchmarks/ios/animation-from-template/gradle.properties deleted file mode 100644 index 402848dbea..0000000000 --- a/benchmarks/ios/animation-from-template/gradle.properties +++ /dev/null @@ -1,24 +0,0 @@ -#Gradle -org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" - -#Kotlin -kotlin.code.style=official - -#MPP -kotlin.mpp.stability.nowarn=true -kotlin.mpp.enableCInteropCommonization=true -kotlin.mpp.androidSourceSetLayoutVersion=2 - -#Compose -org.jetbrains.compose.experimental.uikit.enabled=true - -#Android -android.useAndroidX=true -android.compileSdk=33 -android.targetSdk=33 -android.minSdk=24 - -#Versions -kotlin.version=1.8.20 -agp.version=7.4.2 -compose.version=1.4.0 \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/gradle/wrapper/gradle-wrapper.jar b/benchmarks/ios/animation-from-template/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f0..0000000000 Binary files a/benchmarks/ios/animation-from-template/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/benchmarks/ios/animation-from-template/gradlew b/benchmarks/ios/animation-from-template/gradlew deleted file mode 100755 index a69d9cb6c2..0000000000 --- a/benchmarks/ios/animation-from-template/gradlew +++ /dev/null @@ -1,240 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/benchmarks/ios/animation-from-template/iosApp/Configuration/Config.xcconfig b/benchmarks/ios/animation-from-template/iosApp/Configuration/Config.xcconfig deleted file mode 100644 index f391597827..0000000000 --- a/benchmarks/ios/animation-from-template/iosApp/Configuration/Config.xcconfig +++ /dev/null @@ -1,3 +0,0 @@ -TEAM_ID= -BUNDLE_ID=com.myapplication.MyApplication -APP_NAME=My application diff --git a/benchmarks/ios/animation-from-template/iosApp/Podfile b/benchmarks/ios/animation-from-template/iosApp/Podfile deleted file mode 100644 index aff9c517b2..0000000000 --- a/benchmarks/ios/animation-from-template/iosApp/Podfile +++ /dev/null @@ -1,5 +0,0 @@ -target 'iosApp' do - use_frameworks! - platform :ios, '14.1' - pod 'shared', :path => '../shared' -end \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/iosApp/iosApp.xcodeproj/project.pbxproj b/benchmarks/ios/animation-from-template/iosApp/iosApp.xcodeproj/project.pbxproj deleted file mode 100644 index df8fc264e7..0000000000 --- a/benchmarks/ios/animation-from-template/iosApp/iosApp.xcodeproj/project.pbxproj +++ /dev/null @@ -1,418 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 51; - objects = { - -/* Begin PBXBuildFile section */ - 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; }; - 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; }; - 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; }; - 7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; }; - CFDB58B53BB94DE262B13C24 /* Pods_iosApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B1049432C0C2B312090ABF6 /* Pods_iosApp.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = ""; }; - 4FF3202A603A284706412EDC /* Pods-iosApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.debug.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.debug.xcconfig"; sourceTree = ""; }; - 6B1049432C0C2B312090ABF6 /* Pods_iosApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_iosApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 7555FF7B242A565900829871 /* My application.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "My application.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 7555FF82242A565900829871 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; - 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - AB3632DC29227652001CCB65 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; }; - FF8CA3F5360CEAB49D74065F /* Pods-iosApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.release.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - F85CB1118929364A9C6EFABC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - CFDB58B53BB94DE262B13C24 /* Pods_iosApp.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 058557D7273AAEEB004C7B11 /* Preview Content */ = { - isa = PBXGroup; - children = ( - 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - 42799AB246E5F90AF97AA0EF /* Frameworks */ = { - isa = PBXGroup; - children = ( - 6B1049432C0C2B312090ABF6 /* Pods_iosApp.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 7555FF72242A565900829871 = { - isa = PBXGroup; - children = ( - AB1DB47929225F7C00F7AF9C /* Configuration */, - 7555FF7D242A565900829871 /* iosApp */, - 7555FF7C242A565900829871 /* Products */, - FEFF387C0A8D172AA4D59CAE /* Pods */, - 42799AB246E5F90AF97AA0EF /* Frameworks */, - ); - sourceTree = ""; - }; - 7555FF7C242A565900829871 /* Products */ = { - isa = PBXGroup; - children = ( - 7555FF7B242A565900829871 /* My application.app */, - ); - name = Products; - sourceTree = ""; - }; - 7555FF7D242A565900829871 /* iosApp */ = { - isa = PBXGroup; - children = ( - 058557BA273AAA24004C7B11 /* Assets.xcassets */, - 7555FF82242A565900829871 /* ContentView.swift */, - 7555FF8C242A565B00829871 /* Info.plist */, - 2152FB032600AC8F00CF470E /* iOSApp.swift */, - 058557D7273AAEEB004C7B11 /* Preview Content */, - ); - path = iosApp; - sourceTree = ""; - }; - AB1DB47929225F7C00F7AF9C /* Configuration */ = { - isa = PBXGroup; - children = ( - AB3632DC29227652001CCB65 /* Config.xcconfig */, - ); - path = Configuration; - sourceTree = ""; - }; - FEFF387C0A8D172AA4D59CAE /* Pods */ = { - isa = PBXGroup; - children = ( - 4FF3202A603A284706412EDC /* Pods-iosApp.debug.xcconfig */, - FF8CA3F5360CEAB49D74065F /* Pods-iosApp.release.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 7555FF7A242A565900829871 /* iosApp */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */; - buildPhases = ( - 98D614C51D2DA07C614CC46E /* [CP] Check Pods Manifest.lock */, - 7555FF77242A565900829871 /* Sources */, - 7555FF79242A565900829871 /* Resources */, - F85CB1118929364A9C6EFABC /* Frameworks */, - 2134C13603D0B299603D9F49 /* [CP] Copy Pods Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = iosApp; - productName = iosApp; - productReference = 7555FF7B242A565900829871 /* My application.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 7555FF73242A565900829871 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 1130; - LastUpgradeCheck = 1130; - ORGANIZATIONNAME = orgName; - TargetAttributes = { - 7555FF7A242A565900829871 = { - CreatedOnToolsVersion = 11.3.1; - }; - }; - }; - buildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 7555FF72242A565900829871; - productRefGroup = 7555FF7C242A565900829871 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 7555FF7A242A565900829871 /* iosApp */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 7555FF79242A565900829871 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */, - 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 2134C13603D0B299603D9F49 /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 98D614C51D2DA07C614CC46E /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-iosApp-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 7555FF77242A565900829871 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */, - 7555FF83242A565900829871 /* ContentView.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 7555FFA3242A565B00829871 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 7555FFA4242A565B00829871 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 7555FFA6242A565B00829871 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4FF3202A603A284706412EDC /* Pods-iosApp.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; - DEVELOPMENT_TEAM = "${TEAM_ID}"; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = iosApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; - PRODUCT_NAME = "${APP_NAME}"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 7555FFA7242A565B00829871 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = FF8CA3F5360CEAB49D74065F /* Pods-iosApp.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; - DEVELOPMENT_TEAM = "${TEAM_ID}"; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = iosApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; - PRODUCT_NAME = "${APP_NAME}"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7555FFA3242A565B00829871 /* Debug */, - 7555FFA4242A565B00829871 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7555FFA6242A565B00829871 /* Debug */, - 7555FFA7242A565B00829871 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 7555FF73242A565900829871 /* Project object */; -} diff --git a/benchmarks/ios/animation-from-template/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json b/benchmarks/ios/animation-from-template/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json deleted file mode 100644 index ee7e3ca03f..0000000000 --- a/benchmarks/ios/animation-from-template/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "colors" : [ - { - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/benchmarks/ios/animation-from-template/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 8edf56e7a9..0000000000 --- a/benchmarks/ios/animation-from-template/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "images" : [ - { - "filename" : "app-icon-1024.png", - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/benchmarks/ios/animation-from-template/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png b/benchmarks/ios/animation-from-template/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png deleted file mode 100644 index 53fc536fb9..0000000000 Binary files a/benchmarks/ios/animation-from-template/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png and /dev/null differ diff --git a/benchmarks/ios/animation-from-template/iosApp/iosApp/Assets.xcassets/Contents.json b/benchmarks/ios/animation-from-template/iosApp/iosApp/Assets.xcassets/Contents.json deleted file mode 100644 index 4aa7c5350b..0000000000 --- a/benchmarks/ios/animation-from-template/iosApp/iosApp/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/iosApp/iosApp/ContentView.swift b/benchmarks/ios/animation-from-template/iosApp/iosApp/ContentView.swift deleted file mode 100644 index f7f6457b31..0000000000 --- a/benchmarks/ios/animation-from-template/iosApp/iosApp/ContentView.swift +++ /dev/null @@ -1,21 +0,0 @@ -import UIKit -import SwiftUI -import shared - -struct ComposeView: UIViewControllerRepresentable { - func makeUIViewController(context: Context) -> UIViewController { - Main_iosKt.MainViewController() - } - - func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} -} - -struct ContentView: View { - var body: some View { - ComposeView() - .ignoresSafeArea(.keyboard) // Compose has own keyboard handler - } -} - - - diff --git a/benchmarks/ios/animation-from-template/iosApp/iosApp/Info.plist b/benchmarks/ios/animation-from-template/iosApp/iosApp/Info.plist deleted file mode 100644 index 9a269f5eaa..0000000000 --- a/benchmarks/ios/animation-from-template/iosApp/iosApp/Info.plist +++ /dev/null @@ -1,48 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - - UILaunchScreen - - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/benchmarks/ios/animation-from-template/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json b/benchmarks/ios/animation-from-template/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json deleted file mode 100644 index 4aa7c5350b..0000000000 --- a/benchmarks/ios/animation-from-template/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/iosApp/iosApp/iOSApp.swift b/benchmarks/ios/animation-from-template/iosApp/iosApp/iOSApp.swift deleted file mode 100644 index 0648e8602f..0000000000 --- a/benchmarks/ios/animation-from-template/iosApp/iosApp/iOSApp.swift +++ /dev/null @@ -1,10 +0,0 @@ -import SwiftUI - -@main -struct iOSApp: App { - var body: some Scene { - WindowGroup { - ContentView() - } - } -} \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/settings.gradle.kts b/benchmarks/ios/animation-from-template/settings.gradle.kts deleted file mode 100644 index 56cae17dbc..0000000000 --- a/benchmarks/ios/animation-from-template/settings.gradle.kts +++ /dev/null @@ -1,36 +0,0 @@ -rootProject.name = "MyApplication" - -include(":androidApp") -include(":shared") -include(":desktopApp") - -pluginManagement { - repositories { - gradlePluginPortal() - maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") - google() - } - - plugins { - val kotlinVersion = extra["kotlin.version"] as String - val agpVersion = extra["agp.version"] as String - val composeVersion = extra["compose.version"] as String - - kotlin("jvm").version(kotlinVersion) - kotlin("multiplatform").version(kotlinVersion) - kotlin("android").version(kotlinVersion) - - id("com.android.application").version(agpVersion) - id("com.android.library").version(agpVersion) - - id("org.jetbrains.compose").version(composeVersion) - } -} - -dependencyResolutionManagement { - repositories { - google() - mavenCentral() - maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") - } -} diff --git a/benchmarks/ios/animation-from-template/shared/build.gradle.kts b/benchmarks/ios/animation-from-template/shared/build.gradle.kts deleted file mode 100644 index 8e9b6dadf9..0000000000 --- a/benchmarks/ios/animation-from-template/shared/build.gradle.kts +++ /dev/null @@ -1,83 +0,0 @@ -plugins { - kotlin("multiplatform") - kotlin("native.cocoapods") - id("com.android.library") - id("org.jetbrains.compose") -} - -kotlin { - android() - - jvm("desktop") - - iosX64() - iosArm64() - iosSimulatorArm64() - - cocoapods { - version = "1.0.0" - summary = "Some description for the Shared Module" - homepage = "Link to the Shared Module homepage" - ios.deploymentTarget = "14.1" - podfile = project.file("../iosApp/Podfile") - framework { - baseName = "shared" - isStatic = true - } - extraSpecAttributes["resources"] = "['src/commonMain/resources/**', 'src/iosMain/resources/**']" - } - - sourceSets { - val commonMain by getting { - dependencies { - implementation(compose.runtime) - implementation(compose.foundation) - implementation(compose.material) - @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) - implementation(compose.components.resources) - } - } - val androidMain by getting { - dependencies { - api("androidx.activity:activity-compose:1.6.1") - api("androidx.appcompat:appcompat:1.6.1") - api("androidx.core:core-ktx:1.9.0") - } - } - val iosX64Main by getting - val iosArm64Main by getting - val iosSimulatorArm64Main by getting - val iosMain by creating { - dependsOn(commonMain) - iosX64Main.dependsOn(this) - iosArm64Main.dependsOn(this) - iosSimulatorArm64Main.dependsOn(this) - } - val desktopMain by getting { - dependencies { - implementation(compose.desktop.common) - } - } - } -} - -android { - compileSdk = (findProperty("android.compileSdk") as String).toInt() - namespace = "com.myapplication.common" - - sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") - sourceSets["main"].res.srcDirs("src/androidMain/res") - sourceSets["main"].resources.srcDirs("src/commonMain/resources") - - defaultConfig { - minSdk = (findProperty("android.minSdk") as String).toInt() - targetSdk = (findProperty("android.targetSdk") as String).toInt() - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - kotlin { - jvmToolchain(11) - } -} diff --git a/benchmarks/ios/animation-from-template/shared/src/androidMain/AndroidManifest.xml b/benchmarks/ios/animation-from-template/shared/src/androidMain/AndroidManifest.xml deleted file mode 100644 index 568741e54f..0000000000 --- a/benchmarks/ios/animation-from-template/shared/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/benchmarks/ios/animation-from-template/shared/src/androidMain/kotlin/main.android.kt b/benchmarks/ios/animation-from-template/shared/src/androidMain/kotlin/main.android.kt deleted file mode 100644 index 4a1d2a6feb..0000000000 --- a/benchmarks/ios/animation-from-template/shared/src/androidMain/kotlin/main.android.kt +++ /dev/null @@ -1,3 +0,0 @@ -import androidx.compose.runtime.Composable - -@Composable fun MainView() = App() diff --git a/benchmarks/ios/animation-from-template/shared/src/desktopMain/kotlin/main.desktop.kt b/benchmarks/ios/animation-from-template/shared/src/desktopMain/kotlin/main.desktop.kt deleted file mode 100644 index 190ff810fd..0000000000 --- a/benchmarks/ios/animation-from-template/shared/src/desktopMain/kotlin/main.desktop.kt +++ /dev/null @@ -1,4 +0,0 @@ -import androidx.compose.desktop.ui.tooling.preview.Preview -import androidx.compose.runtime.Composable - -@Composable fun MainView() = App() diff --git a/benchmarks/ios/animation-from-template/shared/src/iosMain/kotlin/main.ios.kt b/benchmarks/ios/animation-from-template/shared/src/iosMain/kotlin/main.ios.kt deleted file mode 100644 index fa143d45ce..0000000000 --- a/benchmarks/ios/animation-from-template/shared/src/iosMain/kotlin/main.ios.kt +++ /dev/null @@ -1,3 +0,0 @@ -import androidx.compose.ui.window.ComposeUIViewController - -fun MainViewController() = ComposeUIViewController { App() } \ No newline at end of file diff --git a/benchmarks/ios/jvm-vs-kotlin-native/README.md b/benchmarks/ios/jvm-vs-kotlin-native/README.md index 2d3a57fa6a..d3e6cb10dd 100644 --- a/benchmarks/ios/jvm-vs-kotlin-native/README.md +++ b/benchmarks/ios/jvm-vs-kotlin-native/README.md @@ -1,8 +1 @@ -# Compose benchmarks for JVM vs Kotlin Native comparison - -## Run Desktop -- `./gradlew :run` - -## Run native on MacOS - - `./gradlew runReleaseExecutableMacosArm64` (Works on Arm64 processors) - - `./gradlew runReleaseExecutableMacosX64` (Works on Intel processors) +### Moved to [multiplatform](https://github.com/JetBrains/compose-multiplatform/tree/master/benchmarks/multiplatform) \ No newline at end of file diff --git a/benchmarks/ios/jvm-vs-kotlin-native/gradle.properties b/benchmarks/ios/jvm-vs-kotlin-native/gradle.properties deleted file mode 100644 index ea3799cf6b..0000000000 --- a/benchmarks/ios/jvm-vs-kotlin-native/gradle.properties +++ /dev/null @@ -1,16 +0,0 @@ -compose.version=1.4.1 -kotlin.version=1.8.20 -agp.version=7.0.4 -org.gradle.jvmargs=-Xmx3g -kotlin.code.style=official -kotlin.native.useEmbeddableCompilerJar=true -kotlin.native.enableDependencyPropagation=false -kotlin.mpp.enableGranularSourceSetsMetadata=true -# Enable kotlin/native experimental memory model -kotlin.native.binary.memoryModel=experimental -compose.desktop.verbose=true -android.useAndroidX=true -kotlin.js.webpack.major.version=4 -org.jetbrains.compose.experimental.jscanvas.enabled=true -org.jetbrains.compose.experimental.macos.enabled=true -org.jetbrains.compose.experimental.uikit.enabled=true diff --git a/benchmarks/ios/jvm-vs-kotlin-native/gradle/wrapper/gradle-wrapper.properties b/benchmarks/ios/jvm-vs-kotlin-native/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index ae04661ee7..0000000000 --- a/benchmarks/ios/jvm-vs-kotlin-native/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/benchmarks/ios/jvm-vs-kotlin-native/gradlew.bat b/benchmarks/ios/jvm-vs-kotlin-native/gradlew.bat deleted file mode 100644 index f127cfd49d..0000000000 --- a/benchmarks/ios/jvm-vs-kotlin-native/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/Benchmarks.kt b/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/Benchmarks.kt deleted file mode 100644 index 00414f67a8..0000000000 --- a/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/Benchmarks.kt +++ /dev/null @@ -1,14 +0,0 @@ -import androidx.compose.runtime.Composable -import benchmarks.animation.AnimatedVisibility -import benchmarks.lazygrid.LazyGrid -import benchmarks.visualeffects.NYContent - -fun runBenchmark(name: String, frameCount: Int, content: @Composable () -> Unit) { - println("$name: " + measureComposable(frameCount, content)) -} - -fun runBenchmarks() { - runBenchmark("AnimatedVisibility", 1000000) { AnimatedVisibility() } - runBenchmark("LazyGrid",2000) { LazyGrid() } - runBenchmark("VisualEffects",1000) { NYContent() } -} \ No newline at end of file diff --git a/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/MeasureComposable.kt b/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/MeasureComposable.kt deleted file mode 100644 index 6b11a8f842..0000000000 --- a/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/MeasureComposable.kt +++ /dev/null @@ -1,33 +0,0 @@ -import androidx.compose.runtime.Composable -import androidx.compose.ui.ComposeScene -import androidx.compose.ui.unit.Constraints -import kotlin.time.Duration -import kotlin.time.ExperimentalTime - -const val width = 640 -const val height = 480 - -const val nanosPerSecond = 1E9.toLong() -const val nanosPerFrame = (0.16 * nanosPerSecond).toLong() - -@OptIn(ExperimentalTime::class) -fun measureComposable( - frameCount: Int = 1000, - content: @Composable () -> Unit -): Duration { - val scene = ComposeScene() - try { - scene.setContent(content) - scene.constraints = Constraints.fixed(width, height) - val surface = org.jetbrains.skia.Surface.makeNull(width, height) - return kotlin.time.measureTime { - var nanoTime = 0L - repeat(frameCount) { - scene.render(surface.canvas, nanoTime) - nanoTime += nanosPerFrame - } - } - } finally { - scene.close() - } -} diff --git a/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/benchmarks/visualeffects/HappyNY.kt b/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/benchmarks/visualeffects/HappyNY.kt deleted file mode 100644 index 0d13bb4ecf..0000000000 --- a/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/benchmarks/visualeffects/HappyNY.kt +++ /dev/null @@ -1,323 +0,0 @@ -package benchmarks.visualeffects - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Surface -import androidx.compose.runtime.* -import androidx.compose.runtime.snapshots.SnapshotStateList -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.* -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import height -import width - -import kotlin.math.* -import kotlin.random.Random - -const val snowCount = 80 -const val starCount = 60 -const val rocketPartsCount = 30 - -data class SnowFlake( - var x: Dp, - var y: Dp, - val scale: Float, - var v: Double, - var alpha: Float, - var angle: Float, - var rotate: Int, - var phase: Double -) - -data class Star(val x: Dp, val y: Dp, val color: Color, val size: Dp) - -val random = Random(123) - -fun random(): Float = random.nextFloat() - -class DoubleRocket(val particle: Particle) { - private val STATE_ROCKET = 0 - private val STATE_SMALL_ROCKETS = 1 - var state = STATE_ROCKET - var rockets: Array = emptyArray() - private fun checkState(time: Long) { - if (particle.vy > -3.0 && state == STATE_ROCKET) { - explode(time) - } - if (state == STATE_SMALL_ROCKETS) { - var done = true - rockets.forEach { - if (!it.exploded) { - it.checkExplode(time) - } - if (!it.checkDone()) { - done = false - } - } - if (done) { - reset() - } - } - } - - private fun reset() { - state = STATE_ROCKET - particle.x = 0.0 - particle.y = 1000.0 - particle.vx = 2.1 - particle.vy = -12.5 - } - - private fun explode(time: Long) { - val colors = arrayOf(Color(0xff, 0, 0), Color(192, 255, 192), Color(192, 212, 255)) - rockets = Array(7) { - val v = 1.2f + 1.0 * random() - val angle = 2 * PI * random() - Rocket( - Particle( - particle.x, - particle.y, - v * sin(angle) + particle.vx, - v * cos(angle) + particle.vy - 0.5f, - colors[it % colors.size] - ), colors[it % colors.size], time - ) - } - state = STATE_SMALL_ROCKETS - } - - fun move(time: Long, prevTime: Long) { - if (rocket.state == rocket.STATE_ROCKET) { - rocket.particle.move(time, prevTime) - rocket.particle.gravity(time, prevTime) - } else { - rocket.rockets.forEach { - it.move(time, prevTime) - } - } - rocket.checkState(time) - } - - @Composable - fun draw() { - if (state == rocket.STATE_ROCKET) { - particle.draw() - } else { - rockets.forEach { - it.draw() - } - } - } - -} - -class Rocket(val particle: Particle, val color: Color, val startTime: Long = 0) { - var exploded = false - var parts: Array = emptyArray() - - fun checkExplode(time: Long) { - if (time - startTime > 1200000000) { - explode() - } - } - - private fun explode() { - parts = Array(rocketPartsCount) { - val v = 0.5f + 1.5 * random() - val angle = 2 * PI * random() - Particle(particle.x, particle.y, v * sin(angle) + particle.vx, v * cos(angle) + particle.vy, color, 1) - } - exploded = true - } - - fun checkDone(): Boolean { - if (!exploded) return false - parts.forEach { - if (it.y < 800) return false - } - return true - } - - fun move(time: Long, prevTime: Long) { - if (!exploded) { - particle.move(time, prevTime) - particle.gravity(time, prevTime) - checkExplode(time) - } else { - parts.forEach { - it.move(time, prevTime) - it.gravity(time, prevTime) - } - } - } - - @Composable - fun draw() { - if (!exploded) { - particle.draw() - } else { - parts.forEach { - it.draw() - } - } - } -} - -class Particle(var x: Double, var y: Double, var vx: Double, var vy: Double, val color: Color, val type: Int = 0) { - fun move(time: Long, prevTime: Long) { - x = (x + vx * (time - prevTime) / 30000000) - y = (y + vy * (time - prevTime) / 30000000) - } - - fun gravity(time: Long, prevTime: Long) { - vy = vy + 1.0f * (time - prevTime) / 300000000 - } - - @Composable - fun draw() { - val alphaFactor = if (type == 0) 1.0f else 1 / (1 + abs(vy / 5)).toFloat() - Box(Modifier.size(5.dp).offset(x.dp, y.dp).alpha(alphaFactor).clip(CircleShape).background(color)) - for (i in 1..5) { - Box( - Modifier.size(4.dp).offset((x - vx / 2 * i).dp, (y - vy / 2 * i).dp) - .alpha(alphaFactor * (1 - 0.18f * i)).clip(CircleShape).background(color) - ) - } - } -} - -val rocket = DoubleRocket(Particle(0.0, 1000.0, 2.1, -12.5, Color.White)) - -fun prepareStarsAndSnowFlakes(stars: SnapshotStateList, snowFlakes: SnapshotStateList) { - for (i in 0..snowCount) { - snowFlakes.add( - SnowFlake( - (50 + (width - 50) * random()).dp, - (height * random()).dp, - 0.1f + 0.2f * random(), - 1.5 + 3 * random(), - (0.4f + 0.4 * random()).toFloat(), - 60 * random(), - Random.nextInt(1, 5) - 3, - random() * 2 * PI - ) - ) - } - val colors = arrayOf(Color.Red, Color.Yellow, Color.Green, Color.Yellow, Color.Cyan, Color.Magenta, Color.White) - for (i in 0..starCount) { - stars.add( - Star( - (width * random()).dp, - (height * random()).dp, - colors[Random.nextInt(colors.size)], - (3 + 5 * random()).dp - ) - ) - } -} - -@Composable -fun NYContent() { - var time by remember { mutableStateOf(0L) } - val startTime = remember { 0L } - var prevTime by remember { mutableStateOf(0L) } - val snowFlakes = remember { mutableStateListOf() } - val stars = remember { mutableStateListOf() } - var flickering2 by remember { mutableStateOf(true) } - remember { prepareStarsAndSnowFlakes(stars, snowFlakes) } - - Surface( - modifier = Modifier.fillMaxSize().padding(5.dp).shadow(3.dp, RoundedCornerShape(20.dp)), - color = Color.Black, - shape = RoundedCornerShape(20.dp) - ) { - - LaunchedEffect(Unit) { - while (true) { - withFrameNanos { - prevTime = time - time = it - } - } - } - - if (flickering2) { - if (time - startTime > 15500000000) { //note, that startTime has been updated above - flickering2 = false - } - } - - rocket.move(time, prevTime) - - Box(Modifier.fillMaxSize()) { - - snow(time, prevTime, snowFlakes, startTime) - - starrySky(stars) - - rocket.draw() - - } - } -} - - -@Composable -fun starrySky(stars: SnapshotStateList) { - stars.forEach { - star(it.x, it.y, it.color, size = it.size) - } -} - -@Composable -fun star(x: Dp, y: Dp, color: Color = Color.White, size: Dp) { - Box(Modifier.offset(x, y).scale(1.0f, 0.2f).rotate(45f).size(size).background(color)) - Box(Modifier.offset(x, y).scale(0.2f, 1.0f).rotate(45f).size(size).background(color)) -} - -@Composable -fun snow(time: Long, prevTime: Long, snowFlakes: SnapshotStateList, startTime: Long) { - val deltaAngle = (time - startTime) / 100000000 - with(LocalDensity.current) { - snowFlakes.forEach { - var y = it.y + ((it.v * (time - prevTime)) / 300000000).dp - if (y > (height + 20).dp) { - y = -20.dp - } - it.y = y - val x = it.x + (15 * sin(time.toDouble() / 3000000000 + it.phase)).dp - snowFlake(Modifier.offset(x, y).scale(it.scale).rotate(it.angle + deltaAngle * it.rotate), it.alpha) - } - } -} - -@Composable -fun snowFlake(modifier: Modifier, alpha: Float = 0.8f) { - Box(modifier) { - snowFlakeInt(0, 0f, 30.dp, 0.dp, alpha) - snowFlakeInt(0, 60f, 15.dp, 25.dp, alpha) - snowFlakeInt(0, 120f, -15.dp, 25.dp, alpha) - snowFlakeInt(0, 180f, -30.dp, 0.dp, alpha) - snowFlakeInt(0, 240f, -15.dp, -25.dp, alpha) - snowFlakeInt(0, 300f, 15.dp, -25.dp, alpha) - } - -} - -@Composable -fun snowFlakeInt(level: Int, angle: Float, shiftX: Dp, shiftY: Dp, alpha: Float) { - if (level > 3) return - Box( - Modifier.offset(shiftX, shiftY).rotate(angle).width(100.dp).height(10.dp).scale(0.6f).alpha(1f) - .background(Color.White.copy(alpha = alpha)) - ) { - snowFlakeInt(level + 1, 30f, 12.dp, 20.dp, alpha * 0.8f) - snowFlakeInt(level + 1, -30f, 12.dp, -20.dp, alpha * 0.8f) - } -} - diff --git a/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/resources/compose-multiplatform.xml b/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/resources/compose-multiplatform.xml deleted file mode 100644 index d7bf7955f4..0000000000 --- a/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/resources/compose-multiplatform.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - diff --git a/benchmarks/ios/jvm-vs-kotlin-native/src/desktopMain/kotlin/main.desktop.kt b/benchmarks/ios/jvm-vs-kotlin-native/src/desktopMain/kotlin/main.desktop.kt deleted file mode 100644 index 6d1367a1a8..0000000000 --- a/benchmarks/ios/jvm-vs-kotlin-native/src/desktopMain/kotlin/main.desktop.kt +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. - * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. - */ - -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.runBlocking - -fun main() = runBlocking(Dispatchers.Main) { runBenchmarks() } diff --git a/benchmarks/ios/jvm-vs-kotlin-native/src/macosMain/kotlin/main.macos.kt b/benchmarks/ios/jvm-vs-kotlin-native/src/macosMain/kotlin/main.macos.kt deleted file mode 100644 index a78976e73a..0000000000 --- a/benchmarks/ios/jvm-vs-kotlin-native/src/macosMain/kotlin/main.macos.kt +++ /dev/null @@ -1,6 +0,0 @@ -/* - * Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. - * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. - */ - -fun main() = runBenchmarks() diff --git a/benchmarks/ios/scroll-lazy-grid/.gitignore b/benchmarks/ios/scroll-lazy-grid/.gitignore deleted file mode 100644 index 6e5f30477c..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea -.DS_Store -build/ -/captures -.externalNativeBuild -.cxx -iosApp/Podfile.lock -iosApp/Pods/* -iosApp/iosApp.xcworkspace/* -iosApp/iosApp.xcodeproj/* -!iosApp/iosApp.xcodeproj/project.pbxproj -shared/shared.podspec diff --git a/benchmarks/ios/scroll-lazy-grid/.run/desktopApp.run.xml b/benchmarks/ios/scroll-lazy-grid/.run/desktopApp.run.xml deleted file mode 100644 index 95395e11ee..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/.run/desktopApp.run.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - true - true - false - - - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/LICENSE.txt b/benchmarks/ios/scroll-lazy-grid/LICENSE.txt deleted file mode 100644 index 244380c242..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2020-2021 JetBrains s.r.o. and and respective authors and developers. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/benchmarks/ios/scroll-lazy-grid/README.md b/benchmarks/ios/scroll-lazy-grid/README.md deleted file mode 100644 index beb03aa03c..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/README.md +++ /dev/null @@ -1 +0,0 @@ -A benchmark app extracted from https://github.com/androidx/androidx/blob/androidx-main/compose/integration-tests/macrobenchmark-target/src/main/java/androidx/compose/integration/macrobenchmark/target/LazyVerticalGridActivity.kt diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/build.gradle.kts b/benchmarks/ios/scroll-lazy-grid/androidApp/build.gradle.kts deleted file mode 100644 index b86596b317..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/androidApp/build.gradle.kts +++ /dev/null @@ -1,38 +0,0 @@ -plugins { - kotlin("multiplatform") - id("com.android.application") - id("org.jetbrains.compose") -} - -kotlin { - android() - sourceSets { - val androidMain by getting { - dependencies { - implementation(project(":shared")) - } - } - } -} - -android { - compileSdk = (findProperty("android.compileSdk") as String).toInt() - namespace = "com.myapplication" - - sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") - - defaultConfig { - applicationId = "com.myapplication.MyApplication" - minSdk = (findProperty("android.minSdk") as String).toInt() - targetSdk = (findProperty("android.targetSdk") as String).toInt() - versionCode = 1 - versionName = "1.0" - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - kotlin { - jvmToolchain(11) - } -} diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/AndroidManifest.xml b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/AndroidManifest.xml deleted file mode 100644 index bc7e861696..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/kotlin/com/myapplication/MainActivity.kt b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/kotlin/com/myapplication/MainActivity.kt deleted file mode 100644 index fd6e831ceb..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/kotlin/com/myapplication/MainActivity.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.myapplication - -import MainView -import android.os.Bundle -import androidx.activity.compose.setContent -import androidx.appcompat.app.AppCompatActivity - -class MainActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - setContent { - MainView() - } - } -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 2b068d1146..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/drawable/ic_launcher_background.xml b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 07d5da9cbf..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index eca70cfe52..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index eca70cfe52..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index a571e60098..0000000000 Binary files a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index 61da551c55..0000000000 Binary files a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c41dd28531..0000000000 Binary files a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index db5080a752..0000000000 Binary files a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 6dba46dab1..0000000000 Binary files a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index da31a871c8..0000000000 Binary files a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 15ac681720..0000000000 Binary files a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index b216f2d313..0000000000 Binary files a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index f25a419744..0000000000 Binary files a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index e96783ccce..0000000000 Binary files a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/values/strings.xml b/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/values/strings.xml deleted file mode 100644 index 592270bf53..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/androidApp/src/androidMain/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - My application - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/build.gradle.kts b/benchmarks/ios/scroll-lazy-grid/build.gradle.kts deleted file mode 100644 index b7e1d5d26a..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/build.gradle.kts +++ /dev/null @@ -1,8 +0,0 @@ -plugins { - // this is necessary to avoid the plugins to be loaded multiple times - // in each subproject's classloader - kotlin("multiplatform").apply(false) - id("com.android.application").apply(false) - id("com.android.library").apply(false) - id("org.jetbrains.compose").apply(false) -} diff --git a/benchmarks/ios/scroll-lazy-grid/cleanup.sh b/benchmarks/ios/scroll-lazy-grid/cleanup.sh deleted file mode 100755 index 62f9391b86..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/cleanup.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -rm -rf .idea -./gradlew clean -rm -rf .gradle -rm -rf build -rm -rf */build -rm -rf iosApp/iosApp.xcworkspace -rm -rf iosApp/Pods -rm -rf iosApp/iosApp.xcodeproj/project.xcworkspace -rm -rf iosApp/iosApp.xcodeproj/xcuserdata diff --git a/benchmarks/ios/scroll-lazy-grid/desktopApp/build.gradle.kts b/benchmarks/ios/scroll-lazy-grid/desktopApp/build.gradle.kts deleted file mode 100644 index 931f3467a2..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/desktopApp/build.gradle.kts +++ /dev/null @@ -1,30 +0,0 @@ -import org.jetbrains.compose.desktop.application.dsl.TargetFormat - -plugins { - kotlin("multiplatform") - id("org.jetbrains.compose") -} - -kotlin { - jvm() - sourceSets { - val jvmMain by getting { - dependencies { - implementation(compose.desktop.currentOs) - implementation(project(":shared")) - } - } - } -} - -compose.desktop { - application { - mainClass = "MainKt" - - nativeDistributions { - targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) - packageName = "KotlinMultiplatformComposeDesktopApplication" - packageVersion = "1.0.0" - } - } -} diff --git a/benchmarks/ios/scroll-lazy-grid/desktopApp/src/jvmMain/kotlin/main.kt b/benchmarks/ios/scroll-lazy-grid/desktopApp/src/jvmMain/kotlin/main.kt deleted file mode 100644 index 5ffada98e1..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/desktopApp/src/jvmMain/kotlin/main.kt +++ /dev/null @@ -1,8 +0,0 @@ -import androidx.compose.ui.window.Window -import androidx.compose.ui.window.application - -fun main() = application { - Window(onCloseRequest = ::exitApplication) { - MainView() - } -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/gradle.properties b/benchmarks/ios/scroll-lazy-grid/gradle.properties deleted file mode 100644 index 402848dbea..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/gradle.properties +++ /dev/null @@ -1,24 +0,0 @@ -#Gradle -org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" - -#Kotlin -kotlin.code.style=official - -#MPP -kotlin.mpp.stability.nowarn=true -kotlin.mpp.enableCInteropCommonization=true -kotlin.mpp.androidSourceSetLayoutVersion=2 - -#Compose -org.jetbrains.compose.experimental.uikit.enabled=true - -#Android -android.useAndroidX=true -android.compileSdk=33 -android.targetSdk=33 -android.minSdk=24 - -#Versions -kotlin.version=1.8.20 -agp.version=7.4.2 -compose.version=1.4.0 \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/gradle/wrapper/gradle-wrapper.jar b/benchmarks/ios/scroll-lazy-grid/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f0..0000000000 Binary files a/benchmarks/ios/scroll-lazy-grid/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-grid/gradle/wrapper/gradle-wrapper.properties b/benchmarks/ios/scroll-lazy-grid/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e1bef7e873..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/benchmarks/ios/scroll-lazy-grid/gradlew b/benchmarks/ios/scroll-lazy-grid/gradlew deleted file mode 100755 index a69d9cb6c2..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/gradlew +++ /dev/null @@ -1,240 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/benchmarks/ios/scroll-lazy-grid/gradlew.bat b/benchmarks/ios/scroll-lazy-grid/gradlew.bat deleted file mode 100644 index f127cfd49d..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/benchmarks/ios/scroll-lazy-grid/iosApp/Configuration/Config.xcconfig b/benchmarks/ios/scroll-lazy-grid/iosApp/Configuration/Config.xcconfig deleted file mode 100644 index f391597827..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/iosApp/Configuration/Config.xcconfig +++ /dev/null @@ -1,3 +0,0 @@ -TEAM_ID= -BUNDLE_ID=com.myapplication.MyApplication -APP_NAME=My application diff --git a/benchmarks/ios/scroll-lazy-grid/iosApp/Podfile b/benchmarks/ios/scroll-lazy-grid/iosApp/Podfile deleted file mode 100644 index aff9c517b2..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/iosApp/Podfile +++ /dev/null @@ -1,5 +0,0 @@ -target 'iosApp' do - use_frameworks! - platform :ios, '14.1' - pod 'shared', :path => '../shared' -end \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp.xcodeproj/project.pbxproj b/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp.xcodeproj/project.pbxproj deleted file mode 100644 index c888c0443c..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp.xcodeproj/project.pbxproj +++ /dev/null @@ -1,400 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 51; - objects = { - -/* Begin PBXBuildFile section */ - 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; }; - 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; }; - 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; }; - 7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; }; - CFDB58B53BB94DE262B13C24 /* Pods_iosApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B1049432C0C2B312090ABF6 /* Pods_iosApp.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = ""; }; - 4FF3202A603A284706412EDC /* Pods-iosApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.debug.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.debug.xcconfig"; sourceTree = ""; }; - 6B1049432C0C2B312090ABF6 /* Pods_iosApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_iosApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 7555FF7B242A565900829871 /* My application.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "My application.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 7555FF82242A565900829871 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; - 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - AB3632DC29227652001CCB65 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; }; - FF8CA3F5360CEAB49D74065F /* Pods-iosApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.release.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - F85CB1118929364A9C6EFABC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - CFDB58B53BB94DE262B13C24 /* Pods_iosApp.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 058557D7273AAEEB004C7B11 /* Preview Content */ = { - isa = PBXGroup; - children = ( - 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - 42799AB246E5F90AF97AA0EF /* Frameworks */ = { - isa = PBXGroup; - children = ( - 6B1049432C0C2B312090ABF6 /* Pods_iosApp.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 7555FF72242A565900829871 = { - isa = PBXGroup; - children = ( - AB1DB47929225F7C00F7AF9C /* Configuration */, - 7555FF7D242A565900829871 /* iosApp */, - 7555FF7C242A565900829871 /* Products */, - FEFF387C0A8D172AA4D59CAE /* Pods */, - 42799AB246E5F90AF97AA0EF /* Frameworks */, - ); - sourceTree = ""; - }; - 7555FF7C242A565900829871 /* Products */ = { - isa = PBXGroup; - children = ( - 7555FF7B242A565900829871 /* My application.app */, - ); - name = Products; - sourceTree = ""; - }; - 7555FF7D242A565900829871 /* iosApp */ = { - isa = PBXGroup; - children = ( - 058557BA273AAA24004C7B11 /* Assets.xcassets */, - 7555FF82242A565900829871 /* ContentView.swift */, - 7555FF8C242A565B00829871 /* Info.plist */, - 2152FB032600AC8F00CF470E /* iOSApp.swift */, - 058557D7273AAEEB004C7B11 /* Preview Content */, - ); - path = iosApp; - sourceTree = ""; - }; - AB1DB47929225F7C00F7AF9C /* Configuration */ = { - isa = PBXGroup; - children = ( - AB3632DC29227652001CCB65 /* Config.xcconfig */, - ); - path = Configuration; - sourceTree = ""; - }; - FEFF387C0A8D172AA4D59CAE /* Pods */ = { - isa = PBXGroup; - children = ( - 4FF3202A603A284706412EDC /* Pods-iosApp.debug.xcconfig */, - FF8CA3F5360CEAB49D74065F /* Pods-iosApp.release.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 7555FF7A242A565900829871 /* iosApp */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */; - buildPhases = ( - 98D614C51D2DA07C614CC46E /* [CP] Check Pods Manifest.lock */, - 7555FF77242A565900829871 /* Sources */, - 7555FF79242A565900829871 /* Resources */, - F85CB1118929364A9C6EFABC /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = iosApp; - productName = iosApp; - productReference = 7555FF7B242A565900829871 /* My application.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 7555FF73242A565900829871 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 1130; - LastUpgradeCheck = 1130; - ORGANIZATIONNAME = orgName; - TargetAttributes = { - 7555FF7A242A565900829871 = { - CreatedOnToolsVersion = 11.3.1; - }; - }; - }; - buildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 7555FF72242A565900829871; - productRefGroup = 7555FF7C242A565900829871 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 7555FF7A242A565900829871 /* iosApp */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 7555FF79242A565900829871 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */, - 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 98D614C51D2DA07C614CC46E /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-iosApp-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 7555FF77242A565900829871 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */, - 7555FF83242A565900829871 /* ContentView.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 7555FFA3242A565B00829871 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 7555FFA4242A565B00829871 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 7555FFA6242A565B00829871 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4FF3202A603A284706412EDC /* Pods-iosApp.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; - DEVELOPMENT_TEAM = "${TEAM_ID}"; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = iosApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; - PRODUCT_NAME = "${APP_NAME}"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 7555FFA7242A565B00829871 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = FF8CA3F5360CEAB49D74065F /* Pods-iosApp.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; - DEVELOPMENT_TEAM = "${TEAM_ID}"; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = iosApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; - PRODUCT_NAME = "${APP_NAME}"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7555FFA3242A565B00829871 /* Debug */, - 7555FFA4242A565B00829871 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7555FFA6242A565B00829871 /* Debug */, - 7555FFA7242A565B00829871 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 7555FF73242A565900829871 /* Project object */; -} diff --git a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json b/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json deleted file mode 100644 index ee7e3ca03f..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "colors" : [ - { - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 8edf56e7a9..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "images" : [ - { - "filename" : "app-icon-1024.png", - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png b/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png deleted file mode 100644 index 53fc536fb9..0000000000 Binary files a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Assets.xcassets/Contents.json b/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Assets.xcassets/Contents.json deleted file mode 100644 index 4aa7c5350b..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/ContentView.swift b/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/ContentView.swift deleted file mode 100644 index f7f6457b31..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/ContentView.swift +++ /dev/null @@ -1,21 +0,0 @@ -import UIKit -import SwiftUI -import shared - -struct ComposeView: UIViewControllerRepresentable { - func makeUIViewController(context: Context) -> UIViewController { - Main_iosKt.MainViewController() - } - - func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} -} - -struct ContentView: View { - var body: some View { - ComposeView() - .ignoresSafeArea(.keyboard) // Compose has own keyboard handler - } -} - - - diff --git a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Info.plist b/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Info.plist deleted file mode 100644 index 9a269f5eaa..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Info.plist +++ /dev/null @@ -1,48 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - - UILaunchScreen - - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json b/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json deleted file mode 100644 index 4aa7c5350b..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/iOSApp.swift b/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/iOSApp.swift deleted file mode 100644 index 0648e8602f..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/iosApp/iosApp/iOSApp.swift +++ /dev/null @@ -1,10 +0,0 @@ -import SwiftUI - -@main -struct iOSApp: App { - var body: some Scene { - WindowGroup { - ContentView() - } - } -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/settings.gradle.kts b/benchmarks/ios/scroll-lazy-grid/settings.gradle.kts deleted file mode 100644 index 56cae17dbc..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/settings.gradle.kts +++ /dev/null @@ -1,36 +0,0 @@ -rootProject.name = "MyApplication" - -include(":androidApp") -include(":shared") -include(":desktopApp") - -pluginManagement { - repositories { - gradlePluginPortal() - maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") - google() - } - - plugins { - val kotlinVersion = extra["kotlin.version"] as String - val agpVersion = extra["agp.version"] as String - val composeVersion = extra["compose.version"] as String - - kotlin("jvm").version(kotlinVersion) - kotlin("multiplatform").version(kotlinVersion) - kotlin("android").version(kotlinVersion) - - id("com.android.application").version(agpVersion) - id("com.android.library").version(agpVersion) - - id("org.jetbrains.compose").version(composeVersion) - } -} - -dependencyResolutionManagement { - repositories { - google() - mavenCentral() - maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") - } -} diff --git a/benchmarks/ios/scroll-lazy-grid/shared/build.gradle.kts b/benchmarks/ios/scroll-lazy-grid/shared/build.gradle.kts deleted file mode 100644 index 8e9b6dadf9..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/shared/build.gradle.kts +++ /dev/null @@ -1,83 +0,0 @@ -plugins { - kotlin("multiplatform") - kotlin("native.cocoapods") - id("com.android.library") - id("org.jetbrains.compose") -} - -kotlin { - android() - - jvm("desktop") - - iosX64() - iosArm64() - iosSimulatorArm64() - - cocoapods { - version = "1.0.0" - summary = "Some description for the Shared Module" - homepage = "Link to the Shared Module homepage" - ios.deploymentTarget = "14.1" - podfile = project.file("../iosApp/Podfile") - framework { - baseName = "shared" - isStatic = true - } - extraSpecAttributes["resources"] = "['src/commonMain/resources/**', 'src/iosMain/resources/**']" - } - - sourceSets { - val commonMain by getting { - dependencies { - implementation(compose.runtime) - implementation(compose.foundation) - implementation(compose.material) - @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) - implementation(compose.components.resources) - } - } - val androidMain by getting { - dependencies { - api("androidx.activity:activity-compose:1.6.1") - api("androidx.appcompat:appcompat:1.6.1") - api("androidx.core:core-ktx:1.9.0") - } - } - val iosX64Main by getting - val iosArm64Main by getting - val iosSimulatorArm64Main by getting - val iosMain by creating { - dependsOn(commonMain) - iosX64Main.dependsOn(this) - iosArm64Main.dependsOn(this) - iosSimulatorArm64Main.dependsOn(this) - } - val desktopMain by getting { - dependencies { - implementation(compose.desktop.common) - } - } - } -} - -android { - compileSdk = (findProperty("android.compileSdk") as String).toInt() - namespace = "com.myapplication.common" - - sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") - sourceSets["main"].res.srcDirs("src/androidMain/res") - sourceSets["main"].resources.srcDirs("src/commonMain/resources") - - defaultConfig { - minSdk = (findProperty("android.minSdk") as String).toInt() - targetSdk = (findProperty("android.targetSdk") as String).toInt() - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - kotlin { - jvmToolchain(11) - } -} diff --git a/benchmarks/ios/scroll-lazy-grid/shared/src/androidMain/AndroidManifest.xml b/benchmarks/ios/scroll-lazy-grid/shared/src/androidMain/AndroidManifest.xml deleted file mode 100644 index 568741e54f..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/shared/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/shared/src/androidMain/kotlin/main.android.kt b/benchmarks/ios/scroll-lazy-grid/shared/src/androidMain/kotlin/main.android.kt deleted file mode 100644 index 4a1d2a6feb..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/shared/src/androidMain/kotlin/main.android.kt +++ /dev/null @@ -1,3 +0,0 @@ -import androidx.compose.runtime.Composable - -@Composable fun MainView() = App() diff --git a/benchmarks/ios/scroll-lazy-grid/shared/src/commonMain/kotlin/App.kt b/benchmarks/ios/scroll-lazy-grid/shared/src/commonMain/kotlin/App.kt deleted file mode 100644 index b89f8ca451..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/shared/src/commonMain/kotlin/App.kt +++ /dev/null @@ -1,104 +0,0 @@ -import androidx.compose.foundation.gestures.scrollBy -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.items -import androidx.compose.foundation.lazy.grid.rememberLazyGridState -import androidx.compose.material.Card -import androidx.compose.material.Checkbox -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.runtime.withFrameMillis -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp - -@Composable -fun App() { - val itemCount = 12000 - val entries = remember {List(itemCount) { Entry("$it") }} - val state = rememberLazyGridState() - - var smoothScroll by remember { mutableStateOf(false)} - - MaterialTheme { - Column { - Row { - Checkbox( - checked = smoothScroll, - onCheckedChange = { value -> smoothScroll = value} - ) - Text (text = "Smooth scroll", modifier = Modifier.align(Alignment.CenterVertically)) - } - - LazyVerticalGrid( - columns = GridCells.Fixed(4), - modifier = Modifier.fillMaxWidth().semantics { contentDescription = "IamLazy" }, - state = state - ) { - items(entries) { - ListCell(it) - } - } - } - - } - - var curItem by remember { mutableStateOf(0) } - var direct by remember { mutableStateOf(true) } - if (smoothScroll) { - LaunchedEffect(Unit) { - while (smoothScroll) { - withFrameMillis { } - curItem = state.firstVisibleItemIndex - if (curItem == 0) direct = true - if (curItem > itemCount - 100) direct = false - state.scrollBy(if (direct) 5f else -5f) - } - } - } else { - LaunchedEffect(curItem) { - withFrameMillis { } - curItem += if (direct) 50 else -50 - if (curItem >= itemCount) { - direct = false - curItem = itemCount - 1 - } else if (curItem <= 0) { - direct = true - curItem = 0 - } - state.scrollToItem(curItem) - } - } - -} - -data class Entry(val contents: String) - -@Composable -private fun ListCell(entry: Entry) { - Card( - modifier = Modifier - .fillMaxWidth() - .padding(8.dp) - ) { - Text( - text = entry.contents, - textAlign = TextAlign.Center, - style = MaterialTheme.typography.h5, - modifier = Modifier.padding(16.dp) - ) - } -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-grid/shared/src/desktopMain/kotlin/main.desktop.kt b/benchmarks/ios/scroll-lazy-grid/shared/src/desktopMain/kotlin/main.desktop.kt deleted file mode 100644 index 190ff810fd..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/shared/src/desktopMain/kotlin/main.desktop.kt +++ /dev/null @@ -1,4 +0,0 @@ -import androidx.compose.desktop.ui.tooling.preview.Preview -import androidx.compose.runtime.Composable - -@Composable fun MainView() = App() diff --git a/benchmarks/ios/scroll-lazy-grid/shared/src/iosMain/kotlin/main.ios.kt b/benchmarks/ios/scroll-lazy-grid/shared/src/iosMain/kotlin/main.ios.kt deleted file mode 100644 index fa143d45ce..0000000000 --- a/benchmarks/ios/scroll-lazy-grid/shared/src/iosMain/kotlin/main.ios.kt +++ /dev/null @@ -1,3 +0,0 @@ -import androidx.compose.ui.window.ComposeUIViewController - -fun MainViewController() = ComposeUIViewController { App() } \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/.gitignore b/benchmarks/ios/scroll-lazy-list/.gitignore deleted file mode 100644 index 6e5f30477c..0000000000 --- a/benchmarks/ios/scroll-lazy-list/.gitignore +++ /dev/null @@ -1,15 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea -.DS_Store -build/ -/captures -.externalNativeBuild -.cxx -iosApp/Podfile.lock -iosApp/Pods/* -iosApp/iosApp.xcworkspace/* -iosApp/iosApp.xcodeproj/* -!iosApp/iosApp.xcodeproj/project.pbxproj -shared/shared.podspec diff --git a/benchmarks/ios/scroll-lazy-list/.run/desktopApp.run.xml b/benchmarks/ios/scroll-lazy-list/.run/desktopApp.run.xml deleted file mode 100644 index 54bb5c1c5a..0000000000 --- a/benchmarks/ios/scroll-lazy-list/.run/desktopApp.run.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - true - true - false - - - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/LICENSE.txt b/benchmarks/ios/scroll-lazy-list/LICENSE.txt deleted file mode 100644 index 244380c242..0000000000 --- a/benchmarks/ios/scroll-lazy-list/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2020-2021 JetBrains s.r.o. and and respective authors and developers. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/benchmarks/ios/scroll-lazy-list/README.md b/benchmarks/ios/scroll-lazy-list/README.md deleted file mode 100644 index 713e51556c..0000000000 --- a/benchmarks/ios/scroll-lazy-list/README.md +++ /dev/null @@ -1,3 +0,0 @@ -A benchmark app extracted from the sample described in this issue: https://github.com/JetBrains/compose-multiplatform/issues/2283 - -In general it is a lazy list with some complex content that automaticall scrolls. \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/build.gradle.kts b/benchmarks/ios/scroll-lazy-list/androidApp/build.gradle.kts deleted file mode 100644 index b86596b317..0000000000 --- a/benchmarks/ios/scroll-lazy-list/androidApp/build.gradle.kts +++ /dev/null @@ -1,38 +0,0 @@ -plugins { - kotlin("multiplatform") - id("com.android.application") - id("org.jetbrains.compose") -} - -kotlin { - android() - sourceSets { - val androidMain by getting { - dependencies { - implementation(project(":shared")) - } - } - } -} - -android { - compileSdk = (findProperty("android.compileSdk") as String).toInt() - namespace = "com.myapplication" - - sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") - - defaultConfig { - applicationId = "com.myapplication.MyApplication" - minSdk = (findProperty("android.minSdk") as String).toInt() - targetSdk = (findProperty("android.targetSdk") as String).toInt() - versionCode = 1 - versionName = "1.0" - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - kotlin { - jvmToolchain(11) - } -} diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/AndroidManifest.xml b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/AndroidManifest.xml deleted file mode 100644 index bc7e861696..0000000000 --- a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/kotlin/com/myapplication/MainActivity.kt b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/kotlin/com/myapplication/MainActivity.kt deleted file mode 100644 index fd6e831ceb..0000000000 --- a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/kotlin/com/myapplication/MainActivity.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.myapplication - -import MainView -import android.os.Bundle -import androidx.activity.compose.setContent -import androidx.appcompat.app.AppCompatActivity - -class MainActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - - setContent { - MainView() - } - } -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 2b068d1146..0000000000 --- a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/drawable/ic_launcher_background.xml b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 07d5da9cbf..0000000000 --- a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml deleted file mode 100644 index eca70cfe52..0000000000 --- a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml deleted file mode 100644 index eca70cfe52..0000000000 --- a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index a571e60098..0000000000 Binary files a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png deleted file mode 100644 index 61da551c55..0000000000 Binary files a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index c41dd28531..0000000000 Binary files a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png deleted file mode 100644 index db5080a752..0000000000 Binary files a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 6dba46dab1..0000000000 Binary files a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png deleted file mode 100644 index da31a871c8..0000000000 Binary files a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index 15ac681720..0000000000 Binary files a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png deleted file mode 100644 index b216f2d313..0000000000 Binary files a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index f25a419744..0000000000 Binary files a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png deleted file mode 100644 index e96783ccce..0000000000 Binary files a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/values/strings.xml b/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/values/strings.xml deleted file mode 100644 index 592270bf53..0000000000 --- a/benchmarks/ios/scroll-lazy-list/androidApp/src/androidMain/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - My application - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/build.gradle.kts b/benchmarks/ios/scroll-lazy-list/build.gradle.kts deleted file mode 100644 index b7e1d5d26a..0000000000 --- a/benchmarks/ios/scroll-lazy-list/build.gradle.kts +++ /dev/null @@ -1,8 +0,0 @@ -plugins { - // this is necessary to avoid the plugins to be loaded multiple times - // in each subproject's classloader - kotlin("multiplatform").apply(false) - id("com.android.application").apply(false) - id("com.android.library").apply(false) - id("org.jetbrains.compose").apply(false) -} diff --git a/benchmarks/ios/scroll-lazy-list/cleanup.sh b/benchmarks/ios/scroll-lazy-list/cleanup.sh deleted file mode 100755 index 62f9391b86..0000000000 --- a/benchmarks/ios/scroll-lazy-list/cleanup.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -rm -rf .idea -./gradlew clean -rm -rf .gradle -rm -rf build -rm -rf */build -rm -rf iosApp/iosApp.xcworkspace -rm -rf iosApp/Pods -rm -rf iosApp/iosApp.xcodeproj/project.xcworkspace -rm -rf iosApp/iosApp.xcodeproj/xcuserdata diff --git a/benchmarks/ios/scroll-lazy-list/desktopApp/build.gradle.kts b/benchmarks/ios/scroll-lazy-list/desktopApp/build.gradle.kts deleted file mode 100644 index 931f3467a2..0000000000 --- a/benchmarks/ios/scroll-lazy-list/desktopApp/build.gradle.kts +++ /dev/null @@ -1,30 +0,0 @@ -import org.jetbrains.compose.desktop.application.dsl.TargetFormat - -plugins { - kotlin("multiplatform") - id("org.jetbrains.compose") -} - -kotlin { - jvm() - sourceSets { - val jvmMain by getting { - dependencies { - implementation(compose.desktop.currentOs) - implementation(project(":shared")) - } - } - } -} - -compose.desktop { - application { - mainClass = "MainKt" - - nativeDistributions { - targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) - packageName = "KotlinMultiplatformComposeDesktopApplication" - packageVersion = "1.0.0" - } - } -} diff --git a/benchmarks/ios/scroll-lazy-list/desktopApp/src/jvmMain/kotlin/main.kt b/benchmarks/ios/scroll-lazy-list/desktopApp/src/jvmMain/kotlin/main.kt deleted file mode 100644 index 5ffada98e1..0000000000 --- a/benchmarks/ios/scroll-lazy-list/desktopApp/src/jvmMain/kotlin/main.kt +++ /dev/null @@ -1,8 +0,0 @@ -import androidx.compose.ui.window.Window -import androidx.compose.ui.window.application - -fun main() = application { - Window(onCloseRequest = ::exitApplication) { - MainView() - } -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/desktopMain/kotlin/main.desktop.kt b/benchmarks/ios/scroll-lazy-list/desktopMain/kotlin/main.desktop.kt deleted file mode 100644 index 5f23de7dd9..0000000000 --- a/benchmarks/ios/scroll-lazy-list/desktopMain/kotlin/main.desktop.kt +++ /dev/null @@ -1,12 +0,0 @@ -import androidx.compose.desktop.ui.tooling.preview.Preview -import androidx.compose.runtime.Composable - -actual fun getPlatformName(): String = "Desktop" - -@Composable fun MainView() = App() - -@Preview -@Composable -fun AppPreview() { - App() -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/gradle.properties b/benchmarks/ios/scroll-lazy-list/gradle.properties deleted file mode 100644 index 402848dbea..0000000000 --- a/benchmarks/ios/scroll-lazy-list/gradle.properties +++ /dev/null @@ -1,24 +0,0 @@ -#Gradle -org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M" - -#Kotlin -kotlin.code.style=official - -#MPP -kotlin.mpp.stability.nowarn=true -kotlin.mpp.enableCInteropCommonization=true -kotlin.mpp.androidSourceSetLayoutVersion=2 - -#Compose -org.jetbrains.compose.experimental.uikit.enabled=true - -#Android -android.useAndroidX=true -android.compileSdk=33 -android.targetSdk=33 -android.minSdk=24 - -#Versions -kotlin.version=1.8.20 -agp.version=7.4.2 -compose.version=1.4.0 \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/gradle/wrapper/gradle-wrapper.jar b/benchmarks/ios/scroll-lazy-list/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f0..0000000000 Binary files a/benchmarks/ios/scroll-lazy-list/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-list/gradle/wrapper/gradle-wrapper.properties b/benchmarks/ios/scroll-lazy-list/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index e1bef7e873..0000000000 --- a/benchmarks/ios/scroll-lazy-list/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/benchmarks/ios/scroll-lazy-list/gradlew b/benchmarks/ios/scroll-lazy-list/gradlew deleted file mode 100755 index a69d9cb6c2..0000000000 --- a/benchmarks/ios/scroll-lazy-list/gradlew +++ /dev/null @@ -1,240 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/benchmarks/ios/scroll-lazy-list/gradlew.bat b/benchmarks/ios/scroll-lazy-list/gradlew.bat deleted file mode 100644 index f127cfd49d..0000000000 --- a/benchmarks/ios/scroll-lazy-list/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/benchmarks/ios/scroll-lazy-list/iosApp/Configuration/Config.xcconfig b/benchmarks/ios/scroll-lazy-list/iosApp/Configuration/Config.xcconfig deleted file mode 100644 index f391597827..0000000000 --- a/benchmarks/ios/scroll-lazy-list/iosApp/Configuration/Config.xcconfig +++ /dev/null @@ -1,3 +0,0 @@ -TEAM_ID= -BUNDLE_ID=com.myapplication.MyApplication -APP_NAME=My application diff --git a/benchmarks/ios/scroll-lazy-list/iosApp/Podfile b/benchmarks/ios/scroll-lazy-list/iosApp/Podfile deleted file mode 100644 index aff9c517b2..0000000000 --- a/benchmarks/ios/scroll-lazy-list/iosApp/Podfile +++ /dev/null @@ -1,5 +0,0 @@ -target 'iosApp' do - use_frameworks! - platform :ios, '14.1' - pod 'shared', :path => '../shared' -end \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp.xcodeproj/project.pbxproj b/benchmarks/ios/scroll-lazy-list/iosApp/iosApp.xcodeproj/project.pbxproj deleted file mode 100644 index c888c0443c..0000000000 --- a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp.xcodeproj/project.pbxproj +++ /dev/null @@ -1,400 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 51; - objects = { - -/* Begin PBXBuildFile section */ - 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; }; - 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; }; - 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; }; - 7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; }; - CFDB58B53BB94DE262B13C24 /* Pods_iosApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B1049432C0C2B312090ABF6 /* Pods_iosApp.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = ""; }; - 4FF3202A603A284706412EDC /* Pods-iosApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.debug.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.debug.xcconfig"; sourceTree = ""; }; - 6B1049432C0C2B312090ABF6 /* Pods_iosApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_iosApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 7555FF7B242A565900829871 /* My application.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "My application.app"; sourceTree = BUILT_PRODUCTS_DIR; }; - 7555FF82242A565900829871 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; - 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - AB3632DC29227652001CCB65 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; }; - FF8CA3F5360CEAB49D74065F /* Pods-iosApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.release.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - F85CB1118929364A9C6EFABC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - CFDB58B53BB94DE262B13C24 /* Pods_iosApp.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 058557D7273AAEEB004C7B11 /* Preview Content */ = { - isa = PBXGroup; - children = ( - 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - 42799AB246E5F90AF97AA0EF /* Frameworks */ = { - isa = PBXGroup; - children = ( - 6B1049432C0C2B312090ABF6 /* Pods_iosApp.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 7555FF72242A565900829871 = { - isa = PBXGroup; - children = ( - AB1DB47929225F7C00F7AF9C /* Configuration */, - 7555FF7D242A565900829871 /* iosApp */, - 7555FF7C242A565900829871 /* Products */, - FEFF387C0A8D172AA4D59CAE /* Pods */, - 42799AB246E5F90AF97AA0EF /* Frameworks */, - ); - sourceTree = ""; - }; - 7555FF7C242A565900829871 /* Products */ = { - isa = PBXGroup; - children = ( - 7555FF7B242A565900829871 /* My application.app */, - ); - name = Products; - sourceTree = ""; - }; - 7555FF7D242A565900829871 /* iosApp */ = { - isa = PBXGroup; - children = ( - 058557BA273AAA24004C7B11 /* Assets.xcassets */, - 7555FF82242A565900829871 /* ContentView.swift */, - 7555FF8C242A565B00829871 /* Info.plist */, - 2152FB032600AC8F00CF470E /* iOSApp.swift */, - 058557D7273AAEEB004C7B11 /* Preview Content */, - ); - path = iosApp; - sourceTree = ""; - }; - AB1DB47929225F7C00F7AF9C /* Configuration */ = { - isa = PBXGroup; - children = ( - AB3632DC29227652001CCB65 /* Config.xcconfig */, - ); - path = Configuration; - sourceTree = ""; - }; - FEFF387C0A8D172AA4D59CAE /* Pods */ = { - isa = PBXGroup; - children = ( - 4FF3202A603A284706412EDC /* Pods-iosApp.debug.xcconfig */, - FF8CA3F5360CEAB49D74065F /* Pods-iosApp.release.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 7555FF7A242A565900829871 /* iosApp */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */; - buildPhases = ( - 98D614C51D2DA07C614CC46E /* [CP] Check Pods Manifest.lock */, - 7555FF77242A565900829871 /* Sources */, - 7555FF79242A565900829871 /* Resources */, - F85CB1118929364A9C6EFABC /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = iosApp; - productName = iosApp; - productReference = 7555FF7B242A565900829871 /* My application.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 7555FF73242A565900829871 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 1130; - LastUpgradeCheck = 1130; - ORGANIZATIONNAME = orgName; - TargetAttributes = { - 7555FF7A242A565900829871 = { - CreatedOnToolsVersion = 11.3.1; - }; - }; - }; - buildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 7555FF72242A565900829871; - productRefGroup = 7555FF7C242A565900829871 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 7555FF7A242A565900829871 /* iosApp */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 7555FF79242A565900829871 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */, - 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 98D614C51D2DA07C614CC46E /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-iosApp-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 7555FF77242A565900829871 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */, - 7555FF83242A565900829871 /* ContentView.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 7555FFA3242A565B00829871 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 7555FFA4242A565B00829871 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 7555FFA6242A565B00829871 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4FF3202A603A284706412EDC /* Pods-iosApp.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; - DEVELOPMENT_TEAM = "${TEAM_ID}"; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = iosApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; - PRODUCT_NAME = "${APP_NAME}"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 7555FFA7242A565B00829871 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = FF8CA3F5360CEAB49D74065F /* Pods-iosApp.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; - DEVELOPMENT_TEAM = "${TEAM_ID}"; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = iosApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; - PRODUCT_NAME = "${APP_NAME}"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7555FFA3242A565B00829871 /* Debug */, - 7555FFA4242A565B00829871 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7555FFA6242A565B00829871 /* Debug */, - 7555FFA7242A565B00829871 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 7555FF73242A565900829871 /* Project object */; -} diff --git a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json b/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json deleted file mode 100644 index ee7e3ca03f..0000000000 --- a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "colors" : [ - { - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 8edf56e7a9..0000000000 --- a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "images" : [ - { - "filename" : "app-icon-1024.png", - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png b/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png deleted file mode 100644 index 53fc536fb9..0000000000 Binary files a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png and /dev/null differ diff --git a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Assets.xcassets/Contents.json b/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Assets.xcassets/Contents.json deleted file mode 100644 index 4aa7c5350b..0000000000 --- a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/ContentView.swift b/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/ContentView.swift deleted file mode 100644 index f7f6457b31..0000000000 --- a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/ContentView.swift +++ /dev/null @@ -1,21 +0,0 @@ -import UIKit -import SwiftUI -import shared - -struct ComposeView: UIViewControllerRepresentable { - func makeUIViewController(context: Context) -> UIViewController { - Main_iosKt.MainViewController() - } - - func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} -} - -struct ContentView: View { - var body: some View { - ComposeView() - .ignoresSafeArea(.keyboard) // Compose has own keyboard handler - } -} - - - diff --git a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Info.plist b/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Info.plist deleted file mode 100644 index 9a269f5eaa..0000000000 --- a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Info.plist +++ /dev/null @@ -1,48 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - - UILaunchScreen - - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json b/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json deleted file mode 100644 index 4aa7c5350b..0000000000 --- a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/iOSApp.swift b/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/iOSApp.swift deleted file mode 100644 index 0648e8602f..0000000000 --- a/benchmarks/ios/scroll-lazy-list/iosApp/iosApp/iOSApp.swift +++ /dev/null @@ -1,10 +0,0 @@ -import SwiftUI - -@main -struct iOSApp: App { - var body: some Scene { - WindowGroup { - ContentView() - } - } -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/settings.gradle.kts b/benchmarks/ios/scroll-lazy-list/settings.gradle.kts deleted file mode 100644 index 2e81b6fa9e..0000000000 --- a/benchmarks/ios/scroll-lazy-list/settings.gradle.kts +++ /dev/null @@ -1,38 +0,0 @@ -rootProject.name = "My application" - -include(":androidApp") -include(":shared") -include(":desktopApp") - -pluginManagement { - repositories { - gradlePluginPortal() - maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") - google() - mavenLocal() - } - - plugins { - val kotlinVersion = extra["kotlin.version"] as String - val agpVersion = extra["agp.version"] as String - val composeVersion = extra["compose.version"] as String - - kotlin("jvm").version(kotlinVersion) - kotlin("multiplatform").version(kotlinVersion) - kotlin("android").version(kotlinVersion) - - id("com.android.application").version(agpVersion) - id("com.android.library").version(agpVersion) - - id("org.jetbrains.compose").version(composeVersion) - } -} - -dependencyResolutionManagement { - repositories { - google() - mavenCentral() - mavenLocal() - maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") - } -} diff --git a/benchmarks/ios/scroll-lazy-list/shared/build.gradle.kts b/benchmarks/ios/scroll-lazy-list/shared/build.gradle.kts deleted file mode 100644 index ad37527fd4..0000000000 --- a/benchmarks/ios/scroll-lazy-list/shared/build.gradle.kts +++ /dev/null @@ -1,91 +0,0 @@ -plugins { - kotlin("multiplatform") - kotlin("native.cocoapods") - id("com.android.library") - id("org.jetbrains.compose") -} - -kotlin { - android() - - jvm("desktop") - - iosX64() - iosArm64() - iosSimulatorArm64() - - cocoapods { - version = "1.0.0" - summary = "Some description for the Shared Module" - homepage = "Link to the Shared Module homepage" - ios.deploymentTarget = "14.1" - podfile = project.file("../iosApp/Podfile") - framework { - baseName = "shared" - isStatic = true - } - extraSpecAttributes["resources"] = "['src/commonMain/resources/**', 'src/iosMain/resources/**']" - } - - sourceSets { - val commonMain by getting { - dependencies { - implementation(compose.runtime) - implementation(compose.foundation) - implementation(compose.material) - @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) - implementation(compose.components.resources) - } - } - val androidMain by getting { - dependencies { - api("androidx.activity:activity-compose:1.6.1") - api("androidx.appcompat:appcompat:1.6.1") - api("androidx.core:core-ktx:1.9.0") - } - } - val iosX64Main by getting - val iosArm64Main by getting - val iosSimulatorArm64Main by getting - val iosMain by creating { - dependsOn(commonMain) - iosX64Main.dependsOn(this) - iosArm64Main.dependsOn(this) - iosSimulatorArm64Main.dependsOn(this) - } - val desktopMain by getting { - dependencies { - implementation(compose.desktop.common) - } - } - } -} - -android { - compileSdk = (findProperty("android.compileSdk") as String).toInt() - namespace = "com.myapplication.common" - - sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") - sourceSets["main"].res.srcDirs("src/androidMain/res") - sourceSets["main"].resources.srcDirs("src/commonMain/resources") - - defaultConfig { - minSdk = (findProperty("android.minSdk") as String).toInt() - targetSdk = (findProperty("android.targetSdk") as String).toInt() - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } - kotlin { - jvmToolchain(11) -// targets.withType { -// binaries.all { -// freeCompilerArgs += listOf("-Xdisable-phases=VerifyBitcode", -// "-Xgc=noop" -// ) -// } -// } - } - -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/androidMain/AndroidManifest.xml b/benchmarks/ios/scroll-lazy-list/shared/src/androidMain/AndroidManifest.xml deleted file mode 100644 index 568741e54f..0000000000 --- a/benchmarks/ios/scroll-lazy-list/shared/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/androidMain/kotlin/listsample/models/FakeItem.kt b/benchmarks/ios/scroll-lazy-list/shared/src/androidMain/kotlin/listsample/models/FakeItem.kt deleted file mode 100644 index 5b6f47f957..0000000000 --- a/benchmarks/ios/scroll-lazy-list/shared/src/androidMain/kotlin/listsample/models/FakeItem.kt +++ /dev/null @@ -1,30 +0,0 @@ -package listsample.models - -import android.os.Parcel -import android.os.Parcelable - -actual fun createFakeItem(): ICompositionModel = AndroidFakeItem() - -class AndroidFakeItem() : FakeItem(), Parcelable { - constructor(parcel: Parcel) : this() { - } - - override fun writeToParcel(parcel: Parcel, flags: Int) { - - } - - override fun describeContents(): Int { - return 0 - } - - companion object CREATOR : Parcelable.Creator { - override fun createFromParcel(parcel: Parcel): AndroidFakeItem { - return AndroidFakeItem(parcel) - } - - override fun newArray(size: Int): Array { - return arrayOfNulls(size) - } - } - -} diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/androidMain/kotlin/main.android.kt b/benchmarks/ios/scroll-lazy-list/shared/src/androidMain/kotlin/main.android.kt deleted file mode 100644 index 4a1d2a6feb..0000000000 --- a/benchmarks/ios/scroll-lazy-list/shared/src/androidMain/kotlin/main.android.kt +++ /dev/null @@ -1,3 +0,0 @@ -import androidx.compose.runtime.Composable - -@Composable fun MainView() = App() diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/App.kt b/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/App.kt deleted file mode 100644 index 0d17ee9d67..0000000000 --- a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/App.kt +++ /dev/null @@ -1,8 +0,0 @@ -import androidx.compose.runtime.Composable - -import listsample.components.MainUiNoImageUseModel - -@Composable -fun App() { - MainUiNoImageUseModel() -} \ No newline at end of file diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/desktopMain/kotlin/listsample/models/FakeItem.kt b/benchmarks/ios/scroll-lazy-list/shared/src/desktopMain/kotlin/listsample/models/FakeItem.kt deleted file mode 100644 index 5c52387f86..0000000000 --- a/benchmarks/ios/scroll-lazy-list/shared/src/desktopMain/kotlin/listsample/models/FakeItem.kt +++ /dev/null @@ -1,3 +0,0 @@ -package listsample.models - -actual fun createFakeItem(): ICompositionModel = FakeItem() diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/desktopMain/kotlin/main.desktop.kt b/benchmarks/ios/scroll-lazy-list/shared/src/desktopMain/kotlin/main.desktop.kt deleted file mode 100644 index 409ab5bcad..0000000000 --- a/benchmarks/ios/scroll-lazy-list/shared/src/desktopMain/kotlin/main.desktop.kt +++ /dev/null @@ -1,4 +0,0 @@ -import androidx.compose.runtime.Composable - -@Composable fun MainView() = App() - diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/iosMain/kotlin/listsample/models/FakeItem.kt b/benchmarks/ios/scroll-lazy-list/shared/src/iosMain/kotlin/listsample/models/FakeItem.kt deleted file mode 100644 index 5c52387f86..0000000000 --- a/benchmarks/ios/scroll-lazy-list/shared/src/iosMain/kotlin/listsample/models/FakeItem.kt +++ /dev/null @@ -1,3 +0,0 @@ -package listsample.models - -actual fun createFakeItem(): ICompositionModel = FakeItem() diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/iosMain/kotlin/main.ios.kt b/benchmarks/ios/scroll-lazy-list/shared/src/iosMain/kotlin/main.ios.kt deleted file mode 100644 index fa143d45ce..0000000000 --- a/benchmarks/ios/scroll-lazy-list/shared/src/iosMain/kotlin/main.ios.kt +++ /dev/null @@ -1,3 +0,0 @@ -import androidx.compose.ui.window.ComposeUIViewController - -fun MainViewController() = ComposeUIViewController { App() } \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/.gitignore b/benchmarks/ios/visual-effects-ny/.gitignore deleted file mode 100644 index 180e034383..0000000000 --- a/benchmarks/ios/visual-effects-ny/.gitignore +++ /dev/null @@ -1,21 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml -.DS_Store -build/ -/captures -.externalNativeBuild -.cxx -iosApp/Podfile.lock -iosApp/Pods/* -iosApp/iosApp.xcworkspace/* -iosApp/iosApp.xcodeproj/* -!iosApp/iosApp.xcodeproj/project.pbxproj -shared/shared.podspec \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/.run/desktopApp.run.xml b/benchmarks/ios/visual-effects-ny/.run/desktopApp.run.xml deleted file mode 100644 index 0de5218670..0000000000 --- a/benchmarks/ios/visual-effects-ny/.run/desktopApp.run.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - true - true - false - - - \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/README.md b/benchmarks/ios/visual-effects-ny/README.md deleted file mode 100644 index 45d2731886..0000000000 --- a/benchmarks/ios/visual-effects-ny/README.md +++ /dev/null @@ -1 +0,0 @@ -A benchmark app extracted from the NY sample of examples/visual-effects \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/androidApp/build.gradle.kts b/benchmarks/ios/visual-effects-ny/androidApp/build.gradle.kts deleted file mode 100644 index 61a9bd4d72..0000000000 --- a/benchmarks/ios/visual-effects-ny/androidApp/build.gradle.kts +++ /dev/null @@ -1,31 +0,0 @@ -plugins { - kotlin("multiplatform") - id("com.android.application") - id("org.jetbrains.compose") -} - -kotlin { - android() - sourceSets { - val androidMain by getting { - dependencies { - implementation(project(":shared")) - } - } - } -} - -android { - compileSdk = 33 - defaultConfig { - applicationId = "org.jetbrains.VisualEffects" - minSdk = 26 - targetSdk = 33 - versionCode = 1 - versionName = "1.0" - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } -} diff --git a/benchmarks/ios/visual-effects-ny/androidApp/src/androidMain/AndroidManifest.xml b/benchmarks/ios/visual-effects-ny/androidApp/src/androidMain/AndroidManifest.xml deleted file mode 100644 index 0e4d4b8a1b..0000000000 --- a/benchmarks/ios/visual-effects-ny/androidApp/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/androidApp/src/androidMain/kotlin/MainActivity.kt b/benchmarks/ios/visual-effects-ny/androidApp/src/androidMain/kotlin/MainActivity.kt deleted file mode 100644 index 783122db5a..0000000000 --- a/benchmarks/ios/visual-effects-ny/androidApp/src/androidMain/kotlin/MainActivity.kt +++ /dev/null @@ -1,14 +0,0 @@ -package org.jetbrains.compose.demo.visuals - -import android.os.Bundle -import androidx.activity.compose.setContent -import androidx.appcompat.app.AppCompatActivity - -class MainActivity : AppCompatActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - MainView() - } - } -} \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/androidApp/src/androidMain/res/values/strings.xml b/benchmarks/ios/visual-effects-ny/androidApp/src/androidMain/res/values/strings.xml deleted file mode 100644 index d23a35eb38..0000000000 --- a/benchmarks/ios/visual-effects-ny/androidApp/src/androidMain/res/values/strings.xml +++ /dev/null @@ -1,3 +0,0 @@ - - Visual Effects - \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/build.gradle.kts b/benchmarks/ios/visual-effects-ny/build.gradle.kts deleted file mode 100644 index 8d0c1f3d7c..0000000000 --- a/benchmarks/ios/visual-effects-ny/build.gradle.kts +++ /dev/null @@ -1,19 +0,0 @@ -plugins { - // this is necessary to avoid the plugins to be loaded multiple times - // in each subproject's classloader - kotlin("jvm") apply false - kotlin("multiplatform") apply false - kotlin("android") apply false - id("com.android.application") apply false - id("com.android.library") apply false - id("org.jetbrains.compose") apply false -} - -allprojects { - repositories { - google() - mavenCentral() - maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") - mavenLocal() - } -} diff --git a/benchmarks/ios/visual-effects-ny/desktopApp/build.gradle.kts b/benchmarks/ios/visual-effects-ny/desktopApp/build.gradle.kts deleted file mode 100644 index 1cebd3ec6a..0000000000 --- a/benchmarks/ios/visual-effects-ny/desktopApp/build.gradle.kts +++ /dev/null @@ -1,55 +0,0 @@ -import org.jetbrains.compose.desktop.application.dsl.TargetFormat - -plugins { - kotlin("multiplatform") - id("org.jetbrains.compose") -} - -kotlin { - jvm {} - sourceSets { - val jvmMain by getting { - dependencies { - implementation(compose.desktop.currentOs) - implementation(project(":shared")) - } - } - } -} - -compose.desktop { - application { - mainClass = "org.jetbrains.compose.demo.visuals.MainKt" - nativeDistributions { - targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) - packageName = "compose-demo" - packageVersion = "1.0.0" - } - } -} - -afterEvaluate { - val additionalArguments = mutableListOf() - - val runTask = tasks.named("run") { - this.args = additionalArguments - } - - tasks.register("runWords") { - additionalArguments.add("words") - group = "compose desktop" - dependsOn(runTask) - } - - tasks.register("runWave") { - additionalArguments.add("wave") - group = "compose desktop" - dependsOn(runTask) - } - - tasks.register("runNewYear") { - additionalArguments.add("NY") - group = "compose desktop" - dependsOn(runTask) - } -} \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/desktopApp/src/jvmMain/kotlin/main.kt b/benchmarks/ios/visual-effects-ny/desktopApp/src/jvmMain/kotlin/main.kt deleted file mode 100644 index 1217cc5b9d..0000000000 --- a/benchmarks/ios/visual-effects-ny/desktopApp/src/jvmMain/kotlin/main.kt +++ /dev/null @@ -1,4 +0,0 @@ -package org.jetbrains.compose.demo.visuals - -fun main() = mainNY() - diff --git a/benchmarks/ios/visual-effects-ny/gradle.properties b/benchmarks/ios/visual-effects-ny/gradle.properties deleted file mode 100644 index 1c9caed420..0000000000 --- a/benchmarks/ios/visual-effects-ny/gradle.properties +++ /dev/null @@ -1,15 +0,0 @@ -kotlin.code.style=official -xcodeproj=./iosApp -kotlin.native.cocoapods.generate.wrapper=true -android.useAndroidX=true -org.gradle.jvmargs=-Xmx3g -org.jetbrains.compose.experimental.jscanvas.enabled=true -org.jetbrains.compose.experimental.macos.enabled=true -org.jetbrains.compose.experimental.uikit.enabled=true -kotlin.mpp.androidSourceSetLayoutVersion=2 -kotlin.native.useEmbeddableCompilerJar=true -# Enable kotlin/native experimental memory model -kotlin.native.binary.memoryModel=experimental -kotlin.version=1.8.20 -agp.version=7.1.3 -compose.version=1.4.0 diff --git a/benchmarks/ios/visual-effects-ny/gradle/wrapper/gradle-wrapper.jar b/benchmarks/ios/visual-effects-ny/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 249e5832f0..0000000000 Binary files a/benchmarks/ios/visual-effects-ny/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/benchmarks/ios/visual-effects-ny/gradle/wrapper/gradle-wrapper.properties b/benchmarks/ios/visual-effects-ny/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index ae04661ee7..0000000000 --- a/benchmarks/ios/visual-effects-ny/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/benchmarks/ios/visual-effects-ny/gradlew b/benchmarks/ios/visual-effects-ny/gradlew deleted file mode 100755 index a69d9cb6c2..0000000000 --- a/benchmarks/ios/visual-effects-ny/gradlew +++ /dev/null @@ -1,240 +0,0 @@ -#!/bin/sh - -# -# Copyright © 2015-2021 the original authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -# -# Gradle start up script for POSIX generated by Gradle. -# -# Important for running: -# -# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is -# noncompliant, but you have some other compliant shell such as ksh or -# bash, then to run this script, type that shell name before the whole -# command line, like: -# -# ksh Gradle -# -# Busybox and similar reduced shells will NOT work, because this script -# requires all of these POSIX shell features: -# * functions; -# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», -# «${var#prefix}», «${var%suffix}», and «$( cmd )»; -# * compound commands having a testable exit status, especially «case»; -# * various built-in commands including «command», «set», and «ulimit». -# -# Important for patching: -# -# (2) This script targets any POSIX shell, so it avoids extensions provided -# by Bash, Ksh, etc; in particular arrays are avoided. -# -# The "traditional" practice of packing multiple parameters into a -# space-separated string is a well documented source of bugs and security -# problems, so this is (mostly) avoided, by progressively accumulating -# options in "$@", and eventually passing that to Java. -# -# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, -# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; -# see the in-line comments for details. -# -# There are tweaks for specific operating systems such as AIX, CygWin, -# Darwin, MinGW, and NonStop. -# -# (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt -# within the Gradle project. -# -# You can find Gradle at https://github.com/gradle/gradle/. -# -############################################################################## - -# Attempt to set APP_HOME - -# Resolve links: $0 may be a link -app_path=$0 - -# Need this for daisy-chained symlinks. -while - APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path - [ -h "$app_path" ] -do - ls=$( ls -ld "$app_path" ) - link=${ls#*' -> '} - case $link in #( - /*) app_path=$link ;; #( - *) app_path=$APP_HOME$link ;; - esac -done - -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" -APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD=maximum - -warn () { - echo "$*" -} >&2 - -die () { - echo - echo "$*" - echo - exit 1 -} >&2 - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "$( uname )" in #( - CYGWIN* ) cygwin=true ;; #( - Darwin* ) darwin=true ;; #( - MSYS* | MINGW* ) msys=true ;; #( - NONSTOP* ) nonstop=true ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD=$JAVA_HOME/jre/sh/java - else - JAVACMD=$JAVA_HOME/bin/java - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then - case $MAX_FD in #( - max*) - MAX_FD=$( ulimit -H -n ) || - warn "Could not query maximum file descriptor limit" - esac - case $MAX_FD in #( - '' | soft) :;; #( - *) - ulimit -n "$MAX_FD" || - warn "Could not set maximum file descriptor limit to $MAX_FD" - esac -fi - -# Collect all arguments for the java command, stacking in reverse order: -# * args from the command line -# * the main class name -# * -classpath -# * -D...appname settings -# * --module-path (only if needed) -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. - -# For Cygwin or MSYS, switch paths to Windows format before running java -if "$cygwin" || "$msys" ; then - APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) - - JAVACMD=$( cygpath --unix "$JAVACMD" ) - - # Now convert the arguments - kludge to limit ourselves to /bin/sh - for arg do - if - case $arg in #( - -*) false ;; # don't mess with options #( - /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath - [ -e "$t" ] ;; #( - *) false ;; - esac - then - arg=$( cygpath --path --ignore --mixed "$arg" ) - fi - # Roll the args list around exactly as many times as the number of - # args, so each arg winds up back in the position where it started, but - # possibly modified. - # - # NB: a `for` loop captures its iteration list before it begins, so - # changing the positional parameters here affects neither the number of - # iterations, nor the values presented in `arg`. - shift # remove old arg - set -- "$@" "$arg" # push replacement arg - done -fi - -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. - -set -- \ - "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ - "$@" - -# Stop when "xargs" is not available. -if ! command -v xargs >/dev/null 2>&1 -then - die "xargs is not available" -fi - -# Use "xargs" to parse quoted args. -# -# With -n1 it outputs one arg per line, with the quotes and backslashes removed. -# -# In Bash we could simply go: -# -# readarray ARGS < <( xargs -n1 <<<"$var" ) && -# set -- "${ARGS[@]}" "$@" -# -# but POSIX shell has neither arrays nor command substitution, so instead we -# post-process each arg (as a line of input to sed) to backslash-escape any -# character that might be a shell metacharacter, then use eval to reverse -# that process (while maintaining the separation between arguments), and wrap -# the whole thing up as a single "set" statement. -# -# This will of course break if any of these variables contains a newline or -# an unmatched quote. -# - -eval "set -- $( - printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | - xargs -n1 | - sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | - tr '\n' ' ' - )" '"$@"' - -exec "$JAVACMD" "$@" diff --git a/benchmarks/ios/visual-effects-ny/gradlew.bat b/benchmarks/ios/visual-effects-ny/gradlew.bat deleted file mode 100644 index f127cfd49d..0000000000 --- a/benchmarks/ios/visual-effects-ny/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/benchmarks/ios/visual-effects-ny/iosApp/Configuration/Config.xcconfig b/benchmarks/ios/visual-effects-ny/iosApp/Configuration/Config.xcconfig deleted file mode 100644 index bad995c745..0000000000 --- a/benchmarks/ios/visual-effects-ny/iosApp/Configuration/Config.xcconfig +++ /dev/null @@ -1,3 +0,0 @@ -TEAM_ID= -BUNDLE_ID=org.jetbrains.VisualEffects -APP_NAME=VisualEffects diff --git a/benchmarks/ios/visual-effects-ny/iosApp/Podfile b/benchmarks/ios/visual-effects-ny/iosApp/Podfile deleted file mode 100644 index aff9c517b2..0000000000 --- a/benchmarks/ios/visual-effects-ny/iosApp/Podfile +++ /dev/null @@ -1,5 +0,0 @@ -target 'iosApp' do - use_frameworks! - platform :ios, '14.1' - pod 'shared', :path => '../shared' -end \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/iosApp/iosApp.xcodeproj/project.pbxproj b/benchmarks/ios/visual-effects-ny/iosApp/iosApp.xcodeproj/project.pbxproj deleted file mode 100644 index 0cea2ac59d..0000000000 --- a/benchmarks/ios/visual-effects-ny/iosApp/iosApp.xcodeproj/project.pbxproj +++ /dev/null @@ -1,418 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 50; - objects = { - -/* Begin PBXBuildFile section */ - 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; }; - 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; }; - 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; }; - 7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; }; - CFDB58B53BB94DE262B13C24 /* Pods_iosApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6B1049432C0C2B312090ABF6 /* Pods_iosApp.framework */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = ""; }; - 4FF3202A603A284706412EDC /* Pods-iosApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.debug.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.debug.xcconfig"; sourceTree = ""; }; - 6B1049432C0C2B312090ABF6 /* Pods_iosApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_iosApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 7555FF7B242A565900829871 /* iosApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iosApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 7555FF82242A565900829871 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; - 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - AB3632DC29227652001CCB65 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; }; - FF8CA3F5360CEAB49D74065F /* Pods-iosApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iosApp.release.xcconfig"; path = "Target Support Files/Pods-iosApp/Pods-iosApp.release.xcconfig"; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - F85CB1118929364A9C6EFABC /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - CFDB58B53BB94DE262B13C24 /* Pods_iosApp.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 058557D7273AAEEB004C7B11 /* Preview Content */ = { - isa = PBXGroup; - children = ( - 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - 42799AB246E5F90AF97AA0EF /* Frameworks */ = { - isa = PBXGroup; - children = ( - 6B1049432C0C2B312090ABF6 /* Pods_iosApp.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 7555FF72242A565900829871 = { - isa = PBXGroup; - children = ( - AB1DB47929225F7C00F7AF9C /* Configuration */, - 7555FF7D242A565900829871 /* iosApp */, - 7555FF7C242A565900829871 /* Products */, - FEFF387C0A8D172AA4D59CAE /* Pods */, - 42799AB246E5F90AF97AA0EF /* Frameworks */, - ); - sourceTree = ""; - }; - 7555FF7C242A565900829871 /* Products */ = { - isa = PBXGroup; - children = ( - 7555FF7B242A565900829871 /* iosApp.app */, - ); - name = Products; - sourceTree = ""; - }; - 7555FF7D242A565900829871 /* iosApp */ = { - isa = PBXGroup; - children = ( - 058557BA273AAA24004C7B11 /* Assets.xcassets */, - 7555FF82242A565900829871 /* ContentView.swift */, - 7555FF8C242A565B00829871 /* Info.plist */, - 2152FB032600AC8F00CF470E /* iOSApp.swift */, - 058557D7273AAEEB004C7B11 /* Preview Content */, - ); - path = iosApp; - sourceTree = ""; - }; - AB1DB47929225F7C00F7AF9C /* Configuration */ = { - isa = PBXGroup; - children = ( - AB3632DC29227652001CCB65 /* Config.xcconfig */, - ); - path = Configuration; - sourceTree = ""; - }; - FEFF387C0A8D172AA4D59CAE /* Pods */ = { - isa = PBXGroup; - children = ( - 4FF3202A603A284706412EDC /* Pods-iosApp.debug.xcconfig */, - FF8CA3F5360CEAB49D74065F /* Pods-iosApp.release.xcconfig */, - ); - path = Pods; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 7555FF7A242A565900829871 /* iosApp */ = { - isa = PBXNativeTarget; - buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */; - buildPhases = ( - 98D614C51D2DA07C614CC46E /* [CP] Check Pods Manifest.lock */, - 7555FF77242A565900829871 /* Sources */, - 7555FF79242A565900829871 /* Resources */, - F85CB1118929364A9C6EFABC /* Frameworks */, - 7694444BC13DD49B4B2626ED /* [CP] Copy Pods Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = iosApp; - productName = iosApp; - productReference = 7555FF7B242A565900829871 /* iosApp.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 7555FF73242A565900829871 /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 1130; - LastUpgradeCheck = 1130; - ORGANIZATIONNAME = orgName; - TargetAttributes = { - 7555FF7A242A565900829871 = { - CreatedOnToolsVersion = 11.3.1; - }; - }; - }; - buildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 7555FF72242A565900829871; - productRefGroup = 7555FF7C242A565900829871 /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 7555FF7A242A565900829871 /* iosApp */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 7555FF79242A565900829871 /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */, - 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 7694444BC13DD49B4B2626ED /* [CP] Copy Pods Resources */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-input-files.xcfilelist", - ); - name = "[CP] Copy Pods Resources"; - outputFileListPaths = ( - "${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources-${CONFIGURATION}-output-files.xcfilelist", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-iosApp/Pods-iosApp-resources.sh\"\n"; - showEnvVarsInLog = 0; - }; - 98D614C51D2DA07C614CC46E /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-iosApp-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 7555FF77242A565900829871 /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */, - 7555FF83242A565900829871 /* ContentView.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - 7555FFA3242A565B00829871 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 7555FFA4242A565B00829871 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 7555FFA6242A565B00829871 /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 4FF3202A603A284706412EDC /* Pods-iosApp.debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; - DEVELOPMENT_TEAM = "${TEAM_ID}"; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = iosApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; - PRODUCT_NAME = "${APP_NAME}"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 7555FFA7242A565B00829871 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = FF8CA3F5360CEAB49D74065F /* Pods-iosApp.release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; - DEVELOPMENT_TEAM = "${TEAM_ID}"; - ENABLE_PREVIEWS = YES; - INFOPLIST_FILE = iosApp/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.1; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; - PRODUCT_NAME = "${APP_NAME}"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7555FFA3242A565B00829871 /* Debug */, - 7555FFA4242A565B00829871 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 7555FFA6242A565B00829871 /* Debug */, - 7555FFA7242A565B00829871 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 7555FF73242A565900829871 /* Project object */; -} diff --git a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json b/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json deleted file mode 100644 index ee7e3ca03f..0000000000 --- a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "colors" : [ - { - "idiom" : "universal" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index fb88a396bf..0000000000 --- a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "20x20" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "20x20" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "29x29" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "29x29" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "40x40" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "40x40" - }, - { - "idiom" : "iphone", - "scale" : "2x", - "size" : "60x60" - }, - { - "idiom" : "iphone", - "scale" : "3x", - "size" : "60x60" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "20x20" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "20x20" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "29x29" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "29x29" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "40x40" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "40x40" - }, - { - "idiom" : "ipad", - "scale" : "1x", - "size" : "76x76" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "76x76" - }, - { - "idiom" : "ipad", - "scale" : "2x", - "size" : "83.5x83.5" - }, - { - "idiom" : "ios-marketing", - "scale" : "1x", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Assets.xcassets/Contents.json b/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Assets.xcassets/Contents.json deleted file mode 100644 index 4aa7c5350b..0000000000 --- a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/ContentView.swift b/benchmarks/ios/visual-effects-ny/iosApp/iosApp/ContentView.swift deleted file mode 100644 index f7f6457b31..0000000000 --- a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/ContentView.swift +++ /dev/null @@ -1,21 +0,0 @@ -import UIKit -import SwiftUI -import shared - -struct ComposeView: UIViewControllerRepresentable { - func makeUIViewController(context: Context) -> UIViewController { - Main_iosKt.MainViewController() - } - - func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} -} - -struct ContentView: View { - var body: some View { - ComposeView() - .ignoresSafeArea(.keyboard) // Compose has own keyboard handler - } -} - - - diff --git a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Info.plist b/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Info.plist deleted file mode 100644 index 9a269f5eaa..0000000000 --- a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Info.plist +++ /dev/null @@ -1,48 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - $(PRODUCT_BUNDLE_PACKAGE_TYPE) - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UIApplicationSceneManifest - - UIApplicationSupportsMultipleScenes - - - UILaunchScreen - - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json b/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json deleted file mode 100644 index 4aa7c5350b..0000000000 --- a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/iOSApp.swift b/benchmarks/ios/visual-effects-ny/iosApp/iosApp/iOSApp.swift deleted file mode 100644 index 0648e8602f..0000000000 --- a/benchmarks/ios/visual-effects-ny/iosApp/iosApp/iOSApp.swift +++ /dev/null @@ -1,10 +0,0 @@ -import SwiftUI - -@main -struct iOSApp: App { - var body: some Scene { - WindowGroup { - ContentView() - } - } -} \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/run-configurations.png b/benchmarks/ios/visual-effects-ny/run-configurations.png deleted file mode 100644 index d859ff0870..0000000000 Binary files a/benchmarks/ios/visual-effects-ny/run-configurations.png and /dev/null differ diff --git a/benchmarks/ios/visual-effects-ny/settings.gradle.kts b/benchmarks/ios/visual-effects-ny/settings.gradle.kts deleted file mode 100644 index 665c2f3deb..0000000000 --- a/benchmarks/ios/visual-effects-ny/settings.gradle.kts +++ /dev/null @@ -1,27 +0,0 @@ -pluginManagement { - repositories { - gradlePluginPortal() - maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") - google() - } - - plugins { - val kotlinVersion = extra["kotlin.version"] as String - val agpVersion = extra["agp.version"] as String - val composeVersion = extra["compose.version"] as String - - kotlin("jvm").version(kotlinVersion) - kotlin("multiplatform").version(kotlinVersion) - kotlin("android").version(kotlinVersion) - id("com.android.base").version(agpVersion) - id("com.android.application").version(agpVersion) - id("com.android.library").version(agpVersion) - id("org.jetbrains.compose").version(composeVersion) - } -} - -rootProject.name = "visual-effects" - -include(":androidApp") -include(":shared") -include(":desktopApp") diff --git a/benchmarks/ios/visual-effects-ny/shared/build.gradle.kts b/benchmarks/ios/visual-effects-ny/shared/build.gradle.kts deleted file mode 100644 index 48f2c79381..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/build.gradle.kts +++ /dev/null @@ -1,95 +0,0 @@ -plugins { - kotlin("multiplatform") - kotlin("native.cocoapods") - id("com.android.library") - id("org.jetbrains.compose") -} - -version = "1.0-SNAPSHOT" - -kotlin { - android() - - jvm("desktop") - - ios() - iosSimulatorArm64() - - macosX64 { - binaries { - executable { - entryPoint = "main" - } - } - } - macosArm64 { - binaries { - executable { - entryPoint = "main" - } - } - } - - cocoapods { - summary = "Shared code for the sample" - homepage = "https://github.com/JetBrains/compose-jb" - ios.deploymentTarget = "14.1" - podfile = project.file("../iosApp/Podfile") - framework { - baseName = "shared" - isStatic = true - } - extraSpecAttributes["resources"] = "['src/commonMain/resources/**', 'src/iosMain/resources/**']" - } - - sourceSets { - val commonMain by getting { - dependencies { - implementation(compose.runtime) - implementation(compose.foundation) - implementation(compose.material) - implementation(compose.materialIconsExtended) - @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) - implementation(compose.components.resources) - } - } - val androidMain by getting { - dependencies { - api("androidx.activity:activity-compose:1.6.1") - api("androidx.appcompat:appcompat:1.6.1") - api("androidx.core:core-ktx:1.9.0") - } - } - val iosMain by getting - val iosSimulatorArm64Main by getting { - dependsOn(iosMain) - } - val desktopMain by getting { - dependencies { - implementation(compose.desktop.common) - } - } - val macosMain by creating { - dependsOn(commonMain) - } - val macosArm64Main by getting { - dependsOn(macosMain) - } - } -} - -android { - compileSdk = 33 - sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") - sourceSets["main"].res.srcDirs("src/androidMain/res") - sourceSets["main"].resources.srcDirs("src/commonMain/resources") - - defaultConfig { - minSdk = 26 - targetSdk = 33 - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_11 - targetCompatibility = JavaVersion.VERSION_11 - } -} diff --git a/benchmarks/ios/visual-effects-ny/shared/src/androidMain/AndroidManifest.xml b/benchmarks/ios/visual-effects-ny/shared/src/androidMain/AndroidManifest.xml deleted file mode 100644 index 9382484a7e..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/src/androidMain/AndroidManifest.xml +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/shared/src/androidMain/kotlin/main.android.kt b/benchmarks/ios/visual-effects-ny/shared/src/androidMain/kotlin/main.android.kt deleted file mode 100644 index 41a4036628..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/src/androidMain/kotlin/main.android.kt +++ /dev/null @@ -1,10 +0,0 @@ -package org.jetbrains.compose.demo.visuals - -import androidx.compose.runtime.Composable -import org.jetbrains.compose.demo.visuals.NYContent - -actual fun width(): Int = 400 -actual fun height(): Int = 800 - -@Composable -fun MainView() = NYContent() \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/shared/src/androidMain/kotlin/platform/NanoTime.kt b/benchmarks/ios/visual-effects-ny/shared/src/androidMain/kotlin/platform/NanoTime.kt deleted file mode 100644 index 55e2b65c61..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/src/androidMain/kotlin/platform/NanoTime.kt +++ /dev/null @@ -1,9 +0,0 @@ -package org.jetbrains.compose.demo.visuals.platform - -import kotlin.system.exitProcess - -actual fun nanoTime(): Long = System.nanoTime() - -actual fun measureTime() = nanoTime() - -actual fun exit(): Unit = exitProcess(0) \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/shared/src/commonMain/kotlin/HappyNY.kt b/benchmarks/ios/visual-effects-ny/shared/src/commonMain/kotlin/HappyNY.kt deleted file mode 100644 index 5dde0cf85c..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/src/commonMain/kotlin/HappyNY.kt +++ /dev/null @@ -1,340 +0,0 @@ -package org.jetbrains.compose.demo.visuals - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Surface -import androidx.compose.runtime.* -import androidx.compose.runtime.snapshots.SnapshotStateList -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.* -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.dp -import kotlinx.coroutines.delay -import org.jetbrains.compose.demo.visuals.platform.exit -import org.jetbrains.compose.demo.visuals.platform.measureTime -import org.jetbrains.compose.demo.visuals.platform.nanoTime -import kotlin.math.* -import kotlin.random.Random - -expect fun width(): Int -expect fun height(): Int - -val width = width() -val height = height() -const val snowCount = 80 -const val starCount = 60 -const val rocketPartsCount = 30 - -data class SnowFlake( - var x: Dp, - var y: Dp, - val scale: Float, - var v: Double, - var alpha: Float, - var angle: Float, - var rotate: Int, - var phase: Double -) - -data class Star(val x: Dp, val y: Dp, val color: Color, val size: Dp) - -val random = Random(123) - -fun random(): Float = random.nextFloat() - -class DoubleRocket(val particle: Particle) { - private val STATE_ROCKET = 0 - private val STATE_SMALL_ROCKETS = 1 - var state = STATE_ROCKET - var rockets: Array = emptyArray() - private fun checkState(time: Long) { - if (particle.vy > -3.0 && state == STATE_ROCKET) { - explode(time) - } - if (state == STATE_SMALL_ROCKETS) { - var done = true - rockets.forEach { - if (!it.exploded) { - it.checkExplode(time) - } - if (!it.checkDone()) { - done = false - } - } - if (done) { - reset() - } - } - } - - var numOfIterations = 1 - - private fun reset() { - state = STATE_ROCKET - particle.x = 0.0 - particle.y = 1000.0 - particle.vx = 2.1 - particle.vy = -12.5 - numOfIterations -=1 - if (numOfIterations == 0) { - println((measureTime() - measureTime)/1000000) - exit() - } - - } - - private fun explode(time: Long) { - val colors = arrayOf(Color(0xff, 0, 0), Color(192, 255, 192), Color(192, 212, 255)) - rockets = Array(7) { - val v = 1.2f + 1.0 * random() - val angle = 2 * PI * random() - Rocket( - Particle( - particle.x, - particle.y, - v * sin(angle) + particle.vx, - v * cos(angle) + particle.vy - 0.5f, - colors[it % colors.size] - ), colors[it % colors.size], time - ) - } - state = STATE_SMALL_ROCKETS - } - - fun move(time: Long, prevTime: Long) { - if (rocket.state == rocket.STATE_ROCKET) { - rocket.particle.move(time, prevTime) - rocket.particle.gravity(time, prevTime) - } else { - rocket.rockets.forEach { - it.move(time, prevTime) - } - } - rocket.checkState(time) - } - - @Composable - fun draw() { - if (state == rocket.STATE_ROCKET) { - particle.draw() - } else { - rockets.forEach { - it.draw() - } - } - } - -} - -class Rocket(val particle: Particle, val color: Color, val startTime: Long = 0) { - var exploded = false - var parts: Array = emptyArray() - - fun checkExplode(time: Long) { - if (time - startTime > 1200000000) { - explode() - } - } - - private fun explode() { - parts = Array(rocketPartsCount) { - val v = 0.5f + 1.5 * random() - val angle = 2 * PI * random() - Particle(particle.x, particle.y, v * sin(angle) + particle.vx, v * cos(angle) + particle.vy, color, 1) - } - exploded = true - } - - fun checkDone(): Boolean { - if (!exploded) return false - parts.forEach { - if (it.y < 800) return false - } - return true - } - - fun move(time: Long, prevTime: Long) { - if (!exploded) { - particle.move(time, prevTime) - particle.gravity(time, prevTime) - checkExplode(time) - } else { - parts.forEach { - it.move(time, prevTime) - it.gravity(time, prevTime) - } - } - } - - @Composable - fun draw() { - if (!exploded) { - particle.draw() - } else { - parts.forEach { - it.draw() - } - } - } -} - -class Particle(var x: Double, var y: Double, var vx: Double, var vy: Double, val color: Color, val type: Int = 0) { - fun move(time: Long, prevTime: Long) { - x = (x + vx * (time - prevTime) / 30000000) - y = (y + vy * (time - prevTime) / 30000000) - } - - fun gravity(time: Long, prevTime: Long) { - vy = vy + 1.0f * (time - prevTime) / 300000000 - } - - @Composable - fun draw() { - val alphaFactor = if (type == 0) 1.0f else 1 / (1 + abs(vy / 5)).toFloat() - Box(Modifier.size(5.dp).offset(x.dp, y.dp).alpha(alphaFactor).clip(CircleShape).background(color)) - for (i in 1..5) { - Box( - Modifier.size(4.dp).offset((x - vx / 2 * i).dp, (y - vy / 2 * i).dp) - .alpha(alphaFactor * (1 - 0.18f * i)).clip(CircleShape).background(color) - ) - } - } -} - -val rocket = DoubleRocket(Particle(0.0, 1000.0, 2.1, -12.5, Color.White)) - -fun prepareStarsAndSnowFlakes(stars: SnapshotStateList, snowFlakes: SnapshotStateList) { - for (i in 0..snowCount) { - snowFlakes.add( - SnowFlake( - (50 + (width - 50) * random()).dp, - (height * random()).dp, - 0.1f + 0.2f * random().toFloat(), - 1.5 + 3 * random(), - (0.4f + 0.4 * random()).toFloat(), - 60 * random().toFloat(), - Random.nextInt(1, 5) - 3, - random() * 2 * PI - ) - ) - } - val colors = arrayOf(Color.Red, Color.Yellow, Color.Green, Color.Yellow, Color.Cyan, Color.Magenta, Color.White) - for (i in 0..starCount) { - stars.add( - Star( - (width * random()).dp, - (height * random()).dp, - colors[Random.nextInt(colors.size)], - (3 + 5 * random()).dp - ) - ) - } -} - -var measureTime: Long = 0 - -@Composable -fun NYContent() { - measureTime = measureTime() - var time by remember { mutableStateOf(nanoTime()) } - var startTime = remember { nanoTime() } - var prevTime by remember { mutableStateOf(nanoTime()) } - val snowFlakes = remember { mutableStateListOf() } - val stars = remember { mutableStateListOf() } - var flickering2 by remember { mutableStateOf(true) } - remember { prepareStarsAndSnowFlakes(stars, snowFlakes) } - - Surface( - modifier = Modifier.fillMaxSize().padding(5.dp).shadow(3.dp, RoundedCornerShape(20.dp)), - color = Color.Black, - shape = RoundedCornerShape(20.dp) - ) { - - LaunchedEffect(Unit) { - while (true) { - withFrameNanos { - prevTime = time - time = it - } - } - } - - if (flickering2) { - if (time - startTime > 15500000000) { //note, that startTime has been updated above - flickering2 = false - } - } - - rocket.move(time, prevTime) - - Box(Modifier.fillMaxSize()) { - - snow(time, prevTime, snowFlakes, startTime) - - starrySky(stars) - - rocket.draw() - - } - } -} - - -@Composable -fun starrySky(stars: SnapshotStateList) { - stars.forEach { - star(it.x, it.y, it.color, size = it.size) - } -} - -@Composable -fun star(x: Dp, y: Dp, color: Color = Color.White, size: Dp) { - Box(Modifier.offset(x, y).scale(1.0f, 0.2f).rotate(45f).size(size).background(color)) - Box(Modifier.offset(x, y).scale(0.2f, 1.0f).rotate(45f).size(size).background(color)) -} - -@Composable -fun snow(time: Long, prevTime: Long, snowFlakes: SnapshotStateList, startTime: Long) { - val deltaAngle = (time - startTime) / 100000000 - with(LocalDensity.current) { - snowFlakes.forEach { - var y = it.y + ((it.v * (time - prevTime)) / 300000000).dp - if (y > (height + 20).dp) { - y = -20.dp - } - it.y = y - val x = it.x + (15 * sin(time.toDouble() / 3000000000 + it.phase)).dp - snowFlake(Modifier.offset(x, y).scale(it.scale).rotate(it.angle + deltaAngle * it.rotate), it.alpha) - } - } -} - -@Composable -fun snowFlake(modifier: Modifier, alpha: Float = 0.8f) { - Box(modifier) { - snowFlakeInt(0, 0f, 30.dp, 0.dp, alpha) - snowFlakeInt(0, 60f, 15.dp, 25.dp, alpha) - snowFlakeInt(0, 120f, -15.dp, 25.dp, alpha) - snowFlakeInt(0, 180f, -30.dp, 0.dp, alpha) - snowFlakeInt(0, 240f, -15.dp, -25.dp, alpha) - snowFlakeInt(0, 300f, 15.dp, -25.dp, alpha) - } - -} - -@Composable -fun snowFlakeInt(level: Int, angle: Float, shiftX: Dp, shiftY: Dp, alpha: Float) { - if (level > 3) return - Box( - Modifier.offset(shiftX, shiftY).rotate(angle).width(100.dp).height(10.dp).scale(0.6f).alpha(1f) - .background(Color.White.copy(alpha = alpha)) - ) { - snowFlakeInt(level + 1, 30f, 12.dp, 20.dp, alpha * 0.8f) - snowFlakeInt(level + 1, -30f, 12.dp, -20.dp, alpha * 0.8f) - } -} - diff --git a/benchmarks/ios/visual-effects-ny/shared/src/commonMain/kotlin/platform/NanoTime.kt b/benchmarks/ios/visual-effects-ny/shared/src/commonMain/kotlin/platform/NanoTime.kt deleted file mode 100644 index 5383ad4dee..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/src/commonMain/kotlin/platform/NanoTime.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.jetbrains.compose.demo.visuals.platform - -expect fun nanoTime(): Long - -expect fun measureTime(): Long -expect fun exit(): Unit \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/shared/src/desktopMain/kotlin/main.desktop.kt b/benchmarks/ios/visual-effects-ny/shared/src/desktopMain/kotlin/main.desktop.kt deleted file mode 100644 index c7e7a05a1f..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/src/desktopMain/kotlin/main.desktop.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.jetbrains.compose.demo.visuals - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.* - -actual fun width(): Int = 640 -actual fun height(): Int = 480 - -@Composable -fun NYWindow(onCloseRequest: () -> Unit) { - val windowState = remember { WindowState(width = width.dp, height = height.dp) } - Window(onCloseRequest = onCloseRequest, undecorated = false, transparent = false, state = windowState) { - NYContent() - } -} - -fun mainNY() = application { - NYWindow(::exitApplication) -} - - diff --git a/benchmarks/ios/visual-effects-ny/shared/src/desktopMain/kotlin/platform/NanoTime.kt b/benchmarks/ios/visual-effects-ny/shared/src/desktopMain/kotlin/platform/NanoTime.kt deleted file mode 100644 index 6b4da718d7..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/src/desktopMain/kotlin/platform/NanoTime.kt +++ /dev/null @@ -1,8 +0,0 @@ -package org.jetbrains.compose.demo.visuals.platform - -import kotlin.system.exitProcess - -actual fun nanoTime(): Long = 0//System.nanoTime() - -actual fun measureTime() = System.nanoTime() -actual fun exit(): Unit = exitProcess(0) \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/shared/src/iosMain/kotlin/actuals.ios.kt b/benchmarks/ios/visual-effects-ny/shared/src/iosMain/kotlin/actuals.ios.kt deleted file mode 100644 index d7fb7142b6..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/src/iosMain/kotlin/actuals.ios.kt +++ /dev/null @@ -1,4 +0,0 @@ -package org.jetbrains.compose.demo.visuals - -actual fun width(): Int = 400 -actual fun height(): Int = 800 \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/shared/src/iosMain/kotlin/main.ios.kt b/benchmarks/ios/visual-effects-ny/shared/src/iosMain/kotlin/main.ios.kt deleted file mode 100644 index bcab5fa15a..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/src/iosMain/kotlin/main.ios.kt +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. - * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. - */ - -import androidx.compose.ui.window.ComposeUIViewController -import org.jetbrains.compose.demo.visuals.NYContent -import platform.UIKit.UIViewController - -fun MainViewController() : UIViewController = ComposeUIViewController { NYContent() } diff --git a/benchmarks/ios/visual-effects-ny/shared/src/iosMain/kotlin/platform/NanoTime.kt b/benchmarks/ios/visual-effects-ny/shared/src/iosMain/kotlin/platform/NanoTime.kt deleted file mode 100644 index 2044acd82d..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/src/iosMain/kotlin/platform/NanoTime.kt +++ /dev/null @@ -1,8 +0,0 @@ -package org.jetbrains.compose.demo.visuals.platform - -import kotlin.system.exitProcess - -actual fun nanoTime(): Long = kotlin.system.getTimeNanos() - -actual fun measureTime() = nanoTime() -actual fun exit(): Unit = exitProcess(0) \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/shared/src/macosMain/kotlin/actuals.macos.kt b/benchmarks/ios/visual-effects-ny/shared/src/macosMain/kotlin/actuals.macos.kt deleted file mode 100644 index 415f78bcf9..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/src/macosMain/kotlin/actuals.macos.kt +++ /dev/null @@ -1,4 +0,0 @@ -package org.jetbrains.compose.demo.visuals - -actual fun width(): Int = 640 -actual fun height(): Int = 480 \ No newline at end of file diff --git a/benchmarks/ios/visual-effects-ny/shared/src/macosMain/kotlin/main.macos.kt b/benchmarks/ios/visual-effects-ny/shared/src/macosMain/kotlin/main.macos.kt deleted file mode 100644 index 600bf5d8a3..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/src/macosMain/kotlin/main.macos.kt +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. - * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. - */ - -import androidx.compose.ui.window.Window -import androidx.compose.runtime.remember -import androidx.compose.ui.unit.dp -import org.jetbrains.compose.demo.visuals.NYContent -import platform.AppKit.NSApp -import platform.AppKit.NSApplication - -fun main() { - NSApplication.sharedApplication() - Window("Visual Effects") { - NYContent() - } - NSApp?.run() -} diff --git a/benchmarks/ios/visual-effects-ny/shared/src/macosMain/kotlin/platform/NanoTime.kt b/benchmarks/ios/visual-effects-ny/shared/src/macosMain/kotlin/platform/NanoTime.kt deleted file mode 100644 index 21a88b5512..0000000000 --- a/benchmarks/ios/visual-effects-ny/shared/src/macosMain/kotlin/platform/NanoTime.kt +++ /dev/null @@ -1,8 +0,0 @@ -package org.jetbrains.compose.demo.visuals.platform - -import kotlin.system.exitProcess - -actual fun nanoTime(): Long = 0;//kotlin.system.getTimeNanos() - -actual fun measureTime() = kotlin.system.getTimeNanos() -actual fun exit(): Unit = exitProcess(0) \ No newline at end of file diff --git a/benchmarks/kn-performance/.gitignore b/benchmarks/kn-performance/.gitignore deleted file mode 100644 index 239c7125d7..0000000000 --- a/benchmarks/kn-performance/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -local.properties -build -.gradle -.idea -.DS_Store diff --git a/benchmarks/kn-performance/README.md b/benchmarks/kn-performance/README.md index 523f2c1003..d3e6cb10dd 100644 --- a/benchmarks/kn-performance/README.md +++ b/benchmarks/kn-performance/README.md @@ -1,5 +1 @@ -# Compose benchmarks for K/N - -## Run native on MacOS - - `./gradlew runReleaseExecutableMacosArm64` (Works on Arm64 processors) - - `./gradlew runReleaseExecutableMacosX64` (Works on Intel processors) +### Moved to [multiplatform](https://github.com/JetBrains/compose-multiplatform/tree/master/benchmarks/multiplatform) \ No newline at end of file diff --git a/benchmarks/kn-performance/build.gradle.kts b/benchmarks/kn-performance/build.gradle.kts deleted file mode 100644 index 2b4f81ce91..0000000000 --- a/benchmarks/kn-performance/build.gradle.kts +++ /dev/null @@ -1,83 +0,0 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile - -plugins { - kotlin("multiplatform") - id("org.jetbrains.compose") -} - -version = "1.0-SNAPSHOT" - -repositories { - mavenLocal() - google() - mavenCentral() - maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") -} - -kotlin { - jvm("desktop") - macosX64 { - binaries { - executable { - entryPoint = "main" - freeCompilerArgs += listOf( - "-linker-option", "-framework", "-linker-option", "Metal" - ) - } - } - } - macosArm64 { - binaries { - executable { - entryPoint = "main" - freeCompilerArgs += listOf( - "-linker-option", "-framework", "-linker-option", "Metal" - ) - } - } - } - - sourceSets { - val commonMain by getting { - dependencies { - implementation(compose.ui) - implementation(compose.foundation) - implementation(compose.material) - implementation(compose.runtime) - @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) - implementation(compose.components.resources) - } - } - - val desktopMain by getting { - dependencies { - implementation(compose.desktop.currentOs) - runtimeOnly("org.jetbrains.kotlinx:kotlinx-coroutines-swing:1.7.1") - } - } - - val nativeMain by creating { - dependsOn(commonMain) - } - val macosMain by creating { - dependsOn(nativeMain) - } - val macosX64Main by getting { - dependsOn(macosMain) - } - val macosArm64Main by getting { - dependsOn(macosMain) - } - } -} - -compose.desktop { - application { - mainClass = "Main_desktopKt" - } -} - -tasks.withType { - kotlinOptions.jvmTarget = "11" -} - diff --git a/benchmarks/kn-performance/gradle/wrapper/gradle-wrapper.jar b/benchmarks/kn-performance/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index e708b1c023..0000000000 Binary files a/benchmarks/kn-performance/gradle/wrapper/gradle-wrapper.jar and /dev/null differ diff --git a/benchmarks/kn-performance/gradle/wrapper/gradle-wrapper.properties b/benchmarks/kn-performance/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index ae04661ee7..0000000000 --- a/benchmarks/kn-performance/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists diff --git a/benchmarks/kn-performance/gradlew b/benchmarks/kn-performance/gradlew deleted file mode 100755 index 4f906e0c81..0000000000 --- a/benchmarks/kn-performance/gradlew +++ /dev/null @@ -1,185 +0,0 @@ -#!/usr/bin/env sh - -# -# Copyright 2015 the original author or authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn () { - echo "$*" -} - -die () { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; -esac - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin or MSYS, switch paths to Windows format before running java -if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=`expr $i + 1` - done - case $i in - 0) set -- ;; - 1) set -- "$args0" ;; - 2) set -- "$args0" "$args1" ;; - 3) set -- "$args0" "$args1" "$args2" ;; - 4) set -- "$args0" "$args1" "$args2" "$args3" ;; - 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=`save "$@"` - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -exec "$JAVACMD" "$@" diff --git a/benchmarks/kn-performance/gradlew.bat b/benchmarks/kn-performance/gradlew.bat deleted file mode 100644 index f127cfd49d..0000000000 --- a/benchmarks/kn-performance/gradlew.bat +++ /dev/null @@ -1,91 +0,0 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/benchmarks/kn-performance/settings.gradle.kts b/benchmarks/kn-performance/settings.gradle.kts deleted file mode 100644 index b39db44fad..0000000000 --- a/benchmarks/kn-performance/settings.gradle.kts +++ /dev/null @@ -1,18 +0,0 @@ -pluginManagement { - repositories { - mavenLocal() - mavenCentral() - gradlePluginPortal() - maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") - google() - } - - plugins { - val kotlinVersion = extra["kotlin.version"] as String - kotlin("multiplatform").version(kotlinVersion) - val composeVersion = extra["compose.version"] as String - id("org.jetbrains.compose").version(composeVersion) - } -} - -rootProject.name = "compose-benchmarks" diff --git a/benchmarks/kn-performance/src/commonMain/kotlin/MeasureComposable.kt b/benchmarks/kn-performance/src/commonMain/kotlin/MeasureComposable.kt deleted file mode 100644 index f614668ea3..0000000000 --- a/benchmarks/kn-performance/src/commonMain/kotlin/MeasureComposable.kt +++ /dev/null @@ -1,76 +0,0 @@ -import androidx.compose.runtime.Composable -import androidx.compose.ui.ComposeScene -import androidx.compose.ui.unit.Constraints -import org.jetbrains.skia.DirectContext -import org.jetbrains.skia.Surface -import kotlin.time.Duration -import kotlin.time.Duration.Companion.nanoseconds -import kotlin.time.ExperimentalTime -import kotlin.time.measureTime -import kotlinx.coroutines.* - -const val nanosPerSecond = 1E9.toLong() -const val millisPerSecond = 1e3.toLong() -const val nanosPerMillisecond = nanosPerSecond / millisPerSecond - -interface GraphicsContext { - fun surface(width: Int, height: Int): Surface - - suspend fun awaitGPUCompletion() -} - -@OptIn(ExperimentalTime::class) -fun measureComposable( - frameCount: Int = 500, - width: Int, - height: Int, - targetFps: Int, - graphicsContext: GraphicsContext?, - content: @Composable () -> Unit -): BenchmarkResult = runBlocking { - val scene = ComposeScene() - try { - val nanosPerFrame = (1.0 / targetFps.toDouble() * nanosPerSecond).toLong() - scene.setContent(content) - scene.constraints = Constraints.fixed(width, height) - val surface = graphicsContext?.surface(width, height) ?: Surface.makeNull(width, height) - - val frames = MutableList(frameCount) { - BenchmarkFrame(Duration.INFINITE, Duration.INFINITE) - } - - var nanoTime = 0L - - repeat(frameCount) { - val frameTime = measureTime { - val cpuTime = measureTime { - scene.render(surface.canvas, nanoTime) - surface.flushAndSubmit(false) - } - - val gpuTime = measureTime { - graphicsContext?.awaitGPUCompletion() - } - - frames[it] = BenchmarkFrame(cpuTime, gpuTime) - } - - val actualNanosPerFrame = frameTime.inWholeNanoseconds - val nanosUntilDeadline = nanosPerFrame - actualNanosPerFrame - - // Emulate waiting for next vsync - if (nanosUntilDeadline > 0) { - delay(nanosUntilDeadline / nanosPerMillisecond) - } - - nanoTime += maxOf(actualNanosPerFrame, nanosPerFrame) - } - - BenchmarkResult( - nanosPerFrame.nanoseconds, - frames - ) - } finally { - scene.close() - } -} diff --git a/benchmarks/kn-performance/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt b/benchmarks/kn-performance/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt deleted file mode 100644 index ea3144ff18..0000000000 --- a/benchmarks/kn-performance/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt +++ /dev/null @@ -1,38 +0,0 @@ -package benchmarks.animation - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.material.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import kotlinx.coroutines.delay -import org.jetbrains.compose.resources.ExperimentalResourceApi -import org.jetbrains.compose.resources.painterResource - -@OptIn(ExperimentalResourceApi::class) -@Composable -fun AnimatedVisibility() { - MaterialTheme { - var showImage by remember { mutableStateOf(false) } - LaunchedEffect(showImage) { - delay(200) - showImage = !showImage - } - Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { - AnimatedVisibility(showImage) { - Image( - painterResource("compose-multiplatform.xml"), - null - ) - } - } - } -} \ No newline at end of file diff --git a/benchmarks/kn-performance/src/commonMain/kotlin/benchmarks/lazygrid/LazyGrid.kt b/benchmarks/kn-performance/src/commonMain/kotlin/benchmarks/lazygrid/LazyGrid.kt deleted file mode 100644 index 386630f9a0..0000000000 --- a/benchmarks/kn-performance/src/commonMain/kotlin/benchmarks/lazygrid/LazyGrid.kt +++ /dev/null @@ -1,106 +0,0 @@ -package benchmarks.lazygrid - -import androidx.compose.foundation.gestures.scrollBy -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.lazy.grid.GridCells -import androidx.compose.foundation.lazy.grid.LazyVerticalGrid -import androidx.compose.foundation.lazy.grid.items -import androidx.compose.foundation.lazy.grid.rememberLazyGridState -import androidx.compose.material.Card -import androidx.compose.material.Checkbox -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.runtime.withFrameMillis -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.dp - -@Composable -fun LazyGrid() { - val itemCount = 12000 - val entries = remember {List(itemCount) { Entry("$it") }} - val state = rememberLazyGridState() - - var smoothScroll by remember { mutableStateOf(false)} - - MaterialTheme { - Column { - Row { - Checkbox( - checked = smoothScroll, - onCheckedChange = { value -> smoothScroll = value} - ) - Text (text = "Smooth scroll", modifier = Modifier.align(Alignment.CenterVertically)) - } - - LazyVerticalGrid( - columns = GridCells.Fixed(4), - modifier = Modifier.fillMaxWidth().semantics { contentDescription = "IamLazy" }, - state = state - ) { - items(entries) { - ListCell(it) - } - } - } - - } - - var curItem by remember { mutableStateOf(0) } - var direct by remember { mutableStateOf(true) } - if (smoothScroll) { - LaunchedEffect(Unit) { - while (smoothScroll) { - withFrameMillis { } - curItem = state.firstVisibleItemIndex - if (curItem == 0) direct = true - if (curItem > itemCount - 100) direct = false - state.scrollBy(if (direct) 5f else -5f) - } - } - } else { - LaunchedEffect(curItem) { - withFrameMillis { } - curItem += if (direct) 50 else -50 - if (curItem >= itemCount) { - direct = false - curItem = itemCount - 1 - } else if (curItem <= 0) { - direct = true - curItem = 0 - } - state.scrollToItem(curItem) - } - } - -} - -data class Entry(val contents: String) - -@Composable -private fun ListCell(entry: Entry) { - Card( - modifier = Modifier - .fillMaxWidth() - .padding(8.dp) - ) { - Text( - text = entry.contents, - textAlign = TextAlign.Center, - style = MaterialTheme.typography.h5, - modifier = Modifier.padding(16.dp) - ) - } -} \ No newline at end of file diff --git a/benchmarks/kn-performance/src/commonMain/resources/compose-multiplatform.xml b/benchmarks/kn-performance/src/commonMain/resources/compose-multiplatform.xml deleted file mode 100644 index d7bf7955f4..0000000000 --- a/benchmarks/kn-performance/src/commonMain/resources/compose-multiplatform.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - diff --git a/benchmarks/ios/jvm-vs-kotlin-native/.gitignore b/benchmarks/multiplatform/.gitignore similarity index 100% rename from benchmarks/ios/jvm-vs-kotlin-native/.gitignore rename to benchmarks/multiplatform/.gitignore diff --git a/benchmarks/multiplatform/README.md b/benchmarks/multiplatform/README.md new file mode 100644 index 0000000000..f8c0e1a666 --- /dev/null +++ b/benchmarks/multiplatform/README.md @@ -0,0 +1,16 @@ +# Compose Multiplatform benchmarks + +## Run Desktop +- `./gradlew :run` + +## Run native on MacOS + - `./gradlew runReleaseExecutableMacosArm64` (Works on Arm64 processors) + - `./gradlew runReleaseExecutableMacosX64` (Works on Intel processors) + +## Run in web browser: + +Please run your browser with manual GC enabled before running the benchmark, like for Google Chrome: + +`open -a Google\ Chrome --args --js-flags="--expose-gc"` + +- `./gradlew wasmJsBrowserProductionRun` (you can see the results printed on the page itself) \ No newline at end of file diff --git a/benchmarks/ios/jvm-vs-kotlin-native/build.gradle.kts b/benchmarks/multiplatform/build.gradle.kts similarity index 64% rename from benchmarks/ios/jvm-vs-kotlin-native/build.gradle.kts rename to benchmarks/multiplatform/build.gradle.kts index 2b4f81ce91..46d0addb88 100644 --- a/benchmarks/ios/jvm-vs-kotlin-native/build.gradle.kts +++ b/benchmarks/multiplatform/build.gradle.kts @@ -1,7 +1,8 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpack plugins { kotlin("multiplatform") + id("org.jetbrains.kotlin.plugin.compose") id("org.jetbrains.compose") } @@ -20,9 +21,6 @@ kotlin { binaries { executable { entryPoint = "main" - freeCompilerArgs += listOf( - "-linker-option", "-framework", "-linker-option", "Metal" - ) } } } @@ -30,13 +28,15 @@ kotlin { binaries { executable { entryPoint = "main" - freeCompilerArgs += listOf( - "-linker-option", "-framework", "-linker-option", "Metal" - ) } } } + wasmJs { + binaries.executable() + browser () + } + sourceSets { val commonMain by getting { dependencies { @@ -77,7 +77,25 @@ compose.desktop { } } -tasks.withType { - kotlinOptions.jvmTarget = "11" -} +val runArguments: String? by project +// Handle runArguments property +gradle.taskGraph.whenReady { + tasks.named("run") { + args(runArguments?.split(" ") ?: listOf()) + } + tasks.forEach { t -> + if ((t is Exec) && t.name.startsWith("runReleaseExecutableMacos")) { + t.args(runArguments?.split(" ") ?: listOf()) + } + } + tasks.named("wasmJsBrowserProductionRun") { + val args = runArguments?.split(" ") + ?.mapIndexed { index, arg -> "arg$index=$arg" } + ?.joinToString("&") ?: "" + + devServerProperty = devServerProperty.get().copy( + open = "http://localhost:8080?$args" + ) + } +} diff --git a/benchmarks/kn-performance/gradle.properties b/benchmarks/multiplatform/gradle.properties similarity index 70% rename from benchmarks/kn-performance/gradle.properties rename to benchmarks/multiplatform/gradle.properties index 17ba8bd122..5e3743651a 100644 --- a/benchmarks/kn-performance/gradle.properties +++ b/benchmarks/multiplatform/gradle.properties @@ -1,10 +1,12 @@ -compose.version=1.5.10 -kotlin.version=1.9.20 +compose.version=1.7.1 +kotlin.version=2.1.0 org.gradle.jvmargs=-Xmx3g kotlin.native.useEmbeddableCompilerJar=true compose.desktop.verbose=true android.useAndroidX=true +runArguments=benchmarks= modes= kotlin.js.webpack.major.version=4 org.jetbrains.compose.experimental.jscanvas.enabled=true org.jetbrains.compose.experimental.macos.enabled=true org.jetbrains.compose.experimental.uikit.enabled=true +org.jetbrains.compose.resources.multimodule.disable=true diff --git a/benchmarks/ios/jvm-vs-kotlin-native/gradle/wrapper/gradle-wrapper.jar b/benchmarks/multiplatform/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from benchmarks/ios/jvm-vs-kotlin-native/gradle/wrapper/gradle-wrapper.jar rename to benchmarks/multiplatform/gradle/wrapper/gradle-wrapper.jar diff --git a/benchmarks/ios/animation-from-template/gradle/wrapper/gradle-wrapper.properties b/benchmarks/multiplatform/gradle/wrapper/gradle-wrapper.properties similarity index 91% rename from benchmarks/ios/animation-from-template/gradle/wrapper/gradle-wrapper.properties rename to benchmarks/multiplatform/gradle/wrapper/gradle-wrapper.properties index e1bef7e873..1e2fbf0d45 100644 --- a/benchmarks/ios/animation-from-template/gradle/wrapper/gradle-wrapper.properties +++ b/benchmarks/multiplatform/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/benchmarks/ios/jvm-vs-kotlin-native/gradlew b/benchmarks/multiplatform/gradlew similarity index 100% rename from benchmarks/ios/jvm-vs-kotlin-native/gradlew rename to benchmarks/multiplatform/gradlew diff --git a/benchmarks/ios/animation-from-template/gradlew.bat b/benchmarks/multiplatform/gradlew.bat similarity index 100% rename from benchmarks/ios/animation-from-template/gradlew.bat rename to benchmarks/multiplatform/gradlew.bat diff --git a/benchmarks/ios/jvm-vs-kotlin-native/settings.gradle.kts b/benchmarks/multiplatform/settings.gradle.kts similarity index 87% rename from benchmarks/ios/jvm-vs-kotlin-native/settings.gradle.kts rename to benchmarks/multiplatform/settings.gradle.kts index b39db44fad..5234bd02ca 100644 --- a/benchmarks/ios/jvm-vs-kotlin-native/settings.gradle.kts +++ b/benchmarks/multiplatform/settings.gradle.kts @@ -10,6 +10,7 @@ pluginManagement { plugins { val kotlinVersion = extra["kotlin.version"] as String kotlin("multiplatform").version(kotlinVersion) + id("org.jetbrains.kotlin.plugin.compose").version(kotlinVersion) val composeVersion = extra["compose.version"] as String id("org.jetbrains.compose").version(composeVersion) } diff --git a/benchmarks/ios/animation-from-template/shared/src/commonMain/resources/compose-multiplatform.xml b/benchmarks/multiplatform/src/commonMain/composeResources/drawable/compose-multiplatform.xml similarity index 100% rename from benchmarks/ios/animation-from-template/shared/src/commonMain/resources/compose-multiplatform.xml rename to benchmarks/multiplatform/src/commonMain/composeResources/drawable/compose-multiplatform.xml diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/Args.kt b/benchmarks/multiplatform/src/commonMain/kotlin/Args.kt new file mode 100644 index 0000000000..0748f96cba --- /dev/null +++ b/benchmarks/multiplatform/src/commonMain/kotlin/Args.kt @@ -0,0 +1,36 @@ +enum class Mode { + CPU, + FRAMES, + FRAMES_GPU +} + +object Args { + private val modes = mutableSetOf() + + private val benchmarks = mutableSetOf() + + private fun argToSet(arg: String): Set = arg.substring(arg.indexOf('=') + 1) + .split(",").filter{!it.isEmpty()}.map{it.uppercase()}.toSet() + + + /** + * Parses command line arguments to determine modes and benchmarks settings. + * + * @param args an array of strings representing the command line arguments. + * Each argument can specify either "modes" or "benchmarks" settings, + * with values separated by commas. + */ + fun parseArgs(args: Array) { + for (arg in args) { + if (arg.startsWith("modes=", ignoreCase = true)) { + modes.addAll(argToSet(arg).map { Mode.valueOf(it) }) + } else if (arg.startsWith("benchmarks=", ignoreCase = true)) { + benchmarks.addAll(argToSet(arg)) + } + } + } + + fun isModeEnabled(mode: Mode): Boolean = modes.isEmpty() || modes.contains(mode) + + fun isBenchmarkEnabled(benchmark: String): Boolean = benchmarks.isEmpty() || benchmarks.contains(benchmark.uppercase()) +} diff --git a/benchmarks/kn-performance/src/commonMain/kotlin/Benchmarks.kt b/benchmarks/multiplatform/src/commonMain/kotlin/Benchmarks.kt similarity index 76% rename from benchmarks/kn-performance/src/commonMain/kotlin/Benchmarks.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/Benchmarks.kt index cd2d006c3a..462998f360 100644 --- a/benchmarks/kn-performance/src/commonMain/kotlin/Benchmarks.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/Benchmarks.kt @@ -1,5 +1,6 @@ import androidx.compose.runtime.Composable import benchmarks.animation.AnimatedVisibility +import benchmarks.complexlazylist.components.MainUiNoImageUseModel import benchmarks.lazygrid.LazyGrid import benchmarks.visualeffects.NYContent import kotlin.math.roundToInt @@ -50,18 +51,30 @@ data class MissedFrames( data class BenchmarkStats( val frameBudget: Duration, + val frameCount: Int, + val renderTime: Duration, val percentileCPUAverage: List, val percentileGPUAverage: List, val noBufferingMissedFrames: MissedFrames, val doubleBufferingMissedFrames: MissedFrames ) { fun prettyPrint() { - percentileCPUAverage.prettyPrint(BenchmarkFrameTimeKind.CPU) - println() - percentileGPUAverage.prettyPrint(BenchmarkFrameTimeKind.GPU) - println() - noBufferingMissedFrames.prettyPrint("no buffering") - doubleBufferingMissedFrames.prettyPrint("double buffering") + if (Args.isModeEnabled(Mode.CPU)) { + println("$frameCount frames CPU render time: $renderTime") + println() + } + if (Args.isModeEnabled(Mode.FRAMES)) { + percentileCPUAverage.prettyPrint(BenchmarkFrameTimeKind.CPU) + println() + if (Args.isModeEnabled(Mode.FRAMES_GPU)) { + percentileGPUAverage.prettyPrint(BenchmarkFrameTimeKind.GPU) + println() + } + noBufferingMissedFrames.prettyPrint("no buffering") + if (Args.isModeEnabled(Mode.FRAMES_GPU)) { + doubleBufferingMissedFrames.prettyPrint("double buffering") + } + } } private fun List.prettyPrint(kind: BenchmarkFrameTimeKind) { @@ -73,6 +86,7 @@ data class BenchmarkStats( class BenchmarkResult( private val frameBudget: Duration, + private val renderTime: Duration, private val frames: List, ) { private fun percentileAverageFrameTime(percentile: Double, kind: BenchmarkFrameTimeKind): Duration { @@ -98,6 +112,8 @@ class BenchmarkResult( return BenchmarkStats( frameBudget, + frames.size, + renderTime, listOf(0.01, 0.02, 0.05, 0.1, 0.25, 0.5).map { percentile -> val average = percentileAverageFrameTime(percentile, BenchmarkFrameTimeKind.CPU) @@ -120,32 +136,34 @@ class BenchmarkResult( } -fun runBenchmark( +suspend fun runBenchmark( name: String, width: Int, height: Int, targetFps: Int, frameCount: Int, graphicsContext: GraphicsContext?, + warmupCount: Int = 100, content: @Composable () -> Unit -): BenchmarkStats { - val stats = measureComposable(frameCount, width, height, targetFps, graphicsContext, content).generateStats() - - println(name) - stats.prettyPrint() - println() - - return stats +) { + if (Args.isBenchmarkEnabled(name)) { + println("$name:") + val stats = measureComposable(warmupCount, frameCount, width, height, targetFps, graphicsContext, content).generateStats() + stats.prettyPrint() + } } -fun runBenchmarks( +suspend fun runBenchmarks( width: Int = 1920, height: Int = 1080, targetFps: Int = 120, graphicsContext: GraphicsContext? = null ) { + println() println("Running emulating $targetFps FPS") + println() runBenchmark("AnimatedVisibility", width, height, targetFps, 1000, graphicsContext) { AnimatedVisibility() } runBenchmark("LazyGrid", width, height, targetFps, 1000, graphicsContext) { LazyGrid() } runBenchmark("VisualEffects", width, height, targetFps, 1000, graphicsContext) { NYContent(width, height) } + runBenchmark("LazyList", width, height, targetFps, 1000, graphicsContext) { MainUiNoImageUseModel()} } \ No newline at end of file diff --git a/benchmarks/multiplatform/src/commonMain/kotlin/MeasureComposable.kt b/benchmarks/multiplatform/src/commonMain/kotlin/MeasureComposable.kt new file mode 100644 index 0000000000..409a8f772a --- /dev/null +++ b/benchmarks/multiplatform/src/commonMain/kotlin/MeasureComposable.kt @@ -0,0 +1,120 @@ +import androidx.compose.runtime.Composable +import androidx.compose.ui.InternalComposeUiApi +import androidx.compose.ui.graphics.asComposeCanvas +import androidx.compose.ui.scene.CanvasLayersComposeScene +import androidx.compose.ui.unit.IntSize +import org.jetbrains.skia.Surface +import kotlin.time.Duration +import kotlin.time.Duration.Companion.nanoseconds +import kotlin.time.ExperimentalTime +import kotlinx.coroutines.* +import kotlin.time.TimeSource.Monotonic.markNow +import kotlin.time.measureTime + +const val nanosPerSecond = 1E9.toLong() + +interface GraphicsContext { + fun surface(width: Int, height: Int): Surface + + suspend fun awaitGPUCompletion() +} + +expect fun runGC() + +suspend inline fun preciseDelay(duration: Duration) { + val liveDelay: Duration + if (duration.inWholeMilliseconds > 2) { + //experiments have shown that for precise delay we should do live delay at least 2 ms + val delayMillis = duration.inWholeMilliseconds - 2 + val delayStart = markNow() + delay(delayMillis) + liveDelay = duration - delayStart.elapsedNow() + } else { + liveDelay = duration + } + val liveDelayStart = markNow() + while (liveDelayStart.elapsedNow() < liveDelay){} +} + +@OptIn(ExperimentalTime::class, InternalComposeUiApi::class) +suspend fun measureComposable( + warmupCount: Int, + frameCount: Int, + width: Int, + height: Int, + targetFps: Int, + graphicsContext: GraphicsContext?, + content: @Composable () -> Unit +): BenchmarkResult { + val scene = CanvasLayersComposeScene(size = IntSize(width, height)) + try { + val nanosPerFrame = (1.0 / targetFps.toDouble() * nanosPerSecond).toLong() + scene.setContent(content) + val surface = graphicsContext?.surface(width, height) ?: Surface.makeNull(width, height) + val canvas = surface.canvas.asComposeCanvas() + + // warmup + repeat(warmupCount) { + scene.render(canvas, it * nanosPerFrame) + } + + runGC() + + var renderTime = Duration.ZERO + if (Args.isModeEnabled(Mode.CPU)) { + renderTime = measureTime { + repeat(frameCount) { + scene.render(canvas, it * nanosPerFrame) + } + } + } + + val frames = MutableList(frameCount) { + BenchmarkFrame(Duration.INFINITE, Duration.INFINITE) + } + + if (Args.isModeEnabled(Mode.FRAMES)) { + + var nextVSync = Duration.ZERO + var missedFrames = 0; + + runGC() + + val start = markNow() + + repeat(frameCount) { + val frameStart = start + nextVSync + + scene.render(canvas, nextVSync.inWholeNanoseconds) + surface.flushAndSubmit(false) + + val cpuTime = frameStart.elapsedNow() + + graphicsContext?.awaitGPUCompletion() + + val frameTime = frameStart.elapsedNow() + + frames[it] = BenchmarkFrame(cpuTime, frameTime - cpuTime) + + missedFrames += (frameTime.inWholeNanoseconds / nanosPerFrame).toInt() + + nextVSync = ((it + 1 + missedFrames) * nanosPerFrame).nanoseconds + + val timeUntilNextVSync = nextVSync - start.elapsedNow() + + if (timeUntilNextVSync > Duration.ZERO) { + // Emulate waiting for next vsync + preciseDelay(timeUntilNextVSync) + } + } + } + + return BenchmarkResult( + nanosPerFrame.nanoseconds, + renderTime, + frames + ) + } finally { + scene.close() + } +} diff --git a/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt similarity index 86% rename from benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt index ea3144ff18..29e13d2244 100644 --- a/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/animation/AnimatedVisibility.kt @@ -13,6 +13,8 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import compose_benchmarks.generated.resources.Res +import compose_benchmarks.generated.resources.compose_multiplatform import kotlinx.coroutines.delay import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.painterResource @@ -29,7 +31,7 @@ fun AnimatedVisibility() { Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { AnimatedVisibility(showImage) { Image( - painterResource("compose-multiplatform.xml"), + painterResource(Res.drawable.compose_multiplatform), null ) } diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/MainUI.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/MainUI.kt similarity index 81% rename from benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/MainUI.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/MainUI.kt index 1305cb0658..9b16c9ee65 100644 --- a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/MainUI.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/MainUI.kt @@ -1,26 +1,23 @@ -package listsample.components +package benchmarks.complexlazylist.components import androidx.compose.foundation.gestures.scrollBy import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material.MaterialTheme import androidx.compose.runtime.* -import listsample.components.refresh.* -import listsample.models.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import listsample.components.refresh.LOADING_MORE -import listsample.components.refresh.LoadingIndicatorDefault -import listsample.components.refresh.NORMAL -import listsample.components.refresh.REFRESHING -import listsample.components.refresh.SwipeRefreshLayout -import listsample.components.refresh.rememberSwipeRefreshState -import listsample.models.IBaseViewModel -import listsample.models.ICompositionModel -import listsample.models.fetchCompositionModels +import benchmarks.complexlazylist.components.refresh.LOADING_MORE +import benchmarks.complexlazylist.components.refresh.LoadingIndicatorDefault +import benchmarks.complexlazylist.components.refresh.NORMAL +import benchmarks.complexlazylist.components.refresh.REFRESHING +import benchmarks.complexlazylist.components.refresh.SwipeRefreshLayout +import benchmarks.complexlazylist.components.refresh.rememberSwipeRefreshState +import benchmarks.complexlazylist.models.IBaseViewModel +import benchmarks.complexlazylist.models.ICompositionModel +import benchmarks.complexlazylist.models.fetchCompositionModels // just for demo internal var models: MutableList = mutableStateListOf() diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/MultiLevelCell.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/MultiLevelCell.kt similarity index 98% rename from benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/MultiLevelCell.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/MultiLevelCell.kt index 228017f374..77ef62ce5e 100644 --- a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/MultiLevelCell.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/MultiLevelCell.kt @@ -1,4 +1,4 @@ -package listsample.components +package benchmarks.complexlazylist.components import androidx.compose.animation.core.animate import androidx.compose.animation.core.animateDpAsState @@ -27,9 +27,9 @@ import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp -import listsample.models.IBaseViewModel -import listsample.models.ICompositionItem -import listsample.models.ICompositionModel +import benchmarks.complexlazylist.models.IBaseViewModel +import benchmarks.complexlazylist.models.ICompositionItem +import benchmarks.complexlazylist.models.ICompositionModel import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/LoadingIndicator.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/LoadingIndicator.kt similarity index 99% rename from benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/LoadingIndicator.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/LoadingIndicator.kt index dca5d7c48c..359f4ea74f 100644 --- a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/LoadingIndicator.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/LoadingIndicator.kt @@ -1,4 +1,4 @@ -package listsample.components.refresh +package benchmarks.complexlazylist.components.refresh import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.core.LinearEasing diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/SwipeProgress.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeProgress.kt similarity index 85% rename from benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/SwipeProgress.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeProgress.kt index 28c8294a92..3c8e0486d8 100644 --- a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/SwipeProgress.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeProgress.kt @@ -1,4 +1,4 @@ -package listsample.components.refresh +package benchmarks.complexlazylist.components.refresh import androidx.compose.runtime.Immutable diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/SwipeRefreshLayout.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshLayout.kt similarity index 98% rename from benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/SwipeRefreshLayout.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshLayout.kt index e60c81525f..6d9142da34 100644 --- a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/SwipeRefreshLayout.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshLayout.kt @@ -1,4 +1,4 @@ -package listsample.components.refresh +package benchmarks.complexlazylist.components.refresh import androidx.compose.animation.core.animate import androidx.compose.animation.core.tween diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/SwipeRefreshNestedScrollConnection.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshNestedScrollConnection.kt similarity index 98% rename from benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/SwipeRefreshNestedScrollConnection.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshNestedScrollConnection.kt index f00b0858c1..9ce64478ad 100644 --- a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/SwipeRefreshNestedScrollConnection.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshNestedScrollConnection.kt @@ -1,4 +1,4 @@ -package listsample.components.refresh +package benchmarks.complexlazylist.components.refresh import androidx.compose.ui.geometry.Offset import androidx.compose.ui.input.nestedscroll.NestedScrollConnection diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/SwipeRefreshState.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshState.kt similarity index 97% rename from benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/SwipeRefreshState.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshState.kt index f4bb7fb24d..5194d64a57 100644 --- a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/components/refresh/SwipeRefreshState.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/components/refresh/SwipeRefreshState.kt @@ -1,4 +1,4 @@ -package listsample.components.refresh +package benchmarks.complexlazylist.components.refresh import androidx.compose.animation.core.Animatable import androidx.compose.foundation.MutatePriority diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/FollowItem.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/FollowItem.kt similarity index 92% rename from benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/FollowItem.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/FollowItem.kt index d159376d61..04949ab8f2 100644 --- a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/FollowItem.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/FollowItem.kt @@ -1,4 +1,4 @@ -package listsample.models +package benchmarks.complexlazylist.models class FollowItem() : IBaseViewModel { override val blockId: String? diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/HotItem.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/HotItem.kt similarity index 93% rename from benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/HotItem.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/HotItem.kt index 8eaeb98566..8c79eb0735 100644 --- a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/HotItem.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/HotItem.kt @@ -1,4 +1,4 @@ -package listsample.models +package benchmarks.complexlazylist.models class HotItem() : IBaseViewModel { override val blockId: String? diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/IBaseViewModel.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/IBaseViewModel.kt similarity index 84% rename from benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/IBaseViewModel.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/IBaseViewModel.kt index 3003eaecca..0c541f6be7 100644 --- a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/IBaseViewModel.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/IBaseViewModel.kt @@ -1,4 +1,4 @@ -package listsample.models +package benchmarks.complexlazylist.models interface IBaseViewModel { val blockId: String? diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/ICompositionModel.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/ICompositionModel.kt similarity index 92% rename from benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/ICompositionModel.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/ICompositionModel.kt index 7775fbab9c..004bb51a0f 100644 --- a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/ICompositionModel.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/ICompositionModel.kt @@ -1,4 +1,4 @@ -package listsample.models +package benchmarks.complexlazylist.models interface ICompositionItem { val bgColor: String? diff --git a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/ViewModelFactory.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/ViewModelFactory.kt similarity index 94% rename from benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/ViewModelFactory.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/ViewModelFactory.kt index fdeb70c779..d1fdc8b782 100644 --- a/benchmarks/ios/scroll-lazy-list/shared/src/commonMain/kotlin/listsample/models/ViewModelFactory.kt +++ b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/complexlazylist/models/ViewModelFactory.kt @@ -1,4 +1,4 @@ -package listsample.models +package benchmarks.complexlazylist.models val fakeItem2 = object : ICompositionItem { @@ -49,7 +49,7 @@ open class FakeItem : ICompositionModel { get() = TODO("Not yet implemented") } -expect fun createFakeItem(): ICompositionModel +fun createFakeItem(): ICompositionModel = FakeItem() internal fun fetchCompositionModels(useJSON: Boolean, callback: (List) -> Unit) { callback(List(250, { createFakeItem() })) diff --git a/benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/benchmarks/lazygrid/LazyGrid.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/lazygrid/LazyGrid.kt similarity index 100% rename from benchmarks/ios/jvm-vs-kotlin-native/src/commonMain/kotlin/benchmarks/lazygrid/LazyGrid.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/lazygrid/LazyGrid.kt diff --git a/benchmarks/kn-performance/src/commonMain/kotlin/benchmarks/visualeffects/HappyNY.kt b/benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/visualeffects/HappyNY.kt similarity index 100% rename from benchmarks/kn-performance/src/commonMain/kotlin/benchmarks/visualeffects/HappyNY.kt rename to benchmarks/multiplatform/src/commonMain/kotlin/benchmarks/visualeffects/HappyNY.kt diff --git a/benchmarks/kn-performance/src/desktopMain/kotlin/main.desktop.kt b/benchmarks/multiplatform/src/desktopMain/kotlin/main.desktop.kt similarity index 70% rename from benchmarks/kn-performance/src/desktopMain/kotlin/main.desktop.kt rename to benchmarks/multiplatform/src/desktopMain/kotlin/main.desktop.kt index 6d1367a1a8..4f23b4c7cb 100644 --- a/benchmarks/kn-performance/src/desktopMain/kotlin/main.desktop.kt +++ b/benchmarks/multiplatform/src/desktopMain/kotlin/main.desktop.kt @@ -6,4 +6,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.runBlocking -fun main() = runBlocking(Dispatchers.Main) { runBenchmarks() } +fun main(args: Array) { + Args.parseArgs(args) + runBlocking(Dispatchers.Main) { runBenchmarks() } +} diff --git a/benchmarks/multiplatform/src/desktopMain/kotlin/runGC.jvm.kt b/benchmarks/multiplatform/src/desktopMain/kotlin/runGC.jvm.kt new file mode 100644 index 0000000000..3095a116b1 --- /dev/null +++ b/benchmarks/multiplatform/src/desktopMain/kotlin/runGC.jvm.kt @@ -0,0 +1,3 @@ +actual fun runGC() { + System.gc() +} \ No newline at end of file diff --git a/benchmarks/kn-performance/src/macosMain/kotlin/main.macos.kt b/benchmarks/multiplatform/src/macosMain/kotlin/main.macos.kt similarity index 94% rename from benchmarks/kn-performance/src/macosMain/kotlin/main.macos.kt rename to benchmarks/multiplatform/src/macosMain/kotlin/main.macos.kt index 73adc79d6b..b2bae485b6 100644 --- a/benchmarks/kn-performance/src/macosMain/kotlin/main.macos.kt +++ b/benchmarks/multiplatform/src/macosMain/kotlin/main.macos.kt @@ -1,5 +1,6 @@ import kotlinx.cinterop.ExperimentalForeignApi import kotlinx.cinterop.objcPtr +import kotlinx.coroutines.runBlocking import org.jetbrains.skia.* import platform.Metal.* import kotlin.coroutines.resume @@ -11,7 +12,8 @@ import kotlin.coroutines.suspendCoroutine */ @OptIn(ExperimentalForeignApi::class) -fun main() { +fun main(args : Array) { + Args.parseArgs(args) val graphicsContext = object : GraphicsContext { private val device = MTLCreateSystemDefaultDevice() ?: throw IllegalStateException("Can't create MTLDevice") private val commandQueue = device.newCommandQueue() ?: throw IllegalStateException("Can't create MTLCommandQueue") @@ -62,5 +64,5 @@ fun main() { } } - runBenchmarks(graphicsContext = graphicsContext) + runBlocking { runBenchmarks(graphicsContext = graphicsContext)} } diff --git a/benchmarks/multiplatform/src/macosMain/kotlin/runGC.native.kt b/benchmarks/multiplatform/src/macosMain/kotlin/runGC.native.kt new file mode 100644 index 0000000000..7b499db732 --- /dev/null +++ b/benchmarks/multiplatform/src/macosMain/kotlin/runGC.native.kt @@ -0,0 +1,7 @@ +import kotlin.native.runtime.GC +import kotlin.native.runtime.NativeRuntimeApi + +@OptIn(NativeRuntimeApi::class) +actual fun runGC() { + GC.collect() +} \ No newline at end of file diff --git a/benchmarks/multiplatform/src/wasmJsMain/kotlin/main.wasmJs.kt b/benchmarks/multiplatform/src/wasmJsMain/kotlin/main.wasmJs.kt new file mode 100644 index 0000000000..d63956a992 --- /dev/null +++ b/benchmarks/multiplatform/src/wasmJsMain/kotlin/main.wasmJs.kt @@ -0,0 +1,15 @@ +import kotlinx.browser.window +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.launch +import org.w3c.dom.url.URLSearchParams + +fun main() { + val urlParams = URLSearchParams(window.location.search.toJsString()) + var i = 0 + val args = generateSequence { urlParams.get("arg${i++}") }.toList().toTypedArray() + Args.parseArgs(args) + MainScope().launch { + runBenchmarks() + println("Completed!") + } +} \ No newline at end of file diff --git a/benchmarks/multiplatform/src/wasmJsMain/kotlin/runGC.wasmJs.kt b/benchmarks/multiplatform/src/wasmJsMain/kotlin/runGC.wasmJs.kt new file mode 100644 index 0000000000..461e709899 --- /dev/null +++ b/benchmarks/multiplatform/src/wasmJsMain/kotlin/runGC.wasmJs.kt @@ -0,0 +1,3 @@ +actual fun runGC() { + js("(typeof gc === 'function')? gc() : console.log('Manual GC is not available. Ensure that the browser was started with the appropriate flags.')") +} \ No newline at end of file diff --git a/benchmarks/multiplatform/src/wasmJsMain/resources/index.html b/benchmarks/multiplatform/src/wasmJsMain/resources/index.html new file mode 100644 index 0000000000..4168e1755c --- /dev/null +++ b/benchmarks/multiplatform/src/wasmJsMain/resources/index.html @@ -0,0 +1,21 @@ + + + + + Benchmarks Compose + K/Wasm + + + + +Wait for the benchmarks to complete... + + \ No newline at end of file diff --git a/ci/compose-uber-jar/gradle.properties b/ci/compose-uber-jar/gradle.properties index f17262a0e2..d18de4daca 100644 --- a/ci/compose-uber-jar/gradle.properties +++ b/ci/compose-uber-jar/gradle.properties @@ -1,2 +1,2 @@ -compose.version=1.6.10 +compose.version=1.7.1 kotlin.code.style=official diff --git a/ci/compose-uber-jar/settings.gradle b/ci/compose-uber-jar/settings.gradle deleted file mode 100644 index bcd394b2a7..0000000000 --- a/ci/compose-uber-jar/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -rootProject.name = 'compose-uber-jar' - diff --git a/ci/compose-uber-jar/settings.gradle.kts b/ci/compose-uber-jar/settings.gradle.kts new file mode 100644 index 0000000000..b506af2507 --- /dev/null +++ b/ci/compose-uber-jar/settings.gradle.kts @@ -0,0 +1,2 @@ +rootProject.name = "compose-uber-jar" + diff --git a/ci/docker/compose-web/Dockerfile b/ci/docker/compose-web/Dockerfile index 8d3b338f56..06ea56de56 100644 --- a/ci/docker/compose-web/Dockerfile +++ b/ci/docker/compose-web/Dockerfile @@ -14,6 +14,10 @@ RUN dpkg --add-architecture i386 && apt-get update -yqq && apt-get install -y \ wget \ xvfb +RUN apt-get update -yqq \ + && wget -qO- https://deb.nodesource.com/gpgkey/nodesource.gpg.key \ + && wget -qO- https://deb.nodesource.com/setup_22.x | bash - \ + && apt-get install -y nodejs ARG CHROME_VERSION="google-chrome-stable" RUN wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - @@ -30,6 +34,3 @@ RUN wget https://github.com/mozilla/geckodriver/releases/download/v0.29.1/geckod RUN export CHROME_DRIVER_VERSION=$(wget -qO- https://chromedriver.storage.googleapis.com/LATEST_RELEASE) \ && wget https://chromedriver.storage.googleapis.com/${CHROME_DRIVER_VERSION}/chromedriver_linux64.zip -P ~/tmp \ && mkdir -p /root/.gradle/selenium/chrome && unzip -d /root/.gradle/selenium/chrome ~/tmp/chromedriver_linux64.zip && rm ~/tmp/chromedriver_linux64.zip - -COPY chrome-no-sandbox /usr/bin/chrome-no-sandbox -RUN chmod u+x /usr/bin/chrome-no-sandbox diff --git a/ci/docker/compose-web/chrome-no-sandbox b/ci/docker/compose-web/chrome-no-sandbox deleted file mode 100644 index e5eda7bacb..0000000000 --- a/ci/docker/compose-web/chrome-no-sandbox +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -google-chrome-stable --no-sandbox "$@" diff --git a/ci/templates/desktop-template/gradle.properties b/ci/templates/desktop-template/gradle.properties index 1b291c2c49..18925d8393 100644 --- a/ci/templates/desktop-template/gradle.properties +++ b/ci/templates/desktop-template/gradle.properties @@ -1,4 +1,4 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 kotlin.code.style=official -kotlin.version=2.0.0 -compose.version=1.6.10 +kotlin.version=2.0.20 +compose.version=1.7.1 diff --git a/ci/templates/html-library-template/gradle.properties b/ci/templates/html-library-template/gradle.properties index 1b291c2c49..18925d8393 100644 --- a/ci/templates/html-library-template/gradle.properties +++ b/ci/templates/html-library-template/gradle.properties @@ -1,4 +1,4 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 kotlin.code.style=official -kotlin.version=2.0.0 -compose.version=1.6.10 +kotlin.version=2.0.20 +compose.version=1.7.1 diff --git a/ci/templates/multiplatform-template/android/build.gradle.kts b/ci/templates/multiplatform-template/android/build.gradle.kts index 3b8151dac1..f3acdfa1cb 100644 --- a/ci/templates/multiplatform-template/android/build.gradle.kts +++ b/ci/templates/multiplatform-template/android/build.gradle.kts @@ -6,12 +6,12 @@ plugins { } android { - compileSdk = 34 + compileSdk = 35 namespace = "com.myapplication" defaultConfig { minSdk = 26 - targetSdk = 34 + targetSdk = 35 versionCode = 1 versionName = "1.0" } diff --git a/ci/templates/multiplatform-template/common/build.gradle.kts b/ci/templates/multiplatform-template/common/build.gradle.kts index 255c9058ef..3aa4081566 100644 --- a/ci/templates/multiplatform-template/common/build.gradle.kts +++ b/ci/templates/multiplatform-template/common/build.gradle.kts @@ -29,7 +29,7 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "com.myapplication.common" defaultConfig { diff --git a/ci/templates/multiplatform-template/gradle.properties b/ci/templates/multiplatform-template/gradle.properties index e50ea8deb0..c0dc424d4b 100644 --- a/ci/templates/multiplatform-template/gradle.properties +++ b/ci/templates/multiplatform-template/gradle.properties @@ -2,6 +2,6 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 android.useAndroidX=true android.enableJetifier=true kotlin.code.style=official -kotlin.version=2.0.0 -agp.version=8.0.2 -compose.version=1.6.10 +kotlin.version=2.0.20 +agp.version=8.1.0 +compose.version=1.7.1 diff --git a/components/gradle.properties b/components/gradle.properties index 478504a76f..79c1a9328e 100644 --- a/components/gradle.properties +++ b/components/gradle.properties @@ -7,9 +7,9 @@ org.gradle.configuration-cache=true android.useAndroidX=true #Versions -kotlin.version=1.9.23 +kotlin.version=1.9.24 agp.version=8.2.2 -compose.version=1.6.10 +compose.version=1.7.0 deploy.version=0.1.0-SNAPSHOT #Compose diff --git a/components/gradle/libs.versions.toml b/components/gradle/libs.versions.toml index 6ecd0569a6..bd1a087c30 100644 --- a/components/gradle/libs.versions.toml +++ b/components/gradle/libs.versions.toml @@ -3,7 +3,7 @@ kotlinx-coroutines = "1.8.0" androidx-appcompat = "1.6.1" androidx-activity-compose = "1.8.2" androidx-test = "1.5.0" -androidx-compose = "1.6.0" +androidx-compose = "1.6.1" [libraries] kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } @@ -11,6 +11,7 @@ kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-t androidx-appcompat = { module = "androidx.appcompat:appcompat", version.ref = "androidx-appcompat" } androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity-compose" } androidx-test-core = { module = "androidx.test:core", version.ref = "androidx-test" } +androidx-test-monitor = { module = "androidx.test:monitor", version.ref = "androidx-test" } androidx-compose-ui-test = { module = "androidx.compose.ui:ui-test", version.ref = "androidx-compose" } androidx-compose-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "androidx-compose" } androidx-compose-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "androidx-compose" } diff --git a/components/resources/demo/androidApp/build.gradle.kts b/components/resources/demo/androidApp/build.gradle.kts index bf0d6c00a0..7e2bee232d 100644 --- a/components/resources/demo/androidApp/build.gradle.kts +++ b/components/resources/demo/androidApp/build.gradle.kts @@ -5,12 +5,12 @@ plugins { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.compose.resources.demo" defaultConfig { applicationId = "me.user.androidApp" minSdk = 21 - targetSdk = 34 + targetSdk = 35 versionCode = 1 versionName = "1.0" } diff --git a/components/resources/demo/shared/build.gradle.kts b/components/resources/demo/shared/build.gradle.kts index 5dc1580b80..ec50b1e233 100644 --- a/components/resources/demo/shared/build.gradle.kts +++ b/components/resources/demo/shared/build.gradle.kts @@ -68,7 +68,7 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.compose.resources.demo.shared" defaultConfig { minSdk = 21 diff --git a/components/resources/demo/shared/src/commonMain/composeResources/drawable-dark/compose.png b/components/resources/demo/shared/src/commonMain/composeResources/drawable-dark/compose.png new file mode 100644 index 0000000000..36a746dc7d Binary files /dev/null and b/components/resources/demo/shared/src/commonMain/composeResources/drawable-dark/compose.png differ diff --git a/components/resources/demo/shared/src/commonMain/composeResources/font-dark/Workbench-Regular.ttf b/components/resources/demo/shared/src/commonMain/composeResources/font-dark/Workbench-Regular.ttf new file mode 100644 index 0000000000..2d116d9205 Binary files /dev/null and b/components/resources/demo/shared/src/commonMain/composeResources/font-dark/Workbench-Regular.ttf differ diff --git a/components/resources/demo/shared/src/commonMain/composeResources/font/NotoColorEmoji.ttf b/components/resources/demo/shared/src/commonMain/composeResources/font/NotoColorEmoji.ttf new file mode 100644 index 0000000000..9d82f52226 Binary files /dev/null and b/components/resources/demo/shared/src/commonMain/composeResources/font/NotoColorEmoji.ttf differ diff --git a/components/resources/demo/shared/src/wasmJsMain/kotlin/main.wasm.kt b/components/resources/demo/shared/src/wasmJsMain/kotlin/main.wasm.kt index 13e78a309a..99499383c2 100644 --- a/components/resources/demo/shared/src/wasmJsMain/kotlin/main.wasm.kt +++ b/components/resources/demo/shared/src/wasmJsMain/kotlin/main.wasm.kt @@ -1,15 +1,57 @@ -import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.CircularProgressIndicator +import androidx.compose.runtime.* +import androidx.compose.ui.* +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalFontFamilyResolver +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.window.CanvasBasedWindow +import components.resources.demo.shared.generated.resources.* +import components.resources.demo.shared.generated.resources.NotoColorEmoji +import components.resources.demo.shared.generated.resources.Res +import components.resources.demo.shared.generated.resources.Workbench_Regular +import components.resources.demo.shared.generated.resources.font_awesome +import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.configureWebResources import org.jetbrains.compose.resources.demo.shared.UseResources +import org.jetbrains.compose.resources.preloadFont -@OptIn(ExperimentalComposeUiApi::class) +@OptIn(ExperimentalComposeUiApi::class, ExperimentalResourceApi::class, InternalComposeUiApi::class) fun main() { configureWebResources { // Not necessary - It's the same as the default. We add it here just to present this feature. resourcePathMapping { path -> "./$path" } } CanvasBasedWindow("Resources demo + K/Wasm") { + val font1 by preloadFont(Res.font.Workbench_Regular) + val font2 by preloadFont(Res.font.font_awesome, FontWeight.Normal, FontStyle.Normal) + val emojiFont = preloadFont(Res.font.NotoColorEmoji).value + var fontsFallbackInitialiazed by remember { mutableStateOf(false) } + UseResources() + + if (font1 != null && font2 != null && emojiFont != null && fontsFallbackInitialiazed) { + println("Fonts are ready") + } else { + Box(modifier = Modifier.fillMaxSize().background(Color.White.copy(alpha = 0.8f)).clickable { }) { + CircularProgressIndicator(modifier = Modifier.align(Alignment.Center)) + } + println("Fonts are not ready yet") + } + + + val fontFamilyResolver = LocalFontFamilyResolver.current + LaunchedEffect(fontFamilyResolver, emojiFont) { + if (emojiFont != null) { + // we have an emoji on Strings tab + fontFamilyResolver.preload(FontFamily(listOf(emojiFont))) + fontsFallbackInitialiazed = true + } + } } } \ No newline at end of file diff --git a/components/resources/library/build.gradle.kts b/components/resources/library/build.gradle.kts index c53dcba642..68c2b48fcc 100644 --- a/components/resources/library/build.gradle.kts +++ b/components/resources/library/build.gradle.kts @@ -113,6 +113,10 @@ kotlin { } val androidMain by getting { dependsOn(jvmAndAndroidMain) + dependencies { + //it will be called only in android instrumented tests where the library should be available + compileOnly(libs.androidx.test.monitor) + } } val androidInstrumentedTest by getting { dependsOn(jvmAndAndroidTest) @@ -156,7 +160,7 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.compose.components.resources" defaultConfig { minSdk = 21 diff --git a/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/AndroidContextProvider.kt b/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/AndroidContextProvider.kt index df9cc46c4c..fafb548b84 100644 --- a/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/AndroidContextProvider.kt +++ b/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/AndroidContextProvider.kt @@ -10,8 +10,10 @@ import android.net.Uri import androidx.compose.runtime.Composable import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalInspectionMode +import androidx.test.platform.app.InstrumentationRegistry internal val androidContext get() = AndroidContextProvider.ANDROID_CONTEXT +internal val androidInstrumentedContext get() = InstrumentationRegistry.getInstrumentation().context /** * The function configures the android context diff --git a/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ImageResources.android.kt b/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ImageResources.android.kt index 0e411ce719..fa8d7c8824 100644 --- a/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ImageResources.android.kt +++ b/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ImageResources.android.kt @@ -6,8 +6,17 @@ import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.unit.Density -internal actual fun ByteArray.toImageBitmap(): ImageBitmap = - BitmapFactory.decodeByteArray(this, 0, size).asImageBitmap() +internal actual fun ByteArray.toImageBitmap(resourceDensity: Int, targetDensity: Int): ImageBitmap { + val options = BitmapFactory.Options().apply { + //https://youtrack.jetbrains.com/issue/CMP-5657 + //android only downscales drawables. If there is only low dpi resource then use it as is (not upscale) + if (resourceDensity > targetDensity) { + inDensity = resourceDensity + inTargetDensity = targetDensity + } + } + return BitmapFactory.decodeByteArray(this, 0, size, options).asImageBitmap() +} internal actual class SvgElement diff --git a/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ResourceReader.android.kt b/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ResourceReader.android.kt index d8e5741966..c58ab133e2 100644 --- a/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ResourceReader.android.kt +++ b/components/resources/library/src/androidMain/kotlin/org/jetbrains/compose/resources/ResourceReader.android.kt @@ -2,6 +2,7 @@ package org.jetbrains.compose.resources import android.content.res.AssetManager import android.net.Uri +import android.util.Log import androidx.compose.runtime.Composable import androidx.compose.runtime.ProvidableCompositionLocal import java.io.FileNotFoundException @@ -16,6 +17,14 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou context.assets } + private val instrumentedAssets: AssetManager? + get() = try { + androidInstrumentedContext.assets + } catch (e: NoClassDefFoundError) { + Log.d("ResourceReader", "Android Instrumentation context is not available.") + null + } + override suspend fun read(path: String): ByteArray { val resource = getResourceAsStream(path) return resource.use { input -> input.readBytes() } @@ -52,7 +61,7 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou } override fun getUri(path: String): String { - val uri = if (assets.hasFile(path)) { + val uri = if (assets.hasFile(path) || instrumentedAssets.hasFile(path)) { Uri.parse("file:///android_asset/$path") } else { val classLoader = getClassLoader() @@ -66,8 +75,12 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou return try { assets.open(path) } catch (e: FileNotFoundException) { - val classLoader = getClassLoader() - classLoader.getResourceAsStream(path) ?: throw MissingResourceException(path) + try { + instrumentedAssets.open(path) + } catch (e: FileNotFoundException) { + val classLoader = getClassLoader() + classLoader.getResourceAsStream(path) ?: throw MissingResourceException(path) + } } } @@ -75,7 +88,7 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou return this.javaClass.classLoader ?: error("Cannot find class loader") } - private fun AssetManager.hasFile(path: String): Boolean { + private fun AssetManager?.hasFile(path: String): Boolean { var inputStream: InputStream? = null val result = try { inputStream = open(path) @@ -87,6 +100,9 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou } return result } + + private fun AssetManager?.open(path: String): InputStream = + this?.open(path) ?: throw FileNotFoundException("Current AssetManager is null.") } internal actual val ProvidableCompositionLocal.currentOrPreview: ResourceReader diff --git a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ImageDecoders.kt b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ImageDecoders.kt new file mode 100644 index 0000000000..b393c1e912 --- /dev/null +++ b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ImageDecoders.kt @@ -0,0 +1,31 @@ +package org.jetbrains.compose.resources + +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.unit.Density +import org.jetbrains.compose.resources.vector.toImageVector + +/** + * Decodes a byte array of a Bitmap to an ImageBitmap. Supports JPEG, PNG, BMP, WEBP + * + * Different platforms can support additional formats. + * + * @return The converted ImageBitmap. + */ +@ExperimentalResourceApi +fun ByteArray.decodeToImageBitmap(): ImageBitmap { + val dumbDensity = 0 //any equal source and target density disable scaling here + return this.toImageBitmap(dumbDensity, dumbDensity) +} + +/** + * Decodes a byte array of a vector XML file to an ImageVector. + * + * @param density density to apply during converting the source units to the [ImageVector] units. + * + * @return The converted ImageVector. + */ +@ExperimentalResourceApi +fun ByteArray.decodeToImageVector(density: Density): ImageVector { + return this.toXmlElement().toImageVector(density) +} diff --git a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ImageResources.kt b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ImageResources.kt index 30892cf43f..d938d302af 100644 --- a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ImageResources.kt +++ b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ImageResources.kt @@ -47,6 +47,9 @@ fun painterResource(resource: DrawableResource): Painter { private val emptyImageBitmap: ImageBitmap by lazy { ImageBitmap(1, 1) } +internal val ImageBitmap.isEmptyPlaceholder: Boolean + get() = this == emptyImageBitmap + /** * Retrieves an ImageBitmap using the specified drawable resource. * @@ -56,10 +59,17 @@ private val emptyImageBitmap: ImageBitmap by lazy { ImageBitmap(1, 1) } @Composable fun imageResource(resource: DrawableResource): ImageBitmap { val resourceReader = LocalResourceReader.currentOrPreview - val imageBitmap by rememberResourceState(resource, resourceReader, { emptyImageBitmap }) { env -> - val path = resource.getResourceItemByEnvironment(env).path - val cached = loadImage(path, resourceReader) { - ImageCache.Bitmap(it.toImageBitmap()) + val resourceEnvironment = rememberResourceEnvironment() + val imageBitmap by rememberResourceState( + resource, resourceReader, resourceEnvironment, { emptyImageBitmap } + ) { env -> + val item = resource.getResourceItemByEnvironment(env) + val resourceDensityQualifier = item.qualifiers.firstOrNull { it is DensityQualifier } as? DensityQualifier + val resourceDensity = resourceDensityQualifier?.dpi ?: DensityQualifier.MDPI.dpi + val screenDensity = resourceEnvironment.density.dpi + val path = item.path + val cached = loadImage(path, "$path-${screenDensity}dpi", resourceReader) { + ImageCache.Bitmap(it.toImageBitmap(resourceDensity, screenDensity)) } as ImageCache.Bitmap cached.bitmap } @@ -70,6 +80,9 @@ private val emptyImageVector: ImageVector by lazy { ImageVector.Builder("emptyImageVector", 1.dp, 1.dp, 1f, 1f).build() } +internal val ImageVector.isEmptyPlaceholder: Boolean + get() = this == emptyImageVector + /** * Retrieves an ImageVector using the specified drawable resource. * @@ -82,7 +95,7 @@ fun vectorResource(resource: DrawableResource): ImageVector { val density = LocalDensity.current val imageVector by rememberResourceState(resource, resourceReader, density, { emptyImageVector }) { env -> val path = resource.getResourceItemByEnvironment(env).path - val cached = loadImage(path, resourceReader) { + val cached = loadImage(path, path, resourceReader) { ImageCache.Vector(it.toXmlElement().toImageVector(density)) } as ImageCache.Vector cached.vector @@ -102,7 +115,7 @@ private fun svgPainter(resource: DrawableResource): Painter { val density = LocalDensity.current val svgPainter by rememberResourceState(resource, resourceReader, density, { emptySvgPainter }) { env -> val path = resource.getResourceItemByEnvironment(env).path - val cached = loadImage(path, resourceReader) { + val cached = loadImage(path, path, resourceReader) { ImageCache.Svg(it.toSvgElement().toSvgPainter(density)) } as ImageCache.Svg cached.painter @@ -126,7 +139,7 @@ suspend fun getDrawableResourceBytes( return DefaultResourceReader.read(resourceItem.path) } -internal expect fun ByteArray.toImageBitmap(): ImageBitmap +internal expect fun ByteArray.toImageBitmap(resourceDensity: Int, targetDensity: Int): ImageBitmap internal expect fun ByteArray.toXmlElement(): Element internal expect fun ByteArray.toSvgElement(): SvgElement @@ -145,6 +158,7 @@ internal fun dropImageCache() { private suspend fun loadImage( path: String, + cacheKey: String, resourceReader: ResourceReader, decode: (ByteArray) -> ImageCache -): ImageCache = imageCache.getOrLoad(path) { decode(resourceReader.read(path)) } +): ImageCache = imageCache.getOrLoad(cacheKey) { decode(resourceReader.read(path)) } diff --git a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/vector/XmlVectorParser.kt b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/vector/XmlVectorParser.kt index ff17801580..ed4631ef18 100644 --- a/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/vector/XmlVectorParser.kt +++ b/components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/vector/XmlVectorParser.kt @@ -75,7 +75,8 @@ internal fun Element.toImageVector(density: Density): ImageVector { defaultWidth = attributeOrNull(ANDROID_NS, "width").parseDp(density), defaultHeight = attributeOrNull(ANDROID_NS, "height").parseDp(density), viewportWidth = attributeOrNull(ANDROID_NS, "viewportWidth")?.toFloat() ?: 0f, - viewportHeight = attributeOrNull(ANDROID_NS, "viewportHeight")?.toFloat() ?: 0f + viewportHeight = attributeOrNull(ANDROID_NS, "viewportHeight")?.toFloat() ?: 0f, + autoMirror = attributeOrNull(ANDROID_NS, "autoMirrored") == "true" ) parseVectorNodes(builder, context) return builder.build() diff --git a/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/ComposeResourceTest.kt b/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/ComposeResourceTest.kt index bc7c7ddb85..0cc4b8651a 100644 --- a/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/ComposeResourceTest.kt +++ b/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/ComposeResourceTest.kt @@ -366,4 +366,49 @@ class ComposeResourceTest { val systemEnvironment = getSystemResourceEnvironment() assertEquals(systemEnvironment, environment) } + + @Test + fun rememberResourceStateAffectedByEnvironmentChanges() = runComposeUiTest { + val env2 = ResourceEnvironment( + language = LanguageQualifier("en"), + region = RegionQualifier("CA"), + theme = ThemeQualifier.DARK, + density = DensityQualifier.MDPI + ) + + val envState = mutableStateOf(TestComposeEnvironment) + var lastEnv1: ResourceEnvironment? = null + var lastEnv2: ResourceEnvironment? = null + var lastEnv3: ResourceEnvironment? = null + + setContent { + CompositionLocalProvider(LocalComposeEnvironment provides envState.value) { + rememberResourceState(1, { "" }) { + lastEnv1 = it + } + rememberResourceState(1, 2, { "" }) { + lastEnv2 = it + } + rememberResourceState(1, 2, 3, { "" }) { + lastEnv3 = it + } + } + } + + assertNotEquals(null, lastEnv1) + assertNotEquals(env2, lastEnv1) + assertEquals(lastEnv1, lastEnv2) + assertEquals(lastEnv2, lastEnv3) + + val testEnv2 = object : ComposeEnvironment { + @Composable + override fun rememberEnvironment() = env2 + } + envState.value = testEnv2 + waitForIdle() + + assertEquals(env2, lastEnv1) + assertEquals(env2, lastEnv2) + assertEquals(env2, lastEnv3) + } } diff --git a/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/vector/XmlVectorParserTest.kt b/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/vector/XmlVectorParserTest.kt new file mode 100644 index 0000000000..78ca14db22 --- /dev/null +++ b/components/resources/library/src/commonTest/kotlin/org/jetbrains/compose/resources/vector/XmlVectorParserTest.kt @@ -0,0 +1,55 @@ +package org.jetbrains.compose.resources.vector + +import androidx.compose.ui.unit.Density +import androidx.compose.ui.unit.dp +import org.jetbrains.compose.resources.decodeToImageVector +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +class XmlVectorParserTest { + + + private val arrowVector1 = """ + + + + """.trimIndent().encodeToByteArray() + + private val arrowVector2 = """ + + + + """.trimIndent().encodeToByteArray() + + @Test + fun canDecodeToImageVector() { + val iv = arrowVector1.decodeToImageVector(Density(1f)) + assertEquals(iv.viewportWidth, 32f) + assertEquals(iv.viewportHeight, 32f) + assertEquals(iv.defaultWidth, 32.dp) + assertEquals(iv.defaultHeight, 32.dp) + assertTrue(iv.autoMirror) + + val iv2 = arrowVector2.decodeToImageVector(Density(1f)) + assertEquals(iv2.viewportWidth, 36f) + assertEquals(iv2.viewportHeight, 24f) + assertEquals(iv2.defaultWidth, 40.dp) + assertEquals(iv2.defaultHeight, 30.dp) + assertFalse(iv2.autoMirror) + } +} \ No newline at end of file diff --git a/components/resources/library/src/desktopMain/kotlin/org/jetbrains/compose/resources/ResourceReader.desktop.kt b/components/resources/library/src/desktopMain/kotlin/org/jetbrains/compose/resources/ResourceReader.desktop.kt index f90b9d516c..c5285a17b7 100644 --- a/components/resources/library/src/desktopMain/kotlin/org/jetbrains/compose/resources/ResourceReader.desktop.kt +++ b/components/resources/library/src/desktopMain/kotlin/org/jetbrains/compose/resources/ResourceReader.desktop.kt @@ -1,5 +1,7 @@ package org.jetbrains.compose.resources +import java.io.EOFException +import java.io.IOException import java.io.InputStream internal actual fun getPlatformResourceReader(): ResourceReader = object : ResourceReader { @@ -12,12 +14,22 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou val resource = getResourceAsStream(path) val result = ByteArray(size.toInt()) resource.use { input -> - input.skipNBytes(offset) + input.skipBytes(offset) input.readNBytes(result, 0, size.toInt()) } return result } + //skipNBytes requires API 12 + private fun InputStream.skipBytes(offset: Long) { + var skippedBytes = 0L + while (skippedBytes < offset) { + val count = skip(offset - skippedBytes) + if (count == 0L) break + skippedBytes += count + } + } + override fun getUri(path: String): String { val classLoader = getClassLoader() val resource = classLoader.getResource(path) ?: throw MissingResourceException(path) diff --git a/components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.ios.kt b/components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.ios.kt index 0da7725bc3..5629c5bf2d 100644 --- a/components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.ios.kt +++ b/components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.ios.kt @@ -1,10 +1,29 @@ package org.jetbrains.compose.resources +import kotlinx.cinterop.BetaInteropApi +import kotlinx.cinterop.ObjCObjectVar import kotlinx.cinterop.addressOf +import kotlinx.cinterop.alloc +import kotlinx.cinterop.memScoped +import kotlinx.cinterop.ptr import kotlinx.cinterop.usePinned -import platform.Foundation.* +import kotlinx.cinterop.value +import org.jetbrains.skiko.OS +import org.jetbrains.skiko.OSVersion +import org.jetbrains.skiko.available +import platform.Foundation.NSBundle +import platform.Foundation.NSData +import platform.Foundation.NSError +import platform.Foundation.NSFileHandle +import platform.Foundation.NSFileManager +import platform.Foundation.NSURL +import platform.Foundation.closeFile +import platform.Foundation.fileHandleForReadingAtPath +import platform.Foundation.readDataOfLength +import platform.Foundation.seekToFileOffset import platform.posix.memcpy +@OptIn(BetaInteropApi::class) internal actual fun getPlatformResourceReader(): ResourceReader = object : ResourceReader { override suspend fun read(path: String): ByteArray { val data = readData(getPathInBundle(path)) @@ -30,7 +49,15 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou private fun readData(path: String, offset: Long, size: Long): NSData { val fileHandle = NSFileHandle.fileHandleForReadingAtPath(path) ?: throw MissingResourceException(path) - fileHandle.seekToOffset(offset.toULong(), null) + if (available(OS.Ios to OSVersion(major = 13))) { + memScoped { + val error = alloc>() + fileHandle.seekToOffset(offset.toULong(), error.ptr) + error.value?.let { err -> error(err.localizedDescription) } + } + } else { + fileHandle.seekToFileOffset(offset.toULong()) + } val result = fileHandle.readDataOfLength(size.toULong()) fileHandle.closeFile() return result diff --git a/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.macos.kt b/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.macos.kt index 83404652ee..55c6d6b032 100644 --- a/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.macos.kt +++ b/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceEnvironment.macos.kt @@ -7,7 +7,12 @@ import platform.CoreGraphics.CGDisplayScreenSize import platform.Foundation.* internal actual fun getSystemEnvironment(): ResourceEnvironment { - val locale = NSLocale.currentLocale() + val locale = NSLocale.preferredLanguages.firstOrNull() + ?.let { NSLocale(it as String) } + ?: NSLocale.currentLocale + + val languageCode = locale.languageCode + val regionCode = locale.objectForKey(NSLocaleCountryCode) as? String val isDarkTheme = NSUserDefaults.standardUserDefaults.stringForKey("AppleInterfaceStyle") == "Dark" val dpi = NSScreen.mainScreen?.let { screen -> @@ -24,8 +29,8 @@ internal actual fun getSystemEnvironment(): ResourceEnvironment { } ?: 0 return ResourceEnvironment( - language = LanguageQualifier(locale.languageCode), - region = RegionQualifier(locale.regionCode.orEmpty()), + language = LanguageQualifier(languageCode), + region = RegionQualifier(regionCode.orEmpty()), theme = ThemeQualifier.selectByValue(isDarkTheme), density = DensityQualifier.selectByValue(dpi) ) diff --git a/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.macos.kt b/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.macos.kt index 4b042d1108..61ddd3aa9a 100644 --- a/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.macos.kt +++ b/components/resources/library/src/macosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.macos.kt @@ -39,12 +39,32 @@ internal actual fun getPlatformResourceReader(): ResourceReader = object : Resou private fun getPathOnDisk(path: String): String { val fm = NSFileManager.defaultManager() val currentDirectoryPath = fm.currentDirectoryPath + val pathFix = getPathWithoutPackage(path) return listOf( + // Framework binary + // todo: support fallback path at bundle root? + NSBundle.mainBundle.resourcePath + "/compose-resources/" + path, + // Executable binary //todo in future bundle resources with app and use all sourceSets (skikoMain, nativeMain) - "$currentDirectoryPath/src/macosMain/composeResources/$path", - "$currentDirectoryPath/src/macosTest/composeResources/$path", - "$currentDirectoryPath/src/commonMain/composeResources/$path", - "$currentDirectoryPath/src/commonTest/composeResources/$path" + "$currentDirectoryPath/src/macosMain/composeResources/$pathFix", + "$currentDirectoryPath/src/macosTest/composeResources/$pathFix", + "$currentDirectoryPath/src/commonMain/composeResources/$pathFix", + "$currentDirectoryPath/src/commonTest/composeResources/$pathFix" ).firstOrNull { p -> fm.fileExistsAtPath(p) } ?: throw MissingResourceException(path) } + + private fun getPathWithoutPackage(path: String): String { + // At the moment resources are not bundled when running a macOS executable binary. + // As a workaround, load the resources from the actual path on disk. So the + // "composeResources/PACKAGE/" prefix must be removed. For example: + // "composeResources/chat_mpp.shared.generated.resources/drawable/background.jpg" + // Will be transformed into: + // "drawable/background.jpg" + // In the future when resources are bundled when running macOS executable binary this + // workaround is no longer needed. + require(path.startsWith("composeResources/")) { "Invalid path: $path" } + return path + .substringAfter("composeResources/") // remove "composeResources/" part + .substringAfter("/") // remove PACKAGE path + } } \ No newline at end of file diff --git a/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/FontResources.skiko.kt b/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/FontResources.skiko.kt index c5e9e1682e..6d697ae253 100644 --- a/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/FontResources.skiko.kt +++ b/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/FontResources.skiko.kt @@ -29,13 +29,20 @@ private val emptyFontBase64 = @OptIn(ExperimentalEncodingApi::class) private val defaultEmptyFont by lazy { Font("org.jetbrains.compose.emptyFont", Base64.decode(emptyFontBase64)) } +private val fontCache = AsyncCache() +internal val Font.isEmptyPlaceholder: Boolean + get() = this == defaultEmptyFont + @Composable actual fun Font(resource: FontResource, weight: FontWeight, style: FontStyle): Font { val resourceReader = LocalResourceReader.currentOrPreview val fontFile by rememberResourceState(resource, weight, style, { defaultEmptyFont }) { env -> val path = resource.getResourceItemByEnvironment(env).path - val fontBytes = resourceReader.read(path) - Font(path, fontBytes, weight, style) + val key = "$path:$weight:$style" + fontCache.getOrLoad(key) { + val fontBytes = resourceReader.read(path) + Font(path, fontBytes, weight, style) + } } return fontFile } \ No newline at end of file diff --git a/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/ImageDecoders.skiko.kt b/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/ImageDecoders.skiko.kt new file mode 100644 index 0000000000..fe5e92eab7 --- /dev/null +++ b/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/ImageDecoders.skiko.kt @@ -0,0 +1,17 @@ +package org.jetbrains.compose.resources + +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.unit.Density + +/** + * Decodes a byte array of an SVG file to a compose Painter. + * + * @param density density to apply during converting the source units to the [Painter] units. + * + * @return The converted Painter. + */ +@ExperimentalResourceApi +fun ByteArray.decodeToSvgPainter(density: Density): Painter { + return this.toSvgElement().toSvgPainter(density) +} \ No newline at end of file diff --git a/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/ImageResources.skiko.kt b/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/ImageResources.skiko.kt index a046534554..3ac9eefc10 100644 --- a/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/ImageResources.skiko.kt +++ b/components/resources/library/src/skikoMain/kotlin/org/jetbrains/compose/resources/ImageResources.skiko.kt @@ -6,10 +6,37 @@ import androidx.compose.ui.graphics.toComposeImageBitmap import androidx.compose.ui.unit.Density import org.jetbrains.skia.Data import org.jetbrains.skia.Image +import org.jetbrains.skia.Paint +import org.jetbrains.skia.Rect +import org.jetbrains.skia.SamplingMode +import org.jetbrains.skia.Surface import org.jetbrains.skia.svg.SVGDOM -internal actual fun ByteArray.toImageBitmap(): ImageBitmap = - Image.makeFromEncoded(this).toComposeImageBitmap() +internal actual fun ByteArray.toImageBitmap(resourceDensity: Int, targetDensity: Int): ImageBitmap { + val image = Image.makeFromEncoded(this) + + val targetImage: Image + //https://youtrack.jetbrains.com/issue/CMP-5657 + //android only downscales drawables. If there is only low dpi resource then use it as is (not upscale) + //we need a consistent behavior on all platforms + if (resourceDensity > targetDensity) { + val scale = targetDensity.toFloat() / resourceDensity.toFloat() + val targetH = image.height * scale + val targetW = image.width * scale + val srcRect = Rect.Companion.makeWH(image.width.toFloat(), image.height.toFloat()) + val dstRect = Rect.Companion.makeWH(targetW, targetH) + + targetImage = Surface.makeRasterN32Premul(targetW.toInt(), targetH.toInt()).run { + val paint = Paint().apply { isAntiAlias = true } + canvas.drawImageRect(image, srcRect, dstRect, SamplingMode.LINEAR, paint, true) + makeImageSnapshot() + } + } else { + targetImage = image + } + + return targetImage.toComposeImageBitmap() +} internal actual class SvgElement(val svgdom: SVGDOM) diff --git a/components/resources/library/src/webMain/kotlin/org/jetbrains/compose/resources/Resource.web.kt b/components/resources/library/src/webMain/kotlin/org/jetbrains/compose/resources/Resource.web.kt index aa44111987..ee9416da3d 100644 --- a/components/resources/library/src/webMain/kotlin/org/jetbrains/compose/resources/Resource.web.kt +++ b/components/resources/library/src/webMain/kotlin/org/jetbrains/compose/resources/Resource.web.kt @@ -1,5 +1,12 @@ package org.jetbrains.compose.resources +import androidx.compose.runtime.* +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.text.font.Font +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight + /** * Represents the configuration object for web resources. * @@ -50,4 +57,138 @@ internal fun getResourceUrl(windowOrigin: String, windowPathname: String, resour path.startsWith("http://") || path.startsWith("https://") -> path else -> windowOrigin + windowPathname + path } +} + +/** + * Preloads a font resource and provides a [State] containing the loaded [Font] or `null` if not yet loaded. + * + * Internally, it reads font bytes, converts them to a [Font] object, and caches the result, speeding up future + * accesses to the same font resource when using @Composable Font function. + * + * **Usage Example:** + * ``` + * @Composable + * fun MyApp() { + * val fontState by preloadFont(Res.font.HeavyFont) + * + * if (fontState != null) { + * MyText() + * } else { + * Box(modifier = Modifier.fillMaxSize()) { + * CircularProgressIndicator(modifier = Modifier.align(Alignment.Center)) + * } + * } + * } + * + * @Composable + * fun MyText() { + * // the font is taken from the cache + * Text(text = "Hello, World!", fontFamily = FontFamily(Font(Res.font.HeavyFont))) + * } + * ``` + * + * @param resource The font resource to be used. + * @param weight The weight of the font. Default value is [FontWeight.Normal]. + * @param style The style of the font. Default value is [FontStyle.Normal]. + * @return A [State]<[Font]?> object that holds the loaded [Font] when available, + * or `null` if the font is not yet ready. + */ +@ExperimentalResourceApi +@Composable +fun preloadFont( + resource: FontResource, + weight: FontWeight = FontWeight.Normal, + style: FontStyle = FontStyle.Normal +): State { + val resState = remember(resource, weight, style) { mutableStateOf(null) }.apply { + value = Font(resource, weight, style).takeIf { !it.isEmptyPlaceholder } + } + return resState +} + +/** + * Preloads an image resource and provides a [State] containing the loaded [ImageBitmap] or `null` if not yet loaded. + * + * Internally, it reads the resource bytes, converts them to a [ImageBitmap] object, and caches the result, + * speeding up future accesses to the same resource when using @Composable [imageResource] or [painterResource] functions. + * + * **Usage Example:** + * ``` + * @Composable + * fun MyApp() { + * val imageState by preloadImageBitmap(Res.drawable.heavy_drawable) + * + * if (imageState != null) { + * MyImage() + * } else { + * Box(modifier = Modifier.fillMaxSize()) { + * CircularProgressIndicator(modifier = Modifier.align(Alignment.Center)) + * } + * } + * } + * + * @Composable + * fun MyImage() { + * // the image is taken from the cache thanks to preloadImageBitmap + * Image(painter = painterResource(Res.drawable.heavy_drawable), contentDescription = null) + * } + * ``` + * + * @param resource The resource to be used. + * @return A [State]<[ImageBitmap]?> object that holds the loaded [ImageBitmap] when available, + * or `null` if the resource is not yet ready. + */ +@ExperimentalResourceApi +@Composable +fun preloadImageBitmap( + resource: DrawableResource, +): State { + val resState = remember(resource) { mutableStateOf(null) }.apply { + value = imageResource(resource).takeIf { !it.isEmptyPlaceholder } + } + return resState +} + + +/** + * Preloads a vector image resource and provides a [State] containing the loaded [ImageVector] or `null` if not yet loaded. + * + * Internally, it reads the resource bytes, converts them to a [ImageVector] object, and caches the result, + * speeding up future accesses to the same resource when using @Composable [vectorResource] or [painterResource] functions. + * + * **Usage Example:** + * ``` + * @Composable + * fun MyApp() { + * val iconState by preloadImageVector(Res.drawable.heavy_vector_icon) + * + * if (iconState != null) { + * MyIcon() + * } else { + * Box(modifier = Modifier.fillMaxSize()) { + * CircularProgressIndicator(modifier = Modifier.align(Alignment.Center)) + * } + * } + * } + * + * @Composable + * fun MyIcon() { + * // the icon is taken from the cache thanks to preloadImageVector + * Image(painter = painterResource(Res.drawable.heavy_vector_icon), contentDescription = null) + * } + * ``` + * + * @param resource The resource to be used. + * @return A [State]<[ImageVector]?> object that holds the loaded [ImageVector] when available, + * or `null` if the resource is not yet ready. + */ +@ExperimentalResourceApi +@Composable +fun preloadImageVector( + resource: DrawableResource, +): State { + val resState = remember(resource) { mutableStateOf(null) }.apply { + value = vectorResource(resource).takeIf { !it.isEmptyPlaceholder } + } + return resState } \ No newline at end of file diff --git a/components/resources/library/src/webMain/kotlin/org/jetbrains/compose/resources/ResourceState.web.kt b/components/resources/library/src/webMain/kotlin/org/jetbrains/compose/resources/ResourceState.web.kt index 3ef99c9a73..9386783106 100644 --- a/components/resources/library/src/webMain/kotlin/org/jetbrains/compose/resources/ResourceState.web.kt +++ b/components/resources/library/src/webMain/kotlin/org/jetbrains/compose/resources/ResourceState.web.kt @@ -16,7 +16,7 @@ internal actual fun rememberResourceState( ): State { val environment = LocalComposeEnvironment.current.rememberEnvironment() val scope = rememberCoroutineScope() - return remember(key1) { + return remember(key1, environment) { val mutableState = mutableStateOf(getDefault()) scope.launch(start = CoroutineStart.UNDISPATCHED) { mutableState.value = block(environment) @@ -34,7 +34,7 @@ internal actual fun rememberResourceState( ): State { val environment = LocalComposeEnvironment.current.rememberEnvironment() val scope = rememberCoroutineScope() - return remember(key1, key2) { + return remember(key1, key2, environment) { val mutableState = mutableStateOf(getDefault()) scope.launch(start = CoroutineStart.UNDISPATCHED) { mutableState.value = block(environment) @@ -53,7 +53,7 @@ internal actual fun rememberResourceState( ): State { val environment = LocalComposeEnvironment.current.rememberEnvironment() val scope = rememberCoroutineScope() - return remember(key1, key2, key3) { + return remember(key1, key2, key3, environment) { val mutableState = mutableStateOf(getDefault()) scope.launch(start = CoroutineStart.UNDISPATCHED) { mutableState.value = block(environment) diff --git a/components/resources/library/src/webTest/kotlin/org/jetbrains/compose/resources/TestResourcePreloading.kt b/components/resources/library/src/webTest/kotlin/org/jetbrains/compose/resources/TestResourcePreloading.kt new file mode 100644 index 0000000000..3d481d8a60 --- /dev/null +++ b/components/resources/library/src/webTest/kotlin/org/jetbrains/compose/resources/TestResourcePreloading.kt @@ -0,0 +1,76 @@ +package org.jetbrains.compose.resources + +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.test.ExperimentalTestApi +import androidx.compose.ui.test.runComposeUiTest +import androidx.compose.ui.text.font.Font +import kotlinx.coroutines.CancellableContinuation +import kotlinx.coroutines.suspendCancellableCoroutine +import kotlin.io.encoding.Base64 +import kotlin.io.encoding.ExperimentalEncodingApi +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals + +@OptIn(ExperimentalTestApi::class, ExperimentalEncodingApi::class) +class TestResourcePreloading { + + @Test + fun testPreloadFont() = runComposeUiTest { + var loadContinuation: CancellableContinuation? = null + + val resLoader = object : ResourceReader { + override suspend fun read(path: String): ByteArray { + return suspendCancellableCoroutine { + loadContinuation = it + } + } + + override suspend fun readPart(path: String, offset: Long, size: Long): ByteArray { + TODO("Not yet implemented") + } + + override fun getUri(path: String): String { + TODO("Not yet implemented") + } + } + + var font: Font? = null + var font2: Font? = null + var condition by mutableStateOf(false) + + + setContent { + CompositionLocalProvider( + LocalComposeEnvironment provides TestComposeEnvironment, + LocalResourceReader provides resLoader + ) { + font = preloadFont(TestFontResource("sometestfont")).value + + if (condition) { + font2 = Font(TestFontResource("sometestfont")) + } + } + } + waitForIdle() + assertEquals(null, font) + assertEquals(null, font2) + + assertNotEquals(null, loadContinuation) + loadContinuation!!.resumeWith(Result.success(ByteArray(0))) + loadContinuation = null + + waitForIdle() + assertNotEquals(null, font) + assertEquals(null, font2) // condition was false for now, so font2 should be not initialized + + condition = true + waitForIdle() + assertNotEquals(null, font) + assertEquals(font, font2, "font2 is expected to be loaded from cache") + assertEquals(null, loadContinuation, "expected no more ResourceReader usages") + } +} \ No newline at end of file diff --git a/components/ui-tooling-preview/demo/shared/build.gradle.kts b/components/ui-tooling-preview/demo/shared/build.gradle.kts index 754457c4b0..a029b500ad 100644 --- a/components/ui-tooling-preview/demo/shared/build.gradle.kts +++ b/components/ui-tooling-preview/demo/shared/build.gradle.kts @@ -57,7 +57,7 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.compose.ui.tooling.preview.demo.shared" defaultConfig { minSdk = 21 diff --git a/components/ui-tooling-preview/library/build.gradle.kts b/components/ui-tooling-preview/library/build.gradle.kts index 1007eadc3b..3aa2dca631 100644 --- a/components/ui-tooling-preview/library/build.gradle.kts +++ b/components/ui-tooling-preview/library/build.gradle.kts @@ -34,7 +34,7 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.compose.ui.tooling.preview" defaultConfig { minSdk = 21 diff --git a/compose/integrations/composable-test-cases/gradle.properties b/compose/integrations/composable-test-cases/gradle.properties index cd327007ea..5e94def572 100644 --- a/compose/integrations/composable-test-cases/gradle.properties +++ b/compose/integrations/composable-test-cases/gradle.properties @@ -13,7 +13,7 @@ kotlinx.coroutines.version=1.8.0 #empty by default - a default version will be used #compose.kotlinCompilerPluginVersion=23.12.18 -compose.kotlinCompilerPluginVersion=1.5.13.3 +compose.kotlinCompilerPluginVersion=1.5.14.1 # default|failingJs - see enum class CasesToRun tests.casesToRun=default diff --git a/examples/chat/androidApp/build.gradle.kts b/examples/chat/androidApp/build.gradle.kts index a7edbd975e..d2a0c56653 100644 --- a/examples/chat/androidApp/build.gradle.kts +++ b/examples/chat/androidApp/build.gradle.kts @@ -17,12 +17,12 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.chat" defaultConfig { applicationId = "org.jetbrains.Chat" minSdk = 26 - targetSdk = 34 + targetSdk = 35 versionCode = 1 versionName = "1.0" } diff --git a/examples/chat/gradle.properties b/examples/chat/gradle.properties index e7adc12149..f0830f4e66 100644 --- a/examples/chat/gradle.properties +++ b/examples/chat/gradle.properties @@ -10,6 +10,6 @@ kotlin.native.useEmbeddableCompilerJar=true kotlin.mpp.androidSourceSetLayoutVersion=2 # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=2.0.0 -agp.version=8.0.2 -compose.version=1.6.10 +kotlin.version=2.0.20 +agp.version=8.5.0 +compose.version=1.7.1 diff --git a/examples/chat/gradle/wrapper/gradle-wrapper.properties b/examples/chat/gradle/wrapper/gradle-wrapper.properties index 17655d0ef2..1fc96abf2b 100644 --- a/examples/chat/gradle/wrapper/gradle-wrapper.properties +++ b/examples/chat/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ +#Thu Oct 17 19:55:35 AMT 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/examples/chat/iosApp/iosApp/Info.plist b/examples/chat/iosApp/iosApp/Info.plist index 9a269f5eaa..412e378128 100644 --- a/examples/chat/iosApp/iosApp/Info.plist +++ b/examples/chat/iosApp/iosApp/Info.plist @@ -20,6 +20,8 @@ 1 LSRequiresIPhoneOS + CADisableMinimumFrameDurationOnPhone + UIApplicationSceneManifest UIApplicationSupportsMultipleScenes diff --git a/examples/chat/shared/build.gradle.kts b/examples/chat/shared/build.gradle.kts index a54ffe5228..c37c93f1d2 100644 --- a/examples/chat/shared/build.gradle.kts +++ b/examples/chat/shared/build.gradle.kts @@ -99,7 +99,7 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.chat" sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") diff --git a/examples/cocoapods-ios-example/gradle.properties b/examples/cocoapods-ios-example/gradle.properties index 9180bd653e..799d1c5b77 100644 --- a/examples/cocoapods-ios-example/gradle.properties +++ b/examples/cocoapods-ios-example/gradle.properties @@ -20,6 +20,6 @@ android.minSdk=24 #Compose #Versions -kotlin.version=2.0.0 -agp.version=8.0.2 -compose.version=1.6.10 \ No newline at end of file +kotlin.version=2.0.20 +agp.version=8.5.0 +compose.version=1.7.1 \ No newline at end of file diff --git a/examples/cocoapods-ios-example/gradle/wrapper/gradle-wrapper.properties b/examples/cocoapods-ios-example/gradle/wrapper/gradle-wrapper.properties index 17655d0ef2..48c0a02ca4 100644 --- a/examples/cocoapods-ios-example/gradle/wrapper/gradle-wrapper.properties +++ b/examples/cocoapods-ios-example/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/examples/codeviewer/androidApp/build.gradle.kts b/examples/codeviewer/androidApp/build.gradle.kts index d314ebb40b..4fb5295d46 100644 --- a/examples/codeviewer/androidApp/build.gradle.kts +++ b/examples/codeviewer/androidApp/build.gradle.kts @@ -17,12 +17,12 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.codeviewer" defaultConfig { applicationId = "org.jetbrains.Codeviewer" minSdk = 26 - targetSdk = 34 + targetSdk = 35 versionCode = 1 versionName = "1.0" } diff --git a/examples/codeviewer/gradle.properties b/examples/codeviewer/gradle.properties index e7adc12149..f0830f4e66 100644 --- a/examples/codeviewer/gradle.properties +++ b/examples/codeviewer/gradle.properties @@ -10,6 +10,6 @@ kotlin.native.useEmbeddableCompilerJar=true kotlin.mpp.androidSourceSetLayoutVersion=2 # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=2.0.0 -agp.version=8.0.2 -compose.version=1.6.10 +kotlin.version=2.0.20 +agp.version=8.5.0 +compose.version=1.7.1 diff --git a/examples/codeviewer/gradle/wrapper/gradle-wrapper.properties b/examples/codeviewer/gradle/wrapper/gradle-wrapper.properties index 17655d0ef2..48c0a02ca4 100644 --- a/examples/codeviewer/gradle/wrapper/gradle-wrapper.properties +++ b/examples/codeviewer/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/examples/codeviewer/iosApp/iosApp/Info.plist b/examples/codeviewer/iosApp/iosApp/Info.plist index 9a269f5eaa..412e378128 100644 --- a/examples/codeviewer/iosApp/iosApp/Info.plist +++ b/examples/codeviewer/iosApp/iosApp/Info.plist @@ -20,6 +20,8 @@ 1 LSRequiresIPhoneOS + CADisableMinimumFrameDurationOnPhone + UIApplicationSceneManifest UIApplicationSupportsMultipleScenes diff --git a/examples/codeviewer/shared/build.gradle.kts b/examples/codeviewer/shared/build.gradle.kts index 233239f707..2670d7ce73 100644 --- a/examples/codeviewer/shared/build.gradle.kts +++ b/examples/codeviewer/shared/build.gradle.kts @@ -70,7 +70,7 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.codeviewer.common" sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") defaultConfig { diff --git a/examples/graphics-2d/androidApp/build.gradle.kts b/examples/graphics-2d/androidApp/build.gradle.kts index 900e901eba..fd5a2d40ab 100644 --- a/examples/graphics-2d/androidApp/build.gradle.kts +++ b/examples/graphics-2d/androidApp/build.gradle.kts @@ -17,12 +17,12 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.graphics2d" defaultConfig { applicationId = "org.jetbrains.Graphics2D" minSdk = 26 - targetSdk = 34 + targetSdk = 35 versionCode = 1 versionName = "1.0" } diff --git a/examples/graphics-2d/gradle.properties b/examples/graphics-2d/gradle.properties index 9c200fd96d..da71e81b3f 100644 --- a/examples/graphics-2d/gradle.properties +++ b/examples/graphics-2d/gradle.properties @@ -10,9 +10,9 @@ kotlin.native.useEmbeddableCompilerJar=true kotlin.mpp.androidSourceSetLayoutVersion=2 # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=2.0.0 -agp.version=8.0.2 -compose.version=1.6.10 +kotlin.version=2.0.20 +agp.version=8.5.0 +compose.version=1.7.1 # TODO: remove when switching to 1.9.10. See: https://youtrack.jetbrains.com/issue/KT-60852 # usage: ./gradlew :jsApp:jsBrowserRun -Pworkaround.kotlin.js.kt60852=true diff --git a/examples/graphics-2d/gradle/wrapper/gradle-wrapper.properties b/examples/graphics-2d/gradle/wrapper/gradle-wrapper.properties index 17655d0ef2..48c0a02ca4 100644 --- a/examples/graphics-2d/gradle/wrapper/gradle-wrapper.properties +++ b/examples/graphics-2d/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/examples/graphics-2d/iosApp/iosApp/Info.plist b/examples/graphics-2d/iosApp/iosApp/Info.plist index 9a269f5eaa..412e378128 100644 --- a/examples/graphics-2d/iosApp/iosApp/Info.plist +++ b/examples/graphics-2d/iosApp/iosApp/Info.plist @@ -20,6 +20,8 @@ 1 LSRequiresIPhoneOS + CADisableMinimumFrameDurationOnPhone + UIApplicationSceneManifest UIApplicationSupportsMultipleScenes diff --git a/examples/graphics-2d/shared/build.gradle.kts b/examples/graphics-2d/shared/build.gradle.kts index 176594ed84..8005b00f94 100644 --- a/examples/graphics-2d/shared/build.gradle.kts +++ b/examples/graphics-2d/shared/build.gradle.kts @@ -68,7 +68,7 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.Graphics2D" sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") diff --git a/examples/html/compose-bird/gradle.properties b/examples/html/compose-bird/gradle.properties index 5a1e304d81..3e62aae619 100644 --- a/examples/html/compose-bird/gradle.properties +++ b/examples/html/compose-bird/gradle.properties @@ -1,5 +1,5 @@ kotlin.code.style=official -kotlin.version=2.0.0 -compose.version=1.6.10 +kotlin.version=2.0.20 +compose.version=1.7.1 org.gradle.configuration-cache=true org.gradle.caching=true diff --git a/examples/html/compose-in-js/gradle.properties b/examples/html/compose-in-js/gradle.properties index 9b0969078e..2db4952f23 100644 --- a/examples/html/compose-in-js/gradle.properties +++ b/examples/html/compose-in-js/gradle.properties @@ -1,6 +1,6 @@ kotlin.code.style=official kotlin.js.webpack.major.version=4 -kotlin.version=2.0.0 -compose.version=1.6.10 +kotlin.version=2.0.20 +compose.version=1.7.1 org.gradle.configuration-cache=true org.gradle.caching=true diff --git a/examples/html/landing/gradle.properties b/examples/html/landing/gradle.properties index 5a1e304d81..3e62aae619 100644 --- a/examples/html/landing/gradle.properties +++ b/examples/html/landing/gradle.properties @@ -1,5 +1,5 @@ kotlin.code.style=official -kotlin.version=2.0.0 -compose.version=1.6.10 +kotlin.version=2.0.20 +compose.version=1.7.1 org.gradle.configuration-cache=true org.gradle.caching=true diff --git a/examples/html/with-react/gradle.properties b/examples/html/with-react/gradle.properties index 5a1e304d81..3e62aae619 100644 --- a/examples/html/with-react/gradle.properties +++ b/examples/html/with-react/gradle.properties @@ -1,5 +1,5 @@ kotlin.code.style=official -kotlin.version=2.0.0 -compose.version=1.6.10 +kotlin.version=2.0.20 +compose.version=1.7.1 org.gradle.configuration-cache=true org.gradle.caching=true diff --git a/examples/imageviewer/README.md b/examples/imageviewer/README.md index 84946f82c3..7718c62347 100755 --- a/examples/imageviewer/README.md +++ b/examples/imageviewer/README.md @@ -1,7 +1,11 @@ # Imageviewer An example of an image gallery with camera and map support -based on Compose Multiplatform (desktop, Android and iOS). +based on Compose Multiplatform (desktop, Web, Android and iOS). + +[![Static Badge](https://img.shields.io/badge/online%20demo%20%F0%9F%9A%80-6b57ff?style=for-the-badge)](https://zal.im/wasm/iv). + +![](screenshots/imageviewer.png) ## Setting up your development environment @@ -29,7 +33,11 @@ Choose a run configuration for an appropriate target in IDE and run it. ## Run on Web via Gradle -`./gradlew :web:wasmJsRun` +> **Note:** +> Web support is in [Alpha](https://kotlinlang.org/docs/components-stability.html). It may be changed at any time. You can use it in scenarios before production. +> We would appreciate your feedback in [GitHub](https://github.com/JetBrains/compose-multiplatform/issues). + +`./gradlew :webApp:wasmJsRun` ### Running Android application diff --git a/examples/imageviewer/androidApp/build.gradle.kts b/examples/imageviewer/androidApp/build.gradle.kts index c091007983..e080c5f3f2 100755 --- a/examples/imageviewer/androidApp/build.gradle.kts +++ b/examples/imageviewer/androidApp/build.gradle.kts @@ -18,12 +18,12 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "example.imageviewer" defaultConfig { applicationId = "org.jetbrains.Imageviewer" minSdk = 26 - targetSdk = 34 + targetSdk = 35 versionCode = 1 versionName = "1.0" } diff --git a/examples/imageviewer/gradle.properties b/examples/imageviewer/gradle.properties index f63e7c163c..465cd1e1ca 100644 --- a/examples/imageviewer/gradle.properties +++ b/examples/imageviewer/gradle.properties @@ -8,6 +8,6 @@ org.gradle.caching=true org.jetbrains.compose.experimental.jscanvas.enabled=true org.jetbrains.compose.experimental.macos.enabled=true org.jetbrains.compose.experimental.wasm.enabled=true -kotlin.version=2.0.0 -agp.version=8.0.2 -compose.version=1.6.10 +kotlin.version=2.0.20 +agp.version=8.5.0 +compose.version=1.7.1 diff --git a/examples/imageviewer/gradle/wrapper/gradle-wrapper.properties b/examples/imageviewer/gradle/wrapper/gradle-wrapper.properties index 17655d0ef2..48c0a02ca4 100644 --- a/examples/imageviewer/gradle/wrapper/gradle-wrapper.properties +++ b/examples/imageviewer/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/examples/imageviewer/iosApp/iosApp/Info.plist b/examples/imageviewer/iosApp/iosApp/Info.plist index 5b28bf5219..8540150120 100644 --- a/examples/imageviewer/iosApp/iosApp/Info.plist +++ b/examples/imageviewer/iosApp/iosApp/Info.plist @@ -22,6 +22,8 @@ 1 LSRequiresIPhoneOS + CADisableMinimumFrameDurationOnPhone + NSCameraUsageDescription This app uses camera for capturing photos UIApplicationSceneManifest diff --git a/examples/imageviewer/screenshots/imageviewer.png b/examples/imageviewer/screenshots/imageviewer.png new file mode 100644 index 0000000000..60437cbbde Binary files /dev/null and b/examples/imageviewer/screenshots/imageviewer.png differ diff --git a/examples/imageviewer/shared/build.gradle.kts b/examples/imageviewer/shared/build.gradle.kts index 32e94f66f5..b9d7966c5d 100755 --- a/examples/imageviewer/shared/build.gradle.kts +++ b/examples/imageviewer/shared/build.gradle.kts @@ -90,7 +90,7 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "example.imageviewer.shared" sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") sourceSets["main"].res.srcDirs("src/androidMain/res") diff --git a/examples/intellij-plugin/gradle.properties b/examples/intellij-plugin/gradle.properties index 5a1e304d81..3e62aae619 100644 --- a/examples/intellij-plugin/gradle.properties +++ b/examples/intellij-plugin/gradle.properties @@ -1,5 +1,5 @@ kotlin.code.style=official -kotlin.version=2.0.0 -compose.version=1.6.10 +kotlin.version=2.0.20 +compose.version=1.7.1 org.gradle.configuration-cache=true org.gradle.caching=true diff --git a/examples/interop/ios-compose-in-swiftui/gradle.properties b/examples/interop/ios-compose-in-swiftui/gradle.properties index b400da5805..826f723fb4 100644 --- a/examples/interop/ios-compose-in-swiftui/gradle.properties +++ b/examples/interop/ios-compose-in-swiftui/gradle.properties @@ -1,5 +1,5 @@ kotlin.code.style=official xcodeproj=./iosApp org.gradle.jvmargs=-Xmx3g -kotlin.version=2.0.0 -compose.version=1.6.10 +kotlin.version=2.0.20 +compose.version=1.7.1 diff --git a/examples/interop/ios-compose-in-uikit/gradle.properties b/examples/interop/ios-compose-in-uikit/gradle.properties index 49003a0583..dd53aa5e4f 100644 --- a/examples/interop/ios-compose-in-uikit/gradle.properties +++ b/examples/interop/ios-compose-in-uikit/gradle.properties @@ -3,5 +3,5 @@ xcodeproj=./iosApp org.gradle.jvmargs=-Xmx3g # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=2.0.0 -compose.version=1.6.10 +kotlin.version=2.0.20 +compose.version=1.7.1 diff --git a/examples/interop/ios-swiftui-in-compose/gradle.properties b/examples/interop/ios-swiftui-in-compose/gradle.properties index 49003a0583..dd53aa5e4f 100644 --- a/examples/interop/ios-swiftui-in-compose/gradle.properties +++ b/examples/interop/ios-swiftui-in-compose/gradle.properties @@ -3,5 +3,5 @@ xcodeproj=./iosApp org.gradle.jvmargs=-Xmx3g # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=2.0.0 -compose.version=1.6.10 +kotlin.version=2.0.20 +compose.version=1.7.1 diff --git a/examples/interop/ios-uikit-in-compose/gradle.properties b/examples/interop/ios-uikit-in-compose/gradle.properties index 49003a0583..dd53aa5e4f 100644 --- a/examples/interop/ios-uikit-in-compose/gradle.properties +++ b/examples/interop/ios-uikit-in-compose/gradle.properties @@ -3,5 +3,5 @@ xcodeproj=./iosApp org.gradle.jvmargs=-Xmx3g # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=2.0.0 -compose.version=1.6.10 +kotlin.version=2.0.20 +compose.version=1.7.1 diff --git a/examples/issues/android/build.gradle.kts b/examples/issues/android/build.gradle.kts index 156819f33b..2baa1b784b 100644 --- a/examples/issues/android/build.gradle.kts +++ b/examples/issues/android/build.gradle.kts @@ -6,12 +6,12 @@ plugins { } android { - compileSdk = 34 + compileSdk = 35 namespace = "com.example.myapplication" defaultConfig { minSdk = 26 - targetSdk = 34 + targetSdk = 35 applicationId = "org.jetbrains.Issues" versionCode = 1 versionName = "1.0" diff --git a/examples/issues/common/build.gradle.kts b/examples/issues/common/build.gradle.kts index ebc6eef1b4..8d97331448 100644 --- a/examples/issues/common/build.gradle.kts +++ b/examples/issues/common/build.gradle.kts @@ -40,7 +40,7 @@ apollo { } android { - compileSdk = 34 + compileSdk = 35 namespace = "com.example.myapplication.common" defaultConfig { diff --git a/examples/issues/gradle.properties b/examples/issues/gradle.properties index b4646bb591..dde6e89ebd 100644 --- a/examples/issues/gradle.properties +++ b/examples/issues/gradle.properties @@ -19,6 +19,6 @@ kotlin.code.style=official android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true -kotlin.version=2.0.0 -agp.version=8.0.2 -compose.version=1.6.10 +kotlin.version=2.0.20 +agp.version=8.5.0 +compose.version=1.7.1 diff --git a/examples/issues/gradle/wrapper/gradle-wrapper.properties b/examples/issues/gradle/wrapper/gradle-wrapper.properties index 17655d0ef2..48c0a02ca4 100644 --- a/examples/issues/gradle/wrapper/gradle-wrapper.properties +++ b/examples/issues/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/examples/jetsnack/.gitignore b/examples/jetsnack/.gitignore index 88f2e2fcc6..a4b97da665 100644 --- a/examples/jetsnack/.gitignore +++ b/examples/jetsnack/.gitignore @@ -1,4 +1,5 @@ .gradle +.kotlin build/ !gradle/wrapper/gradle-wrapper.jar !**/src/main/**/build/ @@ -41,3 +42,9 @@ bin/ ### Mac OS ### .DS_Store /local.properties + +iosApp/Podfile.lock +iosApp/Pods/* +iosApp/iosApp.xcworkspace/* +iosApp/iosApp.xcodeproj/* +!iosApp/iosApp.xcodeproj/project.pbxproj diff --git a/examples/jetsnack/android/build.gradle.kts b/examples/jetsnack/android/build.gradle.kts index 7bb2524512..b8904fd7ec 100644 --- a/examples/jetsnack/android/build.gradle.kts +++ b/examples/jetsnack/android/build.gradle.kts @@ -18,12 +18,12 @@ dependencies { } android { - compileSdk = 34 - namespace = "com.example.android" + compileSdk = 35 + namespace = "example.jetsnack" defaultConfig { - applicationId = "com.example.android" + applicationId = "org.jetbrains.Jetsnack" minSdk = 24 - targetSdk = 33 + targetSdk = 35 versionCode = 1 versionName = "1.0-SNAPSHOT" } diff --git a/examples/jetsnack/android/src/main/AndroidManifest.xml b/examples/jetsnack/android/src/main/AndroidManifest.xml index d456c02f9d..bc60a6ee28 100644 --- a/examples/jetsnack/android/src/main/AndroidManifest.xml +++ b/examples/jetsnack/android/src/main/AndroidManifest.xml @@ -7,7 +7,7 @@ android:allowBackup="false" android:supportsRtl="true" android:theme="@style/Theme.AppCompat.Light.NoActionBar"> - + diff --git a/examples/jetsnack/common/build.gradle.kts b/examples/jetsnack/common/build.gradle.kts index 53e38380ee..08100273ed 100644 --- a/examples/jetsnack/common/build.gradle.kts +++ b/examples/jetsnack/common/build.gradle.kts @@ -39,6 +39,7 @@ kotlin { api(compose.runtime) api(compose.foundation) api(compose.material) + implementation(compose.components.resources) implementation(libs.kotlinx.coroutines) } } @@ -94,12 +95,12 @@ kotlin { android { - compileSdk = 34 + compileSdk = 35 namespace = "com.example.jetsnack" sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") defaultConfig { minSdk = 24 - targetSdk = 33 + targetSdk = 35 } compileOptions { sourceCompatibility = JavaVersion.VERSION_17 diff --git a/examples/jetsnack/common/src/androidMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.kt b/examples/jetsnack/common/src/androidMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.kt index fe715cb652..bfd48c5078 100644 --- a/examples/jetsnack/common/src/androidMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.kt +++ b/examples/jetsnack/common/src/androidMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.kt @@ -1,25 +1,69 @@ package com.example.jetsnack.ui.components -import androidx.compose.foundation.layout.fillMaxSize +import android.annotation.SuppressLint +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.ExperimentalAnimationApi +import androidx.compose.animation.core.TweenSpec +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.with +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource -import coil.compose.AsyncImage -import coil.request.ImageRequest -import com.example.jetsnack.R +import com.example.common.generated.resources.Res +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.jetbrains.compose.resources.ExperimentalResourceApi +private val imagesCache = mutableMapOf() + +@SuppressLint("UnusedContentLambdaTargetStateParameter") +@OptIn(ExperimentalAnimationApi::class, ExperimentalResourceApi::class) @Composable actual fun SnackAsyncImage(imageUrl: String, contentDescription: String?, modifier: Modifier) { - AsyncImage( - model = ImageRequest.Builder(LocalContext.current) - .data(imageUrl) - .crossfade(true) - .build(), - contentDescription = contentDescription, - placeholder = painterResource(R.drawable.placeholder), - modifier = Modifier.fillMaxSize(), - contentScale = ContentScale.Crop, - ) + var img: ImageBitmap? by remember(imageUrl) { mutableStateOf(null) } + + + AnimatedContent(img, transitionSpec = { + fadeIn(TweenSpec()) with fadeOut(TweenSpec()) + }) { + if (img != null) { + Image(img!!, contentDescription = contentDescription, modifier = modifier, contentScale = ContentScale.Crop) + } else { + Box(modifier = modifier) + } + } + + LaunchedEffect(imageUrl) { + if (imagesCache.contains(imageUrl)) { + img = imagesCache[imageUrl] + } else { + withContext(Dispatchers.IO) { + img = try { + Res.readBytes(imageUrl).toAndroidBitmap().asImageBitmap().also { + imagesCache[imageUrl] = it + img = it + } + } catch (e: Throwable) { + e.printStackTrace() + null + } + } + } + } +} + +fun ByteArray.toAndroidBitmap(): Bitmap { + return BitmapFactory.decodeByteArray(this, 0, size) } \ No newline at end of file diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/almonds.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/almonds.jpg new file mode 100644 index 0000000000..0f1eef57e3 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/almonds.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/apple_chips.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/apple_chips.jpg new file mode 100644 index 0000000000..37c805d169 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/apple_chips.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/apple_juice.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/apple_juice.jpg new file mode 100644 index 0000000000..d519dbcd46 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/apple_juice.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/apple_pie.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/apple_pie.jpg new file mode 100644 index 0000000000..41096b2216 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/apple_pie.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/apple_sauce.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/apple_sauce.jpg new file mode 100644 index 0000000000..7f5331ee24 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/apple_sauce.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/apples.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/apples.jpg new file mode 100644 index 0000000000..cc729f1646 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/apples.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/cheese.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/cheese.jpg new file mode 100644 index 0000000000..c5c6dce61c Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/cheese.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/chips.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/chips.jpg new file mode 100644 index 0000000000..04d5fe2cd3 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/chips.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/cupcake.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/cupcake.jpg new file mode 100644 index 0000000000..42e766d843 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/cupcake.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/desserts.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/desserts.jpg new file mode 100644 index 0000000000..6d44990765 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/desserts.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/donut.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/donut.jpg new file mode 100644 index 0000000000..076896a812 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/donut.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/eclair.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/eclair.jpg new file mode 100644 index 0000000000..5601780345 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/eclair.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/froyo.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/froyo.jpg new file mode 100644 index 0000000000..e1bb068cc9 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/froyo.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/fruit.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/fruit.jpg new file mode 100644 index 0000000000..4122473184 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/fruit.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/gingerbread.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/gingerbread.jpg new file mode 100644 index 0000000000..ac069de103 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/gingerbread.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/gluten_free.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/gluten_free.jpg new file mode 100644 index 0000000000..0745457a36 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/gluten_free.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/grapes.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/grapes.jpg new file mode 100644 index 0000000000..3b573787cf Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/grapes.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/honeycomb.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/honeycomb.jpg new file mode 100644 index 0000000000..ea632bd25d Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/honeycomb.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/ice_cream_sandwich.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/ice_cream_sandwich.jpg new file mode 100644 index 0000000000..fd77631e9a Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/ice_cream_sandwich.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/jelly_bean.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/jelly_bean.jpg new file mode 100644 index 0000000000..84a10208c9 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/jelly_bean.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/kitkat.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/kitkat.jpg new file mode 100644 index 0000000000..75b2e44abb Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/kitkat.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/kiwi.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/kiwi.jpg new file mode 100644 index 0000000000..2197fbd48f Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/kiwi.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/lollipop.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/lollipop.jpg new file mode 100644 index 0000000000..98d1db7d2f Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/lollipop.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/mango.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/mango.jpg new file mode 100644 index 0000000000..717773d7b5 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/mango.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/marshmallow.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/marshmallow.jpg new file mode 100644 index 0000000000..cdc1159226 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/marshmallow.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/nougat.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/nougat.jpg new file mode 100644 index 0000000000..1a844d9b9f Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/nougat.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/nuts.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/nuts.jpg new file mode 100644 index 0000000000..03556767ec Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/nuts.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/oreo.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/oreo.jpg new file mode 100644 index 0000000000..cf2c3e534c Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/oreo.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/organic.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/organic.jpg new file mode 100644 index 0000000000..2847abf4f0 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/organic.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/paleo.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/paleo.jpg new file mode 100644 index 0000000000..750fcd58e7 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/paleo.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/pie.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/pie.jpg new file mode 100644 index 0000000000..439c18cfbb Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/pie.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/placeholder.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/placeholder.jpg new file mode 100644 index 0000000000..31e05faacb Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/placeholder.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/popcorn.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/popcorn.jpg new file mode 100644 index 0000000000..02713ffdbf Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/popcorn.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/pretzels.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/pretzels.jpg new file mode 100644 index 0000000000..d31d4aa4eb Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/pretzels.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/smoothies.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/smoothies.jpg new file mode 100644 index 0000000000..f2eaa31bf1 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/smoothies.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/composeResources/files/vegan.jpg b/examples/jetsnack/common/src/commonMain/composeResources/files/vegan.jpg new file mode 100644 index 0000000000..29276a68b7 Binary files /dev/null and b/examples/jetsnack/common/src/commonMain/composeResources/files/vegan.jpg differ diff --git a/examples/jetsnack/common/src/commonMain/kotlin/com/example/jetsnack/model/Search.kt b/examples/jetsnack/common/src/commonMain/kotlin/com/example/jetsnack/model/Search.kt index d22a41edb4..cc949b0150 100644 --- a/examples/jetsnack/common/src/commonMain/kotlin/com/example/jetsnack/model/Search.kt +++ b/examples/jetsnack/common/src/commonMain/kotlin/com/example/jetsnack/model/Search.kt @@ -65,19 +65,19 @@ private val searchCategoryCollections = listOf( categories = listOf( SearchCategory( name = "Chips & crackers", - imageUrl = "https://source.unsplash.com/UsSdMZ78Q3E" + imageUrl = "files/chips.jpg" ), SearchCategory( name = "Fruit snacks", - imageUrl = "https://source.unsplash.com/SfP1PtM9Qa8" + imageUrl = "files/fruit.jpg" ), SearchCategory( name = "Desserts", - imageUrl = "https://source.unsplash.com/_jk8KIyN_uA" + imageUrl = "files/desserts.jpg" ), SearchCategory( name = "Nuts ", - imageUrl = "https://source.unsplash.com/UsSdMZ78Q3E" + imageUrl = "files/nuts.jpg" ) ) ), @@ -87,27 +87,27 @@ private val searchCategoryCollections = listOf( categories = listOf( SearchCategory( name = "Organic", - imageUrl = "https://source.unsplash.com/7meCnGCJ5Ms" + imageUrl = "files/organic.jpg" ), SearchCategory( name = "Gluten Free", - imageUrl = "https://source.unsplash.com/m741tj4Cz7M" + imageUrl = "files/gluten_free.jpg" ), SearchCategory( name = "Paleo", - imageUrl = "https://source.unsplash.com/dt5-8tThZKg" + imageUrl = "files/paleo.jpg" ), SearchCategory( name = "Vegan", - imageUrl = "https://source.unsplash.com/ReXxkS1m1H0" + imageUrl = "files/vegan.jpg" ), SearchCategory( name = "Vegitarian", - imageUrl = "https://source.unsplash.com/IGfIGP5ONV0" + imageUrl = "files/grapes.jpg" ), SearchCategory( name = "Whole30", - imageUrl = "https://source.unsplash.com/9MzCd76xLGk" + imageUrl = "files/popcorn.jpg" ) ) ) diff --git a/examples/jetsnack/common/src/commonMain/kotlin/com/example/jetsnack/model/Snack.kt b/examples/jetsnack/common/src/commonMain/kotlin/com/example/jetsnack/model/Snack.kt index ae2ddb00cc..a01ced2083 100644 --- a/examples/jetsnack/common/src/commonMain/kotlin/com/example/jetsnack/model/Snack.kt +++ b/examples/jetsnack/common/src/commonMain/kotlin/com/example/jetsnack/model/Snack.kt @@ -17,6 +17,7 @@ package com.example.jetsnack.model import androidx.compose.runtime.Immutable +import com.example.common.generated.resources.Res @Immutable data class Snack( @@ -37,190 +38,190 @@ val snacks = listOf( id = 1L, name = "Cupcake", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/pGM4sjt_BdQ", + imageUrl = "files/cupcake.jpg", price = 299 ), Snack( id = 2L, name = "Donut", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/Yc5sL-ejk6U", + imageUrl = "files/donut.jpg", price = 290 ), Snack( id = 3L, name = "Eclair", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/-LojFX9NfPY", + imageUrl = "files/eclair.jpg", price = 289 ), Snack( id = 4L, name = "Froyo", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/3U2V5WqK1PQ", + imageUrl = "files/froyo.jpg", price = 288 ), Snack( id = 5L, name = "Gingerbread", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/Y4YR9OjdIMk", + imageUrl = "files/gingerbread.jpg", price = 499 ), Snack( id = 6L, name = "Honeycomb", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/bELvIg_KZGU", + imageUrl = "files/honeycomb.jpg", price = 309 ), Snack( id = 7L, name = "Ice Cream Sandwich", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/YgYJsFDd4AU", + imageUrl = "files/ice_cream_sandwich.jpg", price = 1299 ), Snack( id = 8L, name = "Jellybean", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/0u_vbeOkMpk", + imageUrl = "files/jelly_bean.jpg", price = 109 ), Snack( id = 9L, name = "KitKat", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/yb16pT5F_jE", + imageUrl = "files/kitkat.jpg", price = 549 ), Snack( id = 10L, name = "Lollipop", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/AHF_ZktTL6Q", + imageUrl = "files/lollipop.jpg", price = 209 ), Snack( id = 11L, name = "Marshmallow", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/rqFm0IgMVYY", + imageUrl = "files/marshmallow.jpg", price = 219 ), Snack( id = 12L, name = "Nougat", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/qRE_OpbVPR8", + imageUrl = "files/nougat.jpg", price = 309 ), Snack( id = 13L, name = "Oreo", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/33fWPnyN6tU", + imageUrl = "files/oreo.jpg", price = 339 ), Snack( id = 14L, name = "Pie", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/aX_ljOOyWJY", + imageUrl = "files/pie.jpg", price = 249 ), Snack( id = 15L, name = "Chips", - imageUrl = "https://source.unsplash.com/UsSdMZ78Q3E", + imageUrl = "files/chips.jpg", price = 277 ), Snack( id = 16L, name = "Pretzels", - imageUrl = "https://source.unsplash.com/7meCnGCJ5Ms", + imageUrl = "files/pretzels.jpg", price = 154 ), Snack( id = 17L, name = "Smoothies", - imageUrl = "https://source.unsplash.com/m741tj4Cz7M", + imageUrl = "files/smoothies.jpg", price = 257 ), Snack( id = 18L, name = "Popcorn", - imageUrl = "https://source.unsplash.com/iuwMdNq0-s4", + imageUrl = "files/popcorn.jpg", price = 167 ), Snack( id = 19L, name = "Almonds", - imageUrl = "https://source.unsplash.com/qgWWQU1SzqM", + imageUrl = "files/almonds.jpg", price = 123 ), Snack( id = 20L, name = "Cheese", - imageUrl = "https://source.unsplash.com/9MzCd76xLGk", + imageUrl = "files/cheese.jpg", price = 231 ), Snack( id = 21L, name = "Apples", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/1d9xXWMtQzQ", + imageUrl = "files/apples.jpg", price = 221 ), Snack( id = 22L, name = "Apple sauce", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/wZxpOw84QTU", + imageUrl = "files/apple_sauce.jpg", price = 222 ), Snack( id = 23L, name = "Apple chips", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/okzeRxm_GPo", + imageUrl = "files/apple_chips.jpg", price = 231 ), Snack( id = 24L, name = "Apple juice", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/l7imGdupuhU", + imageUrl = "files/apple_juice.jpg", price = 241 ), Snack( id = 25L, name = "Apple pie", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/bkXzABDt08Q", + imageUrl = "files/apple_pie.jpg", price = 225 ), Snack( id = 26L, name = "Grapes", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/y2MeW00BdBo", + imageUrl = "files/grapes.jpg", price = 266 ), Snack( id = 27L, name = "Kiwi", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/1oMGgHn-M8k", + imageUrl = "files/kiwi.jpg", price = 127 ), Snack( id = 28L, name = "Mango", tagline = "A tag line", - imageUrl = "https://source.unsplash.com/TIGDsyy0TK4", + imageUrl = "files/mango.jpg", price = 128 ) ) diff --git a/examples/jetsnack/common/src/desktopMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.kt b/examples/jetsnack/common/src/desktopMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.kt index 2aa7db9147..cb465b829a 100644 --- a/examples/jetsnack/common/src/desktopMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.kt +++ b/examples/jetsnack/common/src/desktopMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.kt @@ -9,15 +9,17 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.toComposeImageBitmap import androidx.compose.ui.layout.ContentScale +import com.example.common.generated.resources.Res import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext +import org.jetbrains.compose.resources.ExperimentalResourceApi import java.net.URL import javax.imageio.ImageIO private val imagesCache = mutableMapOf() -@OptIn(ExperimentalAnimationApi::class) +@OptIn(ExperimentalAnimationApi::class, ExperimentalResourceApi::class) @Composable actual fun SnackAsyncImage(imageUrl: String, contentDescription: String?, modifier: Modifier) { var img: ImageBitmap? by remember(imageUrl) { mutableStateOf(null) } @@ -39,7 +41,7 @@ actual fun SnackAsyncImage(imageUrl: String, contentDescription: String?, modifi } else { withContext(Dispatchers.IO) { img = try { - ImageIO.read(URL(imageUrl)).toComposeImageBitmap().also { + org.jetbrains.skia.Image.makeFromEncoded(Res.readBytes(imageUrl)).toComposeImageBitmap().also { imagesCache[imageUrl] = it img = it } diff --git a/examples/jetsnack/common/src/iosMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.ios.kt b/examples/jetsnack/common/src/iosMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.ios.kt index 1e8bdc408d..fe33db7749 100644 --- a/examples/jetsnack/common/src/iosMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.ios.kt +++ b/examples/jetsnack/common/src/iosMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.ios.kt @@ -9,10 +9,12 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.toComposeImageBitmap import androidx.compose.ui.layout.ContentScale +import com.example.common.generated.resources.Res import kotlinx.cinterop.ExperimentalForeignApi import kotlinx.cinterop.addressOf import kotlinx.cinterop.usePinned import kotlinx.coroutines.* +import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.skia.Image import platform.Foundation.* import platform.posix.memcpy @@ -21,7 +23,7 @@ import kotlin.coroutines.resumeWithException private val imagesCache = mutableMapOf() -@OptIn(ExperimentalAnimationApi::class) +@OptIn(ExperimentalAnimationApi::class, ExperimentalResourceApi::class) @Composable actual fun SnackAsyncImage(imageUrl: String, contentDescription: String?, modifier: Modifier) { var img: ImageBitmap? by remember(imageUrl) { mutableStateOf(null) } @@ -43,7 +45,7 @@ actual fun SnackAsyncImage(imageUrl: String, contentDescription: String?, modifi } else { withContext(Dispatchers.IO) { img = try { - loadImage(imageUrl).also { + Image.makeFromEncoded(Res.readBytes(imageUrl)).toComposeImageBitmap().also { imagesCache[imageUrl] = it img = it } @@ -54,33 +56,4 @@ actual fun SnackAsyncImage(imageUrl: String, contentDescription: String?, modifi } } } -} - -@OptIn(ExperimentalForeignApi::class) -suspend fun loadImage(url: String): ImageBitmap = suspendCancellableCoroutine { continuation -> - val nsUrl = NSURL(string = url) - val task = NSURLSession.sharedSession.dataTaskWithURL(nsUrl) { data, response, error -> - if (data != null) { - val byteArray = ByteArray(data.length.toInt()).apply { - usePinned { - memcpy( - it.addressOf(0), - data.bytes, - data.length - ) - } - } - - continuation.resume(Image.makeFromEncoded(byteArray).toComposeImageBitmap()) - } else { - error?.let { - continuation.resumeWithException(Exception(it.localizedDescription)) - } - } - } - - task.resume() - continuation.invokeOnCancellation { - task.cancel() - } } \ No newline at end of file diff --git a/examples/jetsnack/common/src/wasmJsMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.kt b/examples/jetsnack/common/src/wasmJsMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.kt index c06206cae7..4204802ced 100644 --- a/examples/jetsnack/common/src/wasmJsMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.kt +++ b/examples/jetsnack/common/src/wasmJsMain/kotlin/com/example/jetsnack/ui/components/SnackAsyncImage.kt @@ -6,11 +6,14 @@ import androidx.compose.foundation.Image import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.toComposeImageBitmap import androidx.compose.ui.layout.ContentScale +import com.example.common.generated.resources.Res import kotlinx.coroutines.* import com.example.jetsnack.model.snacks +import org.jetbrains.compose.resources.ExperimentalResourceApi val imagesCache = mutableMapOf() +@OptIn(ExperimentalResourceApi::class) @Composable actual fun SnackAsyncImage( imageUrl: String, @@ -28,21 +31,22 @@ actual fun SnackAsyncImage( if (imagesCache.contains(imageUrl)) { bitmap = imagesCache[imageUrl]!! } else { - val arrayBuffer = loadImage(imageUrl) - val skiaImg = org.jetbrains.skia.Image.makeFromEncoded(arrayBuffer.toByteArray()) - imagesCache[imageUrl] = skiaImg.toComposeImageBitmap() + imagesCache[imageUrl] = org.jetbrains.skia.Image.makeFromEncoded( + Res.readBytes(imageUrl) + ).toComposeImageBitmap() bitmap = imagesCache[imageUrl] } } } +@OptIn(ExperimentalResourceApi::class) suspend fun CoroutineScope.prepareImagesCache() { val jobs = mutableListOf() // We have not many images, so we can prepare and cache them upfront snacks.forEach { val j = launch { - val arrayBuffer = loadImage(it.imageUrl) - val skiaImg = org.jetbrains.skia.Image.makeFromEncoded(arrayBuffer.toByteArray()) - imagesCache[it.imageUrl] = skiaImg.toComposeImageBitmap() + imagesCache[it.imageUrl] = org.jetbrains.skia.Image.makeFromEncoded( + Res.readBytes(it.imageUrl) + ).toComposeImageBitmap() } jobs.add(j) } diff --git a/examples/jetsnack/gradle.properties b/examples/jetsnack/gradle.properties index 5527a505a8..2531ef7e68 100644 --- a/examples/jetsnack/gradle.properties +++ b/examples/jetsnack/gradle.properties @@ -1,6 +1,6 @@ org.gradle.jvmargs=-Xmx8g kotlin.code.style=official android.useAndroidX=true -agp.version=8.0.2 -kotlin.version=2.0.0 -compose.version=1.6.10 +agp.version=8.5.0 +kotlin.version=2.0.20 +compose.version=1.7.1 diff --git a/examples/jetsnack/gradle/libs.versions.toml b/examples/jetsnack/gradle/libs.versions.toml index 3cddf4b819..7c1822e001 100644 --- a/examples/jetsnack/gradle/libs.versions.toml +++ b/examples/jetsnack/gradle/libs.versions.toml @@ -68,7 +68,6 @@ androidx-compose-bom = { module = "androidx.compose:compose-bom", version.ref = androidx-compose-foundation = { module = "androidx.compose.foundation:foundation" } androidx-compose-foundation-layout = { module = "androidx.compose.foundation:foundation-layout" } androidx-compose-material = { module = "androidx.compose.material:material" } -androidx-compose-material-iconsExtended = { module = "androidx.compose.material:material-icons-extended" } androidx-compose-material3 = { module = "androidx.compose.material3:material3" } androidx-compose-materialWindow = { module = "androidx.compose.material3:material3-window-size-class" } androidx-compose-runtime = { module = "androidx.compose.runtime:runtime" } diff --git a/examples/jetsnack/gradle/wrapper/gradle-wrapper.properties b/examples/jetsnack/gradle/wrapper/gradle-wrapper.properties index 8838ba97ba..e7646dead0 100644 --- a/examples/jetsnack/gradle/wrapper/gradle-wrapper.properties +++ b/examples/jetsnack/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/jetsnack/ios/Configuration/Config.xcconfig b/examples/jetsnack/ios/Configuration/Config.xcconfig index 6234dc9e5b..165347a3e3 100644 --- a/examples/jetsnack/ios/Configuration/Config.xcconfig +++ b/examples/jetsnack/ios/Configuration/Config.xcconfig @@ -1,3 +1,3 @@ TEAM_ID= -BUNDLE_ID=org.jetbrains.Imageviewer -APP_NAME=My Memories +BUNDLE_ID=org.jetbrains.Jetsnack +APP_NAME=Jetsnack diff --git a/examples/jetsnack/ios/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/examples/jetsnack/ios/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003d..0000000000 --- a/examples/jetsnack/ios/iosApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/examples/jetsnack/ios/iosApp.xcodeproj/project.xcworkspace/xcuserdata/Artem.Kobzar.xcuserdatad/UserInterfaceState.xcuserstate b/examples/jetsnack/ios/iosApp.xcodeproj/project.xcworkspace/xcuserdata/Artem.Kobzar.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 3a2cd48ad9..0000000000 Binary files a/examples/jetsnack/ios/iosApp.xcodeproj/project.xcworkspace/xcuserdata/Artem.Kobzar.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/examples/jetsnack/ios/iosApp.xcodeproj/project.xcworkspace/xcuserdata/Artem.Kobzar.xcuserdatad/xcschemes/xcschememanagement.plist b/examples/jetsnack/ios/iosApp.xcodeproj/project.xcworkspace/xcuserdata/Artem.Kobzar.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index ee3458dd76..0000000000 --- a/examples/jetsnack/ios/iosApp.xcodeproj/project.xcworkspace/xcuserdata/Artem.Kobzar.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/examples/jetsnack/ios/iosApp.xcodeproj/xcuserdata/Artem.Kobzar.xcuserdatad/xcschemes/iosApp.xcscheme b/examples/jetsnack/ios/iosApp.xcodeproj/xcuserdata/Artem.Kobzar.xcuserdatad/xcschemes/iosApp.xcscheme deleted file mode 100644 index 8734c1fb9d..0000000000 --- a/examples/jetsnack/ios/iosApp.xcodeproj/xcuserdata/Artem.Kobzar.xcuserdatad/xcschemes/iosApp.xcscheme +++ /dev/null @@ -1,67 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/examples/jetsnack/ios/iosApp.xcodeproj/xcuserdata/Artem.Kobzar.xcuserdatad/xcschemes/xcschememanagement.plist b/examples/jetsnack/ios/iosApp.xcodeproj/xcuserdata/Artem.Kobzar.xcuserdatad/xcschemes/xcschememanagement.plist deleted file mode 100644 index fa59f97d5e..0000000000 --- a/examples/jetsnack/ios/iosApp.xcodeproj/xcuserdata/Artem.Kobzar.xcuserdatad/xcschemes/xcschememanagement.plist +++ /dev/null @@ -1,14 +0,0 @@ - - - - - SchemeUserState - - iosApp.xcscheme - - orderHint - 0 - - - - diff --git a/examples/jetsnack/ios/iosApp/Info.plist b/examples/jetsnack/ios/iosApp/Info.plist index 5b28bf5219..8540150120 100644 --- a/examples/jetsnack/ios/iosApp/Info.plist +++ b/examples/jetsnack/ios/iosApp/Info.plist @@ -22,6 +22,8 @@ 1 LSRequiresIPhoneOS + CADisableMinimumFrameDurationOnPhone + NSCameraUsageDescription This app uses camera for capturing photos UIApplicationSceneManifest diff --git a/examples/jetsnack/web/src/wasmJsMain/kotlin/Main.kt b/examples/jetsnack/web/src/wasmJsMain/kotlin/Main.kt index 38faff4ffd..cc02636306 100644 --- a/examples/jetsnack/web/src/wasmJsMain/kotlin/Main.kt +++ b/examples/jetsnack/web/src/wasmJsMain/kotlin/Main.kt @@ -13,6 +13,8 @@ import com.example.jetsnack.ui.components.loadImage import com.example.jetsnack.ui.components.toByteArray import com.example.jetsnack.ui.theme.Karla import com.example.jetsnack.ui.theme.Montserrat +import kotlinx.coroutines.joinAll +import kotlinx.coroutines.launch import org.jetbrains.compose.resources.* @OptIn(ExperimentalComposeUiApi::class, ExperimentalResourceApi::class) @@ -31,9 +33,16 @@ fun main() { } LaunchedEffect(Unit) { - loadMontserratFont() - loadKarlaFont() - prepareImagesCache() + val j1 = launch { + loadMontserratFont() + } + val j2 = launch { + loadKarlaFont() + } + val j3 = launch { + prepareImagesCache() + } + joinAll(j1, j2, j3) loading = false } } diff --git a/examples/nav_cupcake/gradle/libs.versions.toml b/examples/nav_cupcake/gradle/libs.versions.toml index 8da5f65617..67901794de 100644 --- a/examples/nav_cupcake/gradle/libs.versions.toml +++ b/examples/nav_cupcake/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -agp = "8.2.0" +agp = "8.5.0" android-compileSdk = "34" android-minSdk = "24" android-targetSdk = "34" @@ -7,9 +7,9 @@ androidx-activity = "1.8.2" androidx-lifecycle = "2.8.0-rc03" androidx-navigation = "2.7.0-alpha06" compose-android = "1.6.7" -compose-multiplatform = "1.6.10" +compose-multiplatform = "1.7.0" junit = "4.13.2" -kotlin = "2.0.0" +kotlin = "2.0.20" kotlinx-datetime = "0.6.0" [libraries] diff --git a/examples/nav_cupcake/gradle/wrapper/gradle-wrapper.properties b/examples/nav_cupcake/gradle/wrapper/gradle-wrapper.properties index 3fa8f862f7..3435e54ff1 100644 --- a/examples/nav_cupcake/gradle/wrapper/gradle-wrapper.properties +++ b/examples/nav_cupcake/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ +#Thu Oct 17 19:23:28 AMT 2024 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/examples/notepad/gradle.properties b/examples/notepad/gradle.properties index cb0d8e12b8..6bce9a309c 100644 --- a/examples/notepad/gradle.properties +++ b/examples/notepad/gradle.properties @@ -1,6 +1,6 @@ org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 kotlin.code.style=official -kotlin.version=2.0.0 -compose.version=1.6.10 +kotlin.version=2.0.20 +compose.version=1.7.1 org.gradle.configuration-cache=true org.gradle.caching=true diff --git a/examples/todoapp-lite/androidApp/build.gradle.kts b/examples/todoapp-lite/androidApp/build.gradle.kts index a132898a20..deb82658af 100755 --- a/examples/todoapp-lite/androidApp/build.gradle.kts +++ b/examples/todoapp-lite/androidApp/build.gradle.kts @@ -18,12 +18,12 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "example.todoapp.lite" defaultConfig { applicationId = "org.jetbrains.TodoAppLite" minSdk = 26 - targetSdk = 34 + targetSdk = 35 versionCode = 1 versionName = "1.0" } diff --git a/examples/todoapp-lite/gradle.properties b/examples/todoapp-lite/gradle.properties index e7adc12149..f0830f4e66 100755 --- a/examples/todoapp-lite/gradle.properties +++ b/examples/todoapp-lite/gradle.properties @@ -10,6 +10,6 @@ kotlin.native.useEmbeddableCompilerJar=true kotlin.mpp.androidSourceSetLayoutVersion=2 # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=2.0.0 -agp.version=8.0.2 -compose.version=1.6.10 +kotlin.version=2.0.20 +agp.version=8.5.0 +compose.version=1.7.1 diff --git a/examples/todoapp-lite/gradle/wrapper/gradle-wrapper.properties b/examples/todoapp-lite/gradle/wrapper/gradle-wrapper.properties index 17655d0ef2..48c0a02ca4 100644 --- a/examples/todoapp-lite/gradle/wrapper/gradle-wrapper.properties +++ b/examples/todoapp-lite/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/examples/todoapp-lite/iosApp/iosApp/Info.plist b/examples/todoapp-lite/iosApp/iosApp/Info.plist index 9a269f5eaa..412e378128 100644 --- a/examples/todoapp-lite/iosApp/iosApp/Info.plist +++ b/examples/todoapp-lite/iosApp/iosApp/Info.plist @@ -20,6 +20,8 @@ 1 LSRequiresIPhoneOS + CADisableMinimumFrameDurationOnPhone + UIApplicationSceneManifest UIApplicationSupportsMultipleScenes diff --git a/examples/todoapp-lite/shared/build.gradle.kts b/examples/todoapp-lite/shared/build.gradle.kts index 0208a8b722..1371124e9f 100755 --- a/examples/todoapp-lite/shared/build.gradle.kts +++ b/examples/todoapp-lite/shared/build.gradle.kts @@ -61,7 +61,7 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "example.todoapp.lite.common" sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") sourceSets["main"].res.srcDirs("src/androidMain/res") diff --git a/examples/widgets-gallery/androidApp/build.gradle.kts b/examples/widgets-gallery/androidApp/build.gradle.kts index 1b91eecaa7..58d9fcd38e 100644 --- a/examples/widgets-gallery/androidApp/build.gradle.kts +++ b/examples/widgets-gallery/androidApp/build.gradle.kts @@ -17,12 +17,12 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.compose.demo.widgets" defaultConfig { applicationId = "org.jetbrains.WidgetsGallery" minSdk = 26 - targetSdk = 34 + targetSdk = 35 versionCode = 1 versionName = "1.0" } diff --git a/examples/widgets-gallery/gradle.properties b/examples/widgets-gallery/gradle.properties index 1b20c5e7a7..b64c7b1c3c 100644 --- a/examples/widgets-gallery/gradle.properties +++ b/examples/widgets-gallery/gradle.properties @@ -10,7 +10,7 @@ kotlin.native.useEmbeddableCompilerJar=true kotlin.mpp.androidSourceSetLayoutVersion=2 # Enable kotlin/native experimental memory model kotlin.native.binary.memoryModel=experimental -kotlin.version=2.0.0 -agp.version=8.0.2 +kotlin.version=2.0.20 +agp.version=8.5.0 # Replace this with release version when it comes out -compose.version=1.6.10 +compose.version=1.7.1 diff --git a/examples/widgets-gallery/gradle/wrapper/gradle-wrapper.properties b/examples/widgets-gallery/gradle/wrapper/gradle-wrapper.properties index 17655d0ef2..48c0a02ca4 100644 --- a/examples/widgets-gallery/gradle/wrapper/gradle-wrapper.properties +++ b/examples/widgets-gallery/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/examples/widgets-gallery/iosApp/iosApp/Info.plist b/examples/widgets-gallery/iosApp/iosApp/Info.plist index 9a269f5eaa..412e378128 100644 --- a/examples/widgets-gallery/iosApp/iosApp/Info.plist +++ b/examples/widgets-gallery/iosApp/iosApp/Info.plist @@ -20,6 +20,8 @@ 1 LSRequiresIPhoneOS + CADisableMinimumFrameDurationOnPhone + UIApplicationSceneManifest UIApplicationSupportsMultipleScenes diff --git a/examples/widgets-gallery/shared/build.gradle.kts b/examples/widgets-gallery/shared/build.gradle.kts index 00b6b2dac5..33f6e137cd 100644 --- a/examples/widgets-gallery/shared/build.gradle.kts +++ b/examples/widgets-gallery/shared/build.gradle.kts @@ -77,7 +77,7 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.compose.demo.widgets.platform" sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") diff --git a/gradle-plugins/build.gradle.kts b/gradle-plugins/build.gradle.kts index c8fc305495..fc57515fbb 100644 --- a/gradle-plugins/build.gradle.kts +++ b/gradle-plugins/build.gradle.kts @@ -1,4 +1,5 @@ -import com.gradle.publish.PluginBundleExtension +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile plugins { @@ -20,8 +21,8 @@ subprojects { plugins.withId("java") { configureIfExists { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 withJavadocJar() withSourcesJar() @@ -30,11 +31,13 @@ subprojects { plugins.withId("org.jetbrains.kotlin.jvm") { tasks.withType(KotlinJvmCompile::class).configureEach { - // must be set to a language version of the kotlin compiler & runtime, - // which is bundled to the oldest supported Gradle - kotlinOptions.languageVersion = "1.5" - kotlinOptions.apiVersion = "1.5" - kotlinOptions.jvmTarget = "1.8" + compilerOptions { + // must be set to a language version of the kotlin compiler & runtime, + // which is bundled to the oldest supported Gradle + languageVersion.set(KotlinVersion.KOTLIN_1_5) + apiVersion.set(KotlinVersion.KOTLIN_1_5) + jvmTarget.set(JvmTarget.JVM_11) + } } } diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerCompatibility.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerCompatibility.kt index 3be60601ff..b32a4d3373 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerCompatibility.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerCompatibility.kt @@ -24,7 +24,8 @@ internal object ComposeCompilerCompatibility { "1.9.21" to "1.5.4", "1.9.22" to "1.5.8.1", "1.9.23" to "1.5.13.5", - "1.9.24" to "1.5.14.1-beta02", + "1.9.24" to "1.5.14.1", + "1.9.25" to "1.5.15", "2.0.0-Beta1" to "1.5.4-dev1-kt2.0.0-Beta1", "2.0.0-Beta4" to "1.5.9-kt-2.0.0-Beta4", "2.0.0-Beta5" to "1.5.11-kt-2.0.0-Beta5", diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerKotlinSupportPlugin.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerKotlinSupportPlugin.kt index 37c87a3a0b..629669ab72 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerKotlinSupportPlugin.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposeCompilerKotlinSupportPlugin.kt @@ -14,7 +14,9 @@ import org.jetbrains.compose.internal.KOTLIN_JVM_PLUGIN_ID import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID import org.jetbrains.compose.internal.Version import org.jetbrains.compose.internal.ideaIsInSyncProvider +import org.jetbrains.compose.internal.mppExtOrNull import org.jetbrains.compose.internal.webExt +import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile import org.jetbrains.kotlin.gradle.plugin.KotlinBasePlugin import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerPluginSupportPlugin @@ -52,6 +54,32 @@ private fun Project.configureComposeCompilerPlugin(kgp: KotlinBasePlugin) { if (Version.fromString(kgpVersion) < Version.fromString(newCompilerIsAvailableVersion)) { logger.info("Apply ComposeCompilerKotlinSupportPlugin (KGP version = $kgpVersion)") project.plugins.apply(ComposeCompilerKotlinSupportPlugin::class.java) + + //legacy logic applied for Kotlin < 2.0 only + project.afterEvaluate { + val composeExtension = project.extensions.getByType(ComposeExtension::class.java) + project.tasks.withType(org.jetbrains.kotlin.gradle.dsl.KotlinCompile::class.java).configureEach { + it.kotlinOptions.apply { + freeCompilerArgs = freeCompilerArgs + + composeExtension.kotlinCompilerPluginArgs.get().flatMap { arg -> + listOf("-P", "plugin:androidx.compose.compiler.plugins.kotlin:$arg") + } + } + } + + val hasAnyWebTarget = project.mppExtOrNull?.targets?.firstOrNull { + it.platformType == KotlinPlatformType.js || + it.platformType == KotlinPlatformType.wasm + } != null + if (hasAnyWebTarget) { + // currently k/wasm compile task is covered by KotlinJsCompile type + project.tasks.withType(KotlinJsCompile::class.java).configureEach { + it.kotlinOptions.freeCompilerArgs += listOf( + "-Xklib-enable-signature-clash-checks=false", + ) + } + } + } } else { //There is no other way to check that the plugin WASN'T applied! afterEvaluate { @@ -76,8 +104,8 @@ class ComposeCompilerKotlinSupportPlugin : KotlinCompilerPluginSupportPlugin { val composeExt = target.extensions.getByType(ComposeExtension::class.java) composeCompilerArtifactProvider = ComposeCompilerArtifactProvider { - composeExt.kotlinCompilerPlugin.orNull ?: - ComposeCompilerCompatibility.compilerVersionFor(target.getKotlinPluginVersion()) + composeExt.kotlinCompilerPlugin.orNull + ?: ComposeCompilerCompatibility.compilerVersionFor(target.getKotlinPluginVersion()) } applicableForPlatformTypes = composeExt.platformTypes diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt index 41e9afd7ef..78301e35b1 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/ComposePlugin.kt @@ -19,17 +19,16 @@ import org.jetbrains.compose.desktop.DesktopExtension import org.jetbrains.compose.desktop.application.internal.configureDesktop import org.jetbrains.compose.desktop.preview.internal.initializePreview import org.jetbrains.compose.experimental.dsl.ExperimentalExtension -import org.jetbrains.compose.experimental.internal.* -import org.jetbrains.compose.internal.* +import org.jetbrains.compose.experimental.internal.configureExperimentalTargetsFlagsCheck +import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID +import org.jetbrains.compose.internal.mppExt import org.jetbrains.compose.internal.utils.currentTarget import org.jetbrains.compose.resources.ResourcesExtension import org.jetbrains.compose.resources.configureComposeResources import org.jetbrains.compose.web.WebExtension import org.jetbrains.compose.web.internal.configureWeb -import org.jetbrains.kotlin.com.github.gundy.semver4j.SemVer -import org.jetbrains.kotlin.gradle.dsl.KotlinCompile -import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile -import org.jetbrains.kotlin.gradle.plugin.* +import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler +import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion internal val composeVersion get() = ComposeBuildConfig.composeVersion @@ -61,32 +60,6 @@ abstract class ComposePlugin : Plugin { val mppExt = project.mppExt project.configureExperimentalTargetsFlagsCheck(mppExt) } - - project.tasks.withType(KotlinCompile::class.java).configureEach { - it.kotlinOptions.apply { - freeCompilerArgs = freeCompilerArgs + - composeExtension.kotlinCompilerPluginArgs.get().flatMap { arg -> - listOf("-P", "plugin:androidx.compose.compiler.plugins.kotlin:$arg") - } - } - } - - disableSignatureClashCheck(project) - } - } - - private fun disableSignatureClashCheck(project: Project) { - val hasAnyWebTarget = project.mppExtOrNull?.targets?.firstOrNull { - it.platformType == KotlinPlatformType.js || - it.platformType == KotlinPlatformType.wasm - } != null - if (hasAnyWebTarget) { - // currently k/wasm compile task is covered by KotlinJsCompile type - project.tasks.withType(KotlinJsCompile::class.java).configureEach { - it.kotlinOptions.freeCompilerArgs += listOf( - "-Xklib-enable-signature-clash-checks=false", - ) - } } } @@ -99,6 +72,7 @@ abstract class ComposePlugin : Plugin { val foundation get() = composeDependency("org.jetbrains.compose.foundation:foundation") val material get() = composeDependency("org.jetbrains.compose.material:material") val material3 get() = composeDependency("org.jetbrains.compose.material3:material3") + val material3AdaptiveNavigationSuite get() = composeDependency("org.jetbrains.compose.material3:material3-adaptive-navigation-suite") val runtime get() = composeDependency("org.jetbrains.compose.runtime:runtime") val runtimeSaveable get() = composeDependency("org.jetbrains.compose.runtime:runtime-saveable") val ui get() = composeDependency("org.jetbrains.compose.ui:ui") @@ -110,7 +84,7 @@ abstract class ComposePlugin : Plugin { val uiTooling get() = composeDependency("org.jetbrains.compose.ui:ui-tooling") val uiUtil get() = composeDependency("org.jetbrains.compose.ui:ui-util") val preview get() = composeDependency("org.jetbrains.compose.ui:ui-tooling-preview") - val materialIconsExtended get() = composeDependency("org.jetbrains.compose.material:material-icons-extended") + val materialIconsExtended get() = "org.jetbrains.compose.material:material-icons-extended:1.7.0-rc01" val components get() = CommonComponentsDependencies @Deprecated("Use compose.html", replaceWith = ReplaceWith("html")) val web: WebDependencies get() = WebDependencies diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/ComposeProjectProperties.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/ComposeProjectProperties.kt index abe936f0b2..f4753ce6ef 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/ComposeProjectProperties.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/ComposeProjectProperties.kt @@ -8,8 +8,10 @@ package org.jetbrains.compose.desktop.application.internal import org.gradle.api.Project import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory +import org.jetbrains.compose.internal.utils.findLocalOrGlobalProperty import org.jetbrains.compose.internal.utils.toBooleanProvider import org.jetbrains.compose.internal.utils.valueOrNull +import org.jetbrains.kotlin.gradle.plugin.extraProperties internal object ComposeProperties { internal const val VERBOSE = "compose.desktop.verbose" @@ -59,7 +61,6 @@ internal object ComposeProperties { providers.valueOrNull(DISABLE_MULTIMODULE_RESOURCES).toBooleanProvider(false) //providers.valueOrNull works only with root gradle.properties - fun dontSyncResources(project: Project): Provider = project.provider { - project.findProperty(SYNC_RESOURCES_PROPERTY)?.toString().equals("false", true) - } + fun dontSyncResources(project: Project): Provider = + project.findLocalOrGlobalProperty(SYNC_RESOURCES_PROPERTY).map { it == "false" } } \ No newline at end of file diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/wixToolset.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/wixToolset.kt index f5f1739d80..fa0afb6bbb 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/wixToolset.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/wixToolset.kt @@ -11,6 +11,7 @@ import org.gradle.api.tasks.Copy import org.jetbrains.compose.desktop.application.tasks.AbstractJPackageTask import org.jetbrains.compose.internal.utils.OS import org.jetbrains.compose.internal.utils.currentOS +import org.jetbrains.compose.internal.utils.findLocalOrGlobalProperty import org.jetbrains.compose.internal.utils.ioFile import java.io.File @@ -32,7 +33,8 @@ internal fun JvmApplicationContext.configureWix() { return } - if (project.findProperty(DOWNLOAD_WIX_PROPERTY) == "false") return + val disableWixDownload = project.findLocalOrGlobalProperty(DOWNLOAD_WIX_PROPERTY).map { it == "false" } + if (disableWixDownload.get()) return val root = project.rootProject val wixDir = project.gradle.gradleUserHomeDir.resolve("compose-jb") diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/internal/checkExperimentalTargets.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/internal/checkExperimentalTargets.kt index a5bb901ee2..92320f02a2 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/internal/checkExperimentalTargets.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/internal/checkExperimentalTargets.kt @@ -6,6 +6,7 @@ package org.jetbrains.compose.experimental.internal import org.gradle.api.Project +import org.jetbrains.compose.internal.utils.findLocalOrGlobalProperty import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinTarget @@ -74,7 +75,8 @@ private fun checkTarget(project: Project, target: KotlinTarget): CheckResult { it.id.displayName.contains(SKIKO_ARTIFACT_PREFIX) } if (containsSkikoArtifact) { - if (project.findProperty(targetType.gradlePropertyName) != "true") { + val targetIsDisabled = project.findLocalOrGlobalProperty(targetType.gradlePropertyName).map { it != "true" } + if (targetIsDisabled.get()) { return CheckResult.Fail(targetType) } } diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/providerUtils.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/providerUtils.kt index 07bd94dd3b..2614dc6094 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/providerUtils.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/internal/utils/providerUtils.kt @@ -5,11 +5,14 @@ package org.jetbrains.compose.internal.utils +import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Property import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory +import org.jetbrains.kotlin.gradle.plugin.extraProperties +import org.gradle.util.GradleVersion internal inline fun ObjectFactory.new(vararg params: Any): T = newInstance(T::class.java, *params) @@ -36,12 +39,19 @@ internal fun ProviderFactory.valueOrNull(prop: String): Provider = } private fun Provider.forUseAtConfigurationTimeSafe(): Provider = - try { - forUseAtConfigurationTime() - } catch (e: NoSuchMethodError) { - // todo: remove once we drop support for Gradle 6.4 + // forUseAtConfigurationTime is a no-op starting at Gradle 7.4 and just produces deprecation warnings. + // See https://docs.gradle.org/current/kotlin-dsl/gradle/org.gradle.api.provider/-provider/for-use-at-configuration-time.html + if (GradleVersion.current() >= GradleVersion.version("7.4")) { this + } else { + // todo: remove once we drop support for Gradle 6.4 + forUseAtConfigurationTime() } internal fun Provider.toBooleanProvider(defaultValue: Boolean): Provider = orElse(defaultValue.toString()).map { "true" == it } + +internal fun Project.findLocalOrGlobalProperty(name: String, default: String = ""): Provider = provider { + if (extraProperties.has(name)) extraProperties.get(name).toString() + else providers.gradleProperty(name).forUseAtConfigurationTimeSafe().getOrElse(default) +} diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/AndroidResources.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/AndroidResources.kt index ac36cf5bb3..0adeed4060 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/AndroidResources.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/AndroidResources.kt @@ -1,24 +1,87 @@ package org.jetbrains.compose.resources +import com.android.build.api.dsl.KotlinMultiplatformAndroidTarget import com.android.build.api.variant.AndroidComponentsExtension -import com.android.build.api.variant.Variant +import com.android.build.api.variant.HasAndroidTest +import com.android.build.api.variant.KotlinMultiplatformAndroidComponentsExtension +import com.android.build.api.variant.Sources import com.android.build.gradle.internal.lint.AndroidLintAnalysisTask import com.android.build.gradle.internal.lint.LintModelWriterTask +import org.gradle.api.DefaultTask import org.gradle.api.Project +import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.FileCollection -import org.gradle.api.tasks.Copy -import org.jetbrains.compose.internal.utils.dir +import org.gradle.api.file.FileSystemOperations +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.IgnoreEmptyDirectories +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction +import org.jetbrains.compose.internal.utils.registerTask import org.jetbrains.compose.internal.utils.uppercaseFirstChar import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget +import java.io.File +import javax.inject.Inject -internal fun Project.getAndroidVariantComposeResources( +//copy all compose resources to android assets +internal fun Project.configureAndroidComposeResources( + agpPluginId: String, + moduleResourceDir: Provider? = null +) { + val kotlinExtension = extensions.findByType(KotlinMultiplatformExtension::class.java) ?: return + + if (agpPluginId != AGP_KMP_LIB_ID) { + extensions.findByType(AndroidComponentsExtension::class.java)?.let { androidComponents -> + configureAndroidComposeResources(kotlinExtension, androidComponents, moduleResourceDir) + } + } else { + @Suppress("UnstableApiUsage") + extensions.findByType(KotlinMultiplatformAndroidComponentsExtension::class.java)?.let { androidComponents -> + configureAndroidComposeResources(kotlinExtension, androidComponents, moduleResourceDir) + } + } +} + +private fun Project.configureAndroidComposeResources( + kotlinExtension: KotlinMultiplatformExtension, + androidComponents: AndroidComponentsExtension<*, *, *>, + moduleResourceDir: Provider? +) { + logger.info("Configure compose resources with AndroidComponentsExtension") + androidComponents.onVariants { variant -> + val componentAssets = getAndroidComponentComposeResources(kotlinExtension, variant.name) + configureGeneratedAndroidComponentAssets( + variant.name, + variant.sources, + componentAssets, + moduleResourceDir + ) + + if (variant is HasAndroidTest) { + variant.androidTest?.let { androidTest -> + val androidTestAssets = getAndroidComponentComposeResources(kotlinExtension, androidTest.name) + configureGeneratedAndroidComponentAssets( + androidTest.name, + androidTest.sources, + androidTestAssets, + moduleResourceDir + ) + } + } + } +} + +private fun Project.getAndroidComponentComposeResources( kotlinExtension: KotlinMultiplatformExtension, - variant: Variant + componentName: String ): FileCollection = project.files({ kotlinExtension.targets.withType(KotlinAndroidTarget::class.java).flatMap { androidTarget -> androidTarget.compilations.flatMap { compilation -> - if (compilation.androidVariant.name == variant.name) { + if (compilation.androidVariant.name == componentName) { compilation.allKotlinSourceSets.map { kotlinSourceSet -> getPreparedComposeResourcesDir(kotlinSourceSet) } @@ -27,44 +90,107 @@ internal fun Project.getAndroidVariantComposeResources( } }) -internal fun Project.getKgpAndroidVariantComposeResources( - variant: Variant +@Suppress("UnstableApiUsage") +private fun Project.configureAndroidComposeResources( + kotlinExtension: KotlinMultiplatformExtension, + androidComponents: KotlinMultiplatformAndroidComponentsExtension, + moduleResourceDir: Provider? +) { + logger.info("Configure compose resources with KotlinMultiplatformAndroidComponentsExtension") + androidComponents.onVariant { variant -> + val variantAssets = getAndroidKmpComponentComposeResources(kotlinExtension, variant.name) + configureGeneratedAndroidComponentAssets( + variant.name, + variant.sources, + variantAssets, + moduleResourceDir + ) + + variant.androidTest?.let { androidTest -> + val androidTestAssets = getAndroidKmpComponentComposeResources(kotlinExtension, androidTest.name) + configureGeneratedAndroidComponentAssets( + androidTest.name, + androidTest.sources, + androidTestAssets, + moduleResourceDir + ) + } + } +} + +@Suppress("UnstableApiUsage") +private fun Project.getAndroidKmpComponentComposeResources( + kotlinExtension: KotlinMultiplatformExtension, + componentName: String ): FileCollection = project.files({ - val taskName = "${variant.name}AssetsCopyForAGP" - if (tasks.names.contains(taskName)) tasks.named(taskName).map { it.outputs.files } - else files() + kotlinExtension.targets.withType(KotlinMultiplatformAndroidTarget::class.java).flatMap { androidTarget -> + androidTarget.compilations.flatMap { compilation -> + if (compilation.componentName == componentName) { + compilation.allKotlinSourceSets.map { kotlinSourceSet -> + getPreparedComposeResourcesDir(kotlinSourceSet) + } + } else emptyList() + } + } }) -internal fun Project.configureAndroidComposeResources( - getVariantComposeResources: (Variant) -> FileCollection +private fun Project.configureGeneratedAndroidComponentAssets( + componentName: String, + componentSources: Sources, + componentAssets: FileCollection, + moduleResourceDir: Provider? ) { - //copy all compose resources to android assets - val androidComponents = project.extensions.findByType(AndroidComponentsExtension::class.java) ?: return - androidComponents.onVariants { variant -> - val variantAssets = getVariantComposeResources(variant) - val variantAssetsDir = layout.buildDirectory.dir(RES_GEN_DIR).dir(variant.name + "AndroidAssets") - - val copyVariantAssets = tasks.register( - "copy${variant.name.uppercaseFirstChar()}ComposeResourcesToAndroidAssets", - Copy::class.java - ) { task -> - task.from(variantAssets) - task.into(variantAssetsDir) + logger.info("Configure $componentName resources for 'android' target") + + val camelComponentName = componentName.uppercaseFirstChar() + val copyComponentAssets = registerTask( + "copy${camelComponentName}ComposeResourcesToAndroidAssets" + ) { + from.set(componentAssets) + moduleResourceDir?.let { relativeResourcePlacement.set(it) } + } + + componentSources.assets?.addGeneratedSourceDirectory( + copyComponentAssets, + CopyResourcesToAndroidAssetsTask::outputDirectory + ) + tasks.configureEach { task -> + //fix agp task dependencies for AndroidStudio preview + if (task.name == "compile${camelComponentName}Sources") { + task.dependsOn(copyComponentAssets) + } + //fix linter task dependencies for `build` task + if (task is AndroidLintAnalysisTask || task is LintModelWriterTask) { + task.mustRunAfter(copyComponentAssets) } + } +} - //https://issuetracker.google.com/348208777 - variant.sources.assets?.addStaticSourceDirectory(variantAssetsDir.get().asFile.path) - tasks.configureEach { task -> - if (task.name == "merge${variant.name.uppercaseFirstChar()}Assets") { - task.dependsOn(copyVariantAssets) - } - //fix task dependencies for AndroidStudio preview - if (task.name == "compile${variant.name.uppercaseFirstChar()}Sources") { - task.dependsOn(copyVariantAssets) - } - //fix linter task dependencies for `build` task - if (task is AndroidLintAnalysisTask || task is LintModelWriterTask) { - task.mustRunAfter(copyVariantAssets) +//Copy task doesn't work with 'variant.sources?.assets?.addGeneratedSourceDirectory' API +internal abstract class CopyResourcesToAndroidAssetsTask : DefaultTask() { + @get:Inject + abstract val fileSystem: FileSystemOperations + + @get:InputFiles + @get:IgnoreEmptyDirectories + abstract val from: Property + + @get:Input + @get:Optional + abstract val relativeResourcePlacement: Property + + @get:OutputDirectory + abstract val outputDirectory: DirectoryProperty + + @TaskAction + fun action() { + fileSystem.copy { + it.includeEmptyDirs = false + it.from(from) + if (relativeResourcePlacement.isPresent) { + it.into(outputDirectory.dir(relativeResourcePlacement.get().path)) + } else { + it.into(outputDirectory) } } } @@ -86,4 +212,4 @@ internal fun Project.fixAndroidLintTaskDependencies() { }.configureEach { it.mustRunAfter(tasks.withType(GenerateResourceAccessorsTask::class.java)) } -} \ No newline at end of file +} diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/AssembleTargetResourcesTask.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/AssembleTargetResourcesTask.kt new file mode 100644 index 0000000000..556b8e1c9e --- /dev/null +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/AssembleTargetResourcesTask.kt @@ -0,0 +1,56 @@ +package org.jetbrains.compose.resources + +import org.gradle.api.DefaultTask +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.file.DuplicatesStrategy +import org.gradle.api.file.FileSystemOperations +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputFiles +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.PathSensitive +import org.gradle.api.tasks.PathSensitivity +import org.gradle.api.tasks.TaskAction +import org.gradle.work.DisableCachingByDefault +import java.io.File +import javax.inject.Inject + +@DisableCachingByDefault(because = "There is no logic, just copy files") +internal abstract class AssembleTargetResourcesTask : DefaultTask() { + + @get:Inject + abstract val fileSystem: FileSystemOperations + + @get:InputFiles + @get:PathSensitive(PathSensitivity.RELATIVE) + abstract val resourceDirectories: ConfigurableFileCollection + + @get:Input + abstract val relativeResourcePlacement: Property + + @get:OutputDirectory + abstract val outputDirectory: DirectoryProperty + + @TaskAction + fun action() { + val outputDirectoryFile = outputDirectory.get().asFile + if (outputDirectoryFile.exists()) { + outputDirectoryFile.deleteRecursively() + } + outputDirectoryFile.mkdirs() + + fileSystem.copy { copy -> + resourceDirectories.files.forEach { dir -> + copy.from(dir) + } + copy.into(outputDirectoryFile.resolve(relativeResourcePlacement.get())) + copy.duplicatesStrategy = DuplicatesStrategy.INCLUDE + } + + if (outputDirectoryFile.listFiles()?.isEmpty() != false) { + // Output an empty directory for the zip task + outputDirectoryFile.resolve(relativeResourcePlacement.get()).mkdirs() + } + } +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResources.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResources.kt index 2a85d3e2bd..e0126d6cb6 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResources.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/ComposeResources.kt @@ -2,25 +2,22 @@ package org.jetbrains.compose.resources import org.gradle.api.Project import org.gradle.api.provider.Provider -import org.gradle.api.tasks.SourceSet import org.gradle.util.GradleVersion import org.jetbrains.compose.desktop.application.internal.ComposeProperties import org.jetbrains.compose.internal.KOTLIN_JVM_PLUGIN_ID import org.jetbrains.compose.internal.KOTLIN_MPP_PLUGIN_ID +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension import org.jetbrains.kotlin.gradle.plugin.KotlinBasePlugin -import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet import org.jetbrains.kotlin.gradle.plugin.extraProperties internal const val COMPOSE_RESOURCES_DIR = "composeResources" internal const val RES_GEN_DIR = "generated/compose/resourceGenerator" -private const val KMP_RES_EXT = "multiplatformResourcesPublication" +internal const val KMP_RES_EXT = "multiplatformResourcesPublication" private const val MIN_GRADLE_VERSION_FOR_KMP_RESOURCES = "7.6" -private val androidPluginIds = listOf( - "com.android.application", - "com.android.library" -) +private const val AGP_APP_ID = "com.android.application" +private const val AGP_LIB_ID = "com.android.library" +internal const val AGP_KMP_LIB_ID = "com.android.kotlin.multiplatform.library" internal fun Project.configureComposeResources(extension: ResourcesExtension) { val config = provider { extension } @@ -38,17 +35,7 @@ private fun Project.onKgpApplied(config: Provider, kgp: Kotl val kmpResourcesAreAvailable = !disableMultimoduleResources && hasKmpResources && currentGradleVersion >= minGradleVersion if (kmpResourcesAreAvailable) { - configureKmpResources(kotlinExtension, extraProperties.get(KMP_RES_EXT)!!, config) - onAgpApplied { - //workaround to fix AndroidStudio preview works with compose resources: - //it copies android assets and mark it as a static assets dir - //yes, the same resources will be registered in AGP twice: from KGP and here as static dirs - //but it works fine and there are no problems during merge android assets - configureAndroidComposeResources { variant -> - getKgpAndroidVariantComposeResources(variant) - } - fixAndroidLintTaskDependencies() - } + configureMultimoduleResources(kotlinExtension, config) } else { if (!disableMultimoduleResources) { if (!hasKmpResources) logger.info( @@ -65,52 +52,19 @@ private fun Project.onKgpApplied(config: Provider, kgp: Kotl ) } - val commonMain = KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME - configureComposeResources(kotlinExtension, commonMain, config) - - onAgpApplied { - configureAndroidComposeResources { variant -> - getAndroidVariantComposeResources(kotlinExtension, variant) - } - fixAndroidLintTaskDependencies() - } + configureSinglemoduleResources(kotlinExtension, config) } configureSyncIosComposeResources(kotlinExtension) } -private fun Project.onAgpApplied(block: () -> Unit) { - androidPluginIds.forEach { pluginId -> - plugins.withId(pluginId) { - block() - } - } +internal fun Project.onKotlinJvmApplied(config: Provider) { + val kotlinExtension = project.extensions.getByType(KotlinJvmProjectExtension::class.java) + configureJvmOnlyResources(kotlinExtension, config) } -private fun Project.onKotlinJvmApplied(config: Provider) { - val kotlinExtension = project.extensions.getByType(KotlinProjectExtension::class.java) - val main = SourceSet.MAIN_SOURCE_SET_NAME - configureComposeResources(kotlinExtension, main, config) -} - -private fun Project.configureComposeResources( - kotlinExtension: KotlinProjectExtension, - resClassSourceSetName: String, - config: Provider -) { - logger.info("Configure compose resources") - configureComposeResourcesGeneration(kotlinExtension, resClassSourceSetName, config, false) - - // mark prepared resources as sourceSet.resources - // 1) it automatically packs the resources to JVM jars - // 2) it configures the webpack to use the resources - // 3) for native targets we will use source set resources to pack them into the final app. see IosResources.kt - // 4) for the android it DOESN'T pack resources! we copy resources to assets in AndroidResources.kt - kotlinExtension.sourceSets.all { sourceSet -> - // the HACK is here because KGP copy androidMain java resources to Android target - // if the resources were registered in the androidMain source set before the target declaration - afterEvaluate { - sourceSet.resources.srcDirs(getPreparedComposeResourcesDir(sourceSet)) - } +internal fun Project.onAgpApplied(block: (pluginId: String) -> Unit) { + listOf(AGP_APP_ID, AGP_LIB_ID, AGP_KMP_LIB_ID).forEach { pluginId -> + plugins.withId(pluginId) { block(pluginId) } } } diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/IosResources.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/IosResources.kt index ae31edbafb..ccb994d4ef 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/IosResources.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/IosResources.kt @@ -33,7 +33,7 @@ internal fun Project.configureSyncIosComposeResources( } kotlinExtension.targets.withType(KotlinNativeTarget::class.java).all { nativeTarget -> - if (nativeTarget.isIosTarget()) { + if (nativeTarget.isIosOrMacTarget()) { nativeTarget.binaries.withType(Framework::class.java).all { iosFramework -> val frameworkClassifier = iosFramework.getClassifier() val checkNoSandboxTask = tasks.registerOrConfigure( @@ -86,8 +86,8 @@ internal fun Project.configureSyncIosComposeResources( plugins.withId(COCOAPODS_PLUGIN_ID) { (kotlinExtension as ExtensionAware).extensions.getByType(CocoapodsExtension::class.java).apply { framework { podFramework -> - val syncDir = podFramework.getFinalResourcesDir().get().asFile.relativeTo(projectDir) - val specAttr = "['${syncDir.path}']" + val syncDir = podFramework.getFinalResourcesDir().get().asFile + val specAttr = "['${syncDir.relativeTo(projectDir).path}']" val specAttributes = extraSpecAttributes val buildFile = project.buildFile val projectPath = project.path @@ -97,7 +97,7 @@ internal fun Project.configureSyncIosComposeResources( if (specAttributes["resources"] != specAttr) error( """ |Kotlin.cocoapods.extraSpecAttributes["resources"] is not compatible with Compose Multiplatform's resources management for iOS. - | * Recommended action: remove extraSpecAttributes["resources"] from '$buildFile' and run '$projectPath:podInstall' once; + | * Recommended action: remove extraSpecAttributes["resources"] from '$buildFile' and run '$projectPath:podspec' once; | * Alternative action: turn off Compose Multiplatform's resources management for iOS by adding '${ComposeProperties.SYNC_RESOURCES_PROPERTY}=false' to your gradle.properties; """.trimMargin() ) @@ -116,6 +116,7 @@ private fun Framework.getClassifier(): String { } internal fun Framework.getSyncResourcesTaskName() = "sync${getClassifier()}ComposeResourcesForIos" + private fun Framework.isCocoapodsFramework() = name.startsWith("pod") private fun Framework.getFinalResourcesDir(): Provider { @@ -125,9 +126,9 @@ private fun Framework.getFinalResourcesDir(): Provider { } else { providers.environmentVariable("BUILT_PRODUCTS_DIR") .zip( - providers.environmentVariable("CONTENTS_FOLDER_PATH") - ) { builtProductsDir, contentsFolderPath -> - File("$builtProductsDir/$contentsFolderPath/$IOS_COMPOSE_RESOURCES_ROOT_DIR").canonicalPath + providers.environmentVariable("UNLOCALIZED_RESOURCES_FOLDER_PATH") + ) { builtProductsDir, unlocalizedResourcesFolderPath -> + File("$builtProductsDir/$unlocalizedResourcesFolderPath/$IOS_COMPOSE_RESOURCES_ROOT_DIR").canonicalPath } .flatMap { project.objects.directoryProperty().apply { set(File(it)) } @@ -142,4 +143,10 @@ private fun KotlinNativeTarget.isIosDeviceTarget(): Boolean = konanTarget === KonanTarget.IOS_ARM64 private fun KotlinNativeTarget.isIosTarget(): Boolean = - isIosSimulatorTarget() || isIosDeviceTarget() \ No newline at end of file + isIosSimulatorTarget() || isIosDeviceTarget() + +private fun KotlinNativeTarget.isMacTarget(): Boolean = + konanTarget === KonanTarget.MACOS_X64 || konanTarget === KonanTarget.MACOS_ARM64 + +private fun KotlinNativeTarget.isIosOrMacTarget(): Boolean = + isIosTarget() || isMacTarget() diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/IosResourcesTasks.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/IosResourcesTasks.kt index b024e9412b..62afc07983 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/IosResourcesTasks.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/IosResourcesTasks.kt @@ -118,7 +118,17 @@ private fun getRequestedKonanTargetsByXcode(platform: String, archs: List error("Unknown iOS platform: '$platform'") + platform.startsWith("macosx") -> { + targets.addAll(archs.map { arch -> + when (arch) { + "arm64" -> KonanTarget.MACOS_ARM64 + "x86_64" -> KonanTarget.MACOS_X64 + else -> error("Unknown macOS arch: '$arch'") + } + }) + } + + else -> error("Unknown Apple platform: '$platform'") } return targets.toList() diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/KmpResources.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/KmpResources.kt deleted file mode 100644 index 5ace0c22a9..0000000000 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/KmpResources.kt +++ /dev/null @@ -1,95 +0,0 @@ -package org.jetbrains.compose.resources - -import org.gradle.api.Project -import org.gradle.api.provider.Provider -import org.jetbrains.kotlin.gradle.ComposeKotlinGradlePluginApi -import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension -import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension -import org.jetbrains.kotlin.gradle.plugin.* -import org.jetbrains.kotlin.gradle.plugin.mpp.* -import org.jetbrains.kotlin.gradle.plugin.mpp.resources.KotlinTargetResourcesPublication -import java.io.File - - -@OptIn(ComposeKotlinGradlePluginApi::class) -internal fun Project.configureKmpResources( - kotlinExtension: KotlinProjectExtension, - kmpResources: Any, - config: Provider -) { - kotlinExtension as KotlinMultiplatformExtension - kmpResources as KotlinTargetResourcesPublication - - logger.info("Configure KMP resources") - - val commonMain = KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME - configureComposeResourcesGeneration(kotlinExtension, commonMain, config, true) - - //configure KMP resources publishing for each supported target - kotlinExtension.targets - .matching { target -> kmpResources.canPublishResources(target) } - .all { target -> - logger.info("Configure resources publication for '${target.targetName}' target") - val packedResourceDir = config.getModuleResourcesDir(project) - - if (target !is KotlinAndroidTarget) { - kmpResources.publishResourcesAsKotlinComponent( - target, - { sourceSet -> - KotlinTargetResourcesPublication.ResourceRoot( - getPreparedComposeResourcesDir(sourceSet), - emptyList(), - emptyList() - ) - }, - packedResourceDir - ) - } else { - //for android target publish resources in assets - kmpResources.publishInAndroidAssets( - target, - { sourceSet -> - KotlinTargetResourcesPublication.ResourceRoot( - getPreparedComposeResourcesDir(sourceSet), - emptyList(), - emptyList() - ) - }, - packedResourceDir - ) - } - } - - //add all resolved resources for browser and native compilations - val platformsForSetupCompilation = listOf(KotlinPlatformType.native, KotlinPlatformType.js, KotlinPlatformType.wasm) - kotlinExtension.targets - .matching { target -> target.platformType in platformsForSetupCompilation } - .all { target: KotlinTarget -> - val allResources = kmpResources.resolveResources(target) - target.compilations.all { compilation -> - if (compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME) { - configureResourcesForCompilation(compilation, allResources) - } - } - } -} - -/** - * Add resolved resources to a kotlin compilation to include it into a resulting platform artefact - * It is required for JS and Native targets. - * For JVM and Android it works automatically via jar files - */ -private fun Project.configureResourcesForCompilation( - compilation: KotlinCompilation<*>, - directoryWithAllResourcesForCompilation: Provider -) { - logger.info("Add all resolved resources to '${compilation.target.targetName}' target '${compilation.name}' compilation") - compilation.defaultSourceSet.resources.srcDir(directoryWithAllResourcesForCompilation) - - //JS packaging requires explicit dependency - if (compilation is KotlinJsCompilation) { - tasks.named(compilation.processResourcesTaskName).configure { processResourcesTask -> - processResourcesTask.dependsOn(directoryWithAllResourcesForCompilation) - } - } -} \ No newline at end of file diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/MultimoduleResources.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/MultimoduleResources.kt new file mode 100644 index 0000000000..b34fc9accc --- /dev/null +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/MultimoduleResources.kt @@ -0,0 +1,166 @@ +package org.jetbrains.compose.resources + +import com.android.build.api.dsl.KotlinMultiplatformAndroidTarget +import org.gradle.api.Project +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.SourceSet +import org.jetbrains.compose.internal.utils.registerTask +import org.jetbrains.compose.internal.utils.uppercaseFirstChar +import org.jetbrains.kotlin.gradle.ComposeKotlinGradlePluginApi +import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation +import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet +import org.jetbrains.kotlin.gradle.plugin.KotlinTarget +import org.jetbrains.kotlin.gradle.plugin.extraProperties +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinAndroidTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinJsCompilation +import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.resources.KotlinTargetResourcesPublication +import java.io.File + +//configure multi-module resources (with publishing and module isolation) +internal fun Project.configureMultimoduleResources( + kotlinExtension: KotlinMultiplatformExtension, + config: Provider +) { + logger.info("Configure multi-module compose resources") + + val commonMain = KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME + configureComposeResourcesGeneration(kotlinExtension, commonMain, config, true) + + val moduleIsolationDirectory = config.getModuleResourcesDir(project) + + kotlinExtension.targets + .matching { target -> !target.skipResourcesConfiguration() } + .all { target -> configureTargetResources(target, moduleIsolationDirectory) } + + + //configure ANDROID resources + onAgpApplied { agpId -> + configureAndroidComposeResources(agpId, moduleIsolationDirectory) + fixAndroidLintTaskDependencies() + } +} + +//configure java multi-module resources (with module isolation) +internal fun Project.configureJvmOnlyResources( + kotlinExtension: KotlinJvmProjectExtension, + config: Provider +) { + logger.info("Configure java-only compose resources") + + val main = SourceSet.MAIN_SOURCE_SET_NAME + configureComposeResourcesGeneration(kotlinExtension, main, config, true) + + val moduleIsolationDirectory = config.getModuleResourcesDir(project) + val javaTarget = kotlinExtension.target + + configureTargetResources(javaTarget, moduleIsolationDirectory) +} + +private fun Project.configureTargetResources( + target: KotlinTarget, + moduleIsolationDirectory: Provider +) { + target.compilations.all { compilation -> + logger.info("Configure ${compilation.name} resources for '${target.targetName}' target") + val compilationResources = files({ + compilation.allKotlinSourceSets.map { sourceSet -> getPreparedComposeResourcesDir(sourceSet) } + }) + val assembleResTask = registerTask( + name = "assemble${target.targetName.uppercaseFirstChar()}${compilation.name.uppercaseFirstChar()}Resources" + ) { + resourceDirectories.setFrom(compilationResources) + relativeResourcePlacement.set(moduleIsolationDirectory) + outputDirectory.set( + layout.buildDirectory.dir( + "$RES_GEN_DIR/assembledResources/${target.targetName}${compilation.name.uppercaseFirstChar()}" + ) + ) + } + val allCompilationResources = assembleResTask.flatMap { it.outputDirectory.asFile } + + if ( + target.platformType in platformsForSetupKmpResources + && compilation.name == KotlinCompilation.MAIN_COMPILATION_NAME + ) { + configureKmpResources(compilation, allCompilationResources) + } else { + configureResourcesForCompilation(compilation, allCompilationResources) + } + } +} + +private fun KotlinTarget.skipResourcesConfiguration(): Boolean = when { + this is KotlinMetadataTarget -> true + + //android resources should be configured via AGP + this is KotlinAndroidTarget -> true + + //new AGP library target + this.isMultiplatformAndroidTarget() -> true + + else -> false +} + +@Suppress("UnstableApiUsage") +private fun KotlinTarget.isMultiplatformAndroidTarget(): Boolean = try { + this is KotlinMultiplatformAndroidTarget +} catch (e: NoClassDefFoundError) { + false +} + +private val platformsForSetupKmpResources = listOf( + KotlinPlatformType.native, KotlinPlatformType.js, KotlinPlatformType.wasm +) + +@OptIn(ComposeKotlinGradlePluginApi::class) +private fun Project.configureKmpResources( + compilation: KotlinCompilation<*>, + allCompilationResources: Provider +) { + require(compilation.platformType in platformsForSetupKmpResources) + val kmpResources = extraProperties.get(KMP_RES_EXT) as KotlinTargetResourcesPublication + + //For Native/Js/Wasm main resources: + // 1) we have to configure new Kotlin component publication + // 2) we have to collect all transitive main resources + + //TODO temporary API misuse. will be changed on the KMP side + //https://youtrack.jetbrains.com/issue/KT-70909 + val target = compilation.target + val kmpEmptyPath = provider { File("") } + val emptyDir = layout.buildDirectory.dir("$RES_GEN_DIR/emptyResourcesDir").map { it.asFile } + logger.info("Configure KMP component publication for '${compilation.target.targetName}'") + kmpResources.publishResourcesAsKotlinComponent( + target, + { kotlinSourceSet -> + if (kotlinSourceSet == compilation.defaultSourceSet) { + KotlinTargetResourcesPublication.ResourceRoot(allCompilationResources, emptyList(), emptyList()) + } else { + KotlinTargetResourcesPublication.ResourceRoot(emptyDir, emptyList(), emptyList()) + } + }, + kmpEmptyPath + ) + + val allResources = kmpResources.resolveResources(target) + logger.info("Collect resolved ${compilation.name} resources for '${compilation.target.targetName}'") + configureResourcesForCompilation(compilation, allResources) +} + +private fun Project.configureResourcesForCompilation( + compilation: KotlinCompilation<*>, + directoryWithAllResourcesForCompilation: Provider +) { + compilation.defaultSourceSet.resources.srcDir(directoryWithAllResourcesForCompilation) + + //JS packaging requires explicit dependency + if (compilation is KotlinJsCompilation) { + tasks.named(compilation.processResourcesTaskName).configure { processResourcesTask -> + processResourcesTask.dependsOn(directoryWithAllResourcesForCompilation) + } + } +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/SinglemoduleResources.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/SinglemoduleResources.kt new file mode 100644 index 0000000000..a5a52c5e04 --- /dev/null +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/resources/SinglemoduleResources.kt @@ -0,0 +1,34 @@ +package org.jetbrains.compose.resources + +import org.gradle.api.Project +import org.gradle.api.provider.Provider +import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet + +//configure single-module resources (no publishing, no module isolation) +internal fun Project.configureSinglemoduleResources( + kotlinExtension: KotlinMultiplatformExtension, + config: Provider +) { + logger.info("Configure single-module compose resources") + val commonMain = KotlinSourceSet.COMMON_MAIN_SOURCE_SET_NAME + configureComposeResourcesGeneration(kotlinExtension, commonMain, config, false) + + // mark prepared resources as sourceSet.resources + // 1) it automatically packs the resources to JVM jars + // 2) it configures the webpack to use the resources + // 3) for native targets we will use source set resources to pack them into the final app. see IosResources.kt + // 4) for the android it DOESN'T pack resources! we copy resources to assets in AndroidResources.kt + kotlinExtension.sourceSets.all { sourceSet -> + // the HACK is here because KGP copy androidMain java resources to Android target + // if the resources were registered in the androidMain source set before the target declaration + afterEvaluate { + sourceSet.resources.srcDirs(getPreparedComposeResourcesDir(sourceSet)) + } + } + + onAgpApplied { agpId -> + configureAndroidComposeResources(agpId) + fixAndroidLintTaskDependencies() + } +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/internal/configureWebApplication.kt b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/internal/configureWebApplication.kt index 79b68b8227..f49259f424 100644 --- a/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/internal/configureWebApplication.kt +++ b/gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/web/internal/configureWebApplication.kt @@ -10,13 +10,19 @@ import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ResolvedDependency import org.gradle.api.artifacts.UnresolvedDependency import org.gradle.api.artifacts.component.ModuleComponentIdentifier +import org.gradle.api.file.DuplicatesStrategy import org.gradle.api.provider.Provider +import org.gradle.api.tasks.Copy +import org.gradle.language.jvm.tasks.ProcessResources import org.jetbrains.compose.ComposeBuildConfig import org.jetbrains.compose.ComposeExtension import org.jetbrains.compose.internal.utils.detachedComposeDependency +import org.jetbrains.compose.internal.utils.file import org.jetbrains.compose.internal.utils.registerTask import org.jetbrains.compose.web.WebExtension import org.jetbrains.compose.web.tasks.UnpackSkikoWasmRuntimeTask +import org.jetbrains.kotlin.gradle.targets.js.KotlinWasmTargetType +import org.jetbrains.kotlin.gradle.targets.js.ir.KotlinJsIrTarget import org.jetbrains.kotlin.gradle.tasks.IncrementalSyncTask internal fun Project.configureWeb( @@ -46,13 +52,16 @@ internal fun Project.configureWeb( } } + val targets = webExt.targetsToConfigure(project) + // configure only if there is k/wasm or k/js target: - if (webExt.targetsToConfigure(project).isNotEmpty()) { - configureWebApplication(project, shouldRunUnpackSkiko) + if (targets.isNotEmpty()) { + configureWebApplication(targets, project, shouldRunUnpackSkiko) } } internal fun configureWebApplication( + targets: Collection, project: Project, shouldRunUnpackSkiko: Provider ) { @@ -64,7 +73,8 @@ internal fun configureWebApplication( it.addLater(skikoJsWasmRuntimeDependency) } - val unpackedRuntimeDir = project.layout.buildDirectory.dir("compose/skiko-wasm") + val unpackedRuntimeDir = project.layout.buildDirectory.dir("compose/skiko-for-web-runtime") + val processedRuntimeDir = project.layout.buildDirectory.dir("compose/skiko-runtime-processed-wasmjs") val taskName = "unpackSkikoWasmRuntime" val unpackRuntime = project.registerTask(taskName) { @@ -76,9 +86,48 @@ internal fun configureWebApplication( outputDir.set(unpackedRuntimeDir) } - project.tasks.withType(IncrementalSyncTask::class.java) { - it.dependsOn(unpackRuntime) - it.from.from(unpackedRuntimeDir) + val processSkikoRuntimeForKWasm = project.registerTask("processSkikoRuntimeForKWasm") { + dependsOn(unpackRuntime) + from(unpackedRuntimeDir) + into(processedRuntimeDir) + + doLast { + // TODO: in the next versions we can simply filter skiko.js out for k/wasm target + processedRuntimeDir.file("skiko.js").get().apply { + asFile.appendText("\n\n// Warn about skiko.js redundancy in case of K/Wasm target:\n") + asFile.appendText( + """console.warn("Note: skiko.js is redundant in K/Wasm Compose for Web applications. + |Consider removing it from index.html, + |it will be removed from the distribution in next Compose Multiplatform versions"); + """.trimMargin().replace("\n", "") + ) + } + } + } + + targets.forEach { target -> + target.compilations.all { compilation -> + // `wasmTargetType` is available starting with kotlin 1.9.2x + if (target.wasmTargetType != null) { + // Kotlin/Wasm uses ES module system to depend on skiko through skiko.mjs. + // Further bundler could process all files by its own (both skiko.mjs and skiko.wasm) and then emits its own version. + // So that’s why we need to provide skiko.mjs and skiko.wasm only for webpack, but not in the final dist. + compilation.binaries.all { + it.linkSyncTask.configure { + it.dependsOn(processSkikoRuntimeForKWasm) + it.from.from(processedRuntimeDir) + } + } + } else { + // Kotlin/JS depends on Skiko through global space. + // Bundler cannot know anything about global externals, so that’s why we need to copy it to final dist + project.tasks.named(compilation.processResourcesTaskName, ProcessResources::class.java) { + it.from(unpackedRuntimeDir) + it.dependsOn(unpackRuntime) + it.exclude("META-INF") + } + } + } } } diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt index 261b32054c..03be0f1967 100644 --- a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/GradlePluginTest.kt @@ -11,6 +11,7 @@ import org.gradle.util.GradleVersion import org.jetbrains.compose.desktop.ui.tooling.preview.rpc.PreviewLogger import org.jetbrains.compose.desktop.ui.tooling.preview.rpc.RemoteConnection import org.jetbrains.compose.desktop.ui.tooling.preview.rpc.receiveConfigFromGradle +import org.jetbrains.compose.internal.Version import org.jetbrains.compose.test.utils.GradlePluginTestBase import org.jetbrains.compose.test.utils.checkExists import org.jetbrains.compose.test.utils.checks @@ -46,9 +47,11 @@ class GradlePluginTest : GradlePluginTestBase() { jsCanvasEnabled(true) gradle(":build").checks { check.taskSuccessful(":unpackSkikoWasmRuntime") + check.taskSuccessful(":processSkikoRuntimeForKWasm") check.taskSuccessful(":compileKotlinJs") check.taskSuccessful(":compileKotlinWasmJs") check.taskSuccessful(":wasmJsBrowserDistribution") + check.taskSuccessful(":jsBrowserDistribution") file("./build/dist/wasmJs/productionExecutable").apply { checkExists() @@ -61,12 +64,22 @@ class GradlePluginTest : GradlePluginTestBase() { // one file is the app wasm file and another one is skiko wasm file with a mangled name assertEquals(2, distributionFiles.filter { it.endsWith(".wasm") }.size) } + + file("./build/dist/js/productionExecutable").apply { + checkExists() + assertTrue(isDirectory) + val distributionFiles = listFiles()!!.map { it.name }.toList() + assertTrue(distributionFiles.contains("skiko.wasm")) + assertTrue(distributionFiles.contains("skiko.js")) + assertFalse(this.resolve("skiko.js").readText().contains("skiko.js is redundant")) + } } } @Test fun newAndroidTarget() { - Assumptions.assumeTrue(defaultTestEnvironment.parsedGradleVersion >= GradleVersion.version("8.0.0")) + Assumptions.assumeTrue(defaultTestEnvironment.parsedGradleVersion >= GradleVersion.version("8.10.2")) + Assumptions.assumeTrue(Version.fromString(defaultTestEnvironment.agpVersion) >= Version.fromString("8.8.0-alpha08")) with(testProject("application/newAndroidTarget")) { gradle("build", "--dry-run").checks { } diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/KotlinCompatibilityTest.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/KotlinCompatibilityTest.kt index 0a452fd67c..8d2ef522a0 100644 --- a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/KotlinCompatibilityTest.kt +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/KotlinCompatibilityTest.kt @@ -16,7 +16,7 @@ class KotlinCompatibilityTest : GradlePluginTestBase() { fun testKotlinMpp_1_9_10() = testMpp("1.9.10") @Test - fun testKotlinJsMpp_1_9_10() = testJsMpp("1.9.10") + fun testKotlinJsMpp_1_9_24() = testJsMpp("1.9.24") @Test fun testKotlinMpp_1_9_20() = testMpp("1.9.20") diff --git a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/ResourcesTest.kt b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/ResourcesTest.kt index 95b599bfcb..68ff7907ac 100644 --- a/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/ResourcesTest.kt +++ b/gradle-plugins/compose/src/test/kotlin/org/jetbrains/compose/test/tests/integration/ResourcesTest.kt @@ -2,6 +2,7 @@ package org.jetbrains.compose.test.tests.integration import org.gradle.util.GradleVersion import org.jetbrains.compose.desktop.application.internal.ComposeProperties +import org.jetbrains.compose.internal.Version import org.jetbrains.compose.internal.utils.Arch import org.jetbrains.compose.internal.utils.OS import org.jetbrains.compose.internal.utils.currentArch @@ -254,7 +255,7 @@ class ResourcesTest : GradlePluginTestBase() { } gradle(":cmplib:publishAllPublicationsToMavenRepository").checks { - check.logContains("Configure KMP resources") + check.logContains("Configure multi-module compose resources") val resDir = file("cmplib/src/commonMain/composeResources") val resourcesFiles = resDir.walkTopDown() @@ -279,6 +280,13 @@ class ResourcesTest : GradlePluginTestBase() { libpath("iossimulatorarm64", "-kotlin_resources.kotlin_resources.zip") ) checkResourcesZip(iossimulatorarm64ResZip, resourcesFiles, false) + + val macosx64ResZip = + file(libpath("macosx64", "-kotlin_resources.kotlin_resources.zip")) + checkResourcesZip(macosx64ResZip, resourcesFiles, false) + val macosarm64ResZip = + file(libpath("macosarm64", "-kotlin_resources.kotlin_resources.zip")) + checkResourcesZip(macosarm64ResZip, resourcesFiles, false) } val jsResZip = file(libpath("js", "-kotlin_resources.kotlin_resources.zip")) checkResourcesZip(jsResZip, resourcesFiles, false) @@ -299,6 +307,13 @@ class ResourcesTest : GradlePluginTestBase() { ":appModule:iosSimulatorArm64Test" } gradle(iosTask) + + val macosTask = if (currentArch == Arch.X64) { + ":appModule:macosX64Test" + } else { + ":appModule:macosArm64Test" + } + gradle(macosTask) } file("featureModule/src/commonMain/kotlin/me/sample/app/Feature.kt").modify { content -> @@ -316,17 +331,32 @@ class ResourcesTest : GradlePluginTestBase() { } @Test - fun testDisableMultimoduleResourcesWithNewKotlin() { - val environment = defaultTestEnvironment.copy( - kotlinVersion = "2.0.0-RC2" - ) + fun testNewAgpResources() { + Assumptions.assumeTrue(defaultTestEnvironment.parsedGradleVersion >= GradleVersion.version("8.10.2")) + Assumptions.assumeTrue(Version.fromString(defaultTestEnvironment.agpVersion) >= Version.fromString("8.8.0-alpha08")) + + with(testProject("misc/newAgpResources", defaultTestEnvironment)) { + gradle(":appModule:assembleDebug").checks { + check.logContains("Configure compose resources with KotlinMultiplatformAndroidComponentsExtension") + + val resourcesFiles = sequenceOf( + "composeResources/newagpresources.appmodule.generated.resources/values/strings.commonMain.cvr", + "composeResources/newagpresources.featuremodule.generated.resources/values/strings.commonMain.cvr" + ) + val apk = file("appModule/build/outputs/apk/debug/appModule-debug.apk") + checkResourcesZip(apk, resourcesFiles, true) + } + } + } - with(testProject("misc/kmpResourcePublication", environment)) { + @Test + fun testDisableMultimoduleResourcesWithNewKotlin() { + with(testProject("misc/kmpResourcePublication")) { file("gradle.properties").modify { content -> content + "\n" + ComposeProperties.DISABLE_MULTIMODULE_RESOURCES + "=true" } gradle(":cmplib:build").checks { - check.logContains("Configure compose resources") + check.logContains("Configure single-module compose resources") } } } @@ -388,10 +418,10 @@ class ResourcesTest : GradlePluginTestBase() { .getConvertedResources(commonResourcesDir, repackDir) gradle("build").checks { - check.taskSuccessful(":demoDebugAssetsCopyForAGP") - check.taskSuccessful(":demoReleaseAssetsCopyForAGP") - check.taskSuccessful(":fullDebugAssetsCopyForAGP") - check.taskSuccessful(":fullReleaseAssetsCopyForAGP") + check.taskSuccessful(":copyDemoDebugComposeResourcesToAndroidAssets") + check.taskSuccessful(":copyDemoReleaseComposeResourcesToAndroidAssets") + check.taskSuccessful(":copyFullDebugComposeResourcesToAndroidAssets") + check.taskSuccessful(":copyFullReleaseComposeResourcesToAndroidAssets") getAndroidApk("demo", "debug", "Resources-Test").let { apk -> checkResourcesZip(apk, commonResourcesFiles, true) @@ -523,6 +553,7 @@ class ResourcesTest : GradlePluginTestBase() { @Test fun testJvmOnlyProject(): Unit = with(testProject("misc/jvmOnlyResources")) { gradle("jar").checks { + check.logContains("Configure java-only compose resources") assertDirectoriesContentEquals( file("build/generated/compose/resourceGenerator/kotlin"), file("expected") @@ -594,6 +625,14 @@ class ResourcesTest : GradlePluginTestBase() { ) with(TestProject("misc/iosResources", testEnv)) { + gradle(":podspec", "-Pkotlin.native.cocoapods.generate.wrapper=true").checks { + assertEqualTextFiles( + file("iosResources.podspec"), + file("expected/iosResources.podspec") + ) + file("build/compose/cocoapods/compose-resources").checkExists() + } + gradle( ":syncFramework", "-Pkotlin.native.cocoapods.platform=${iosEnv["PLATFORM_NAME"]}", @@ -659,12 +698,94 @@ class ResourcesTest : GradlePluginTestBase() { file("build/compose/cocoapods/compose-resources/composeResources/iosresources.generated.resources/drawable/compose-multiplatform.xml").checkExists() file("build/compose/cocoapods/compose-resources/composeResources/iosresources.generated.resources/drawable/icon.xml").checkExists() } + } + } + @Test + fun macosResources() { + Assumptions.assumeTrue(currentOS == OS.MacOS) + val macosEnv = mapOf( + "PLATFORM_NAME" to "macosx", + "ARCHS" to "arm64", + "CONFIGURATION" to "Debug", + ) + val testEnv = defaultTestEnvironment.copy( + additionalEnvVars = macosEnv + ) + + with(TestProject("misc/macosResources", testEnv)) { gradle(":podspec", "-Pkotlin.native.cocoapods.generate.wrapper=true").checks { assertEqualTextFiles( - file("iosResources.podspec"), - file("expected/iosResources.podspec") + file("macosResources.podspec"), + file("expected/macosResources.podspec") ) + file("build/compose/cocoapods/compose-resources").checkExists() + } + + gradle( + ":syncFramework", + "-Pkotlin.native.cocoapods.platform=${macosEnv["PLATFORM_NAME"]}", + "-Pkotlin.native.cocoapods.archs=${macosEnv["ARCHS"]}", + "-Pkotlin.native.cocoapods.configuration=${macosEnv["CONFIGURATION"]}", + "--dry-run" + ).checks { + check.taskSkipped(":generateComposeResClass") + + check.taskSkipped(":convertXmlValueResourcesForCommonMain") + check.taskSkipped(":copyNonXmlValueResourcesForCommonMain") + check.taskSkipped(":prepareComposeResourcesTaskForCommonMain") + check.taskSkipped(":generateResourceAccessorsForCommonMain") + + check.taskSkipped(":convertXmlValueResourcesForNativeMain") + check.taskSkipped(":copyNonXmlValueResourcesForNativeMain") + check.taskSkipped(":prepareComposeResourcesTaskForNativeMain") + check.taskSkipped(":generateResourceAccessorsForNativeMain") + + check.taskSkipped(":convertXmlValueResourcesForAppleMain") + check.taskSkipped(":copyNonXmlValueResourcesForAppleMain") + check.taskSkipped(":prepareComposeResourcesTaskForAppleMain") + check.taskSkipped(":generateResourceAccessorsForAppleMain") + + check.taskSkipped(":convertXmlValueResourcesForMacosMain") + check.taskSkipped(":copyNonXmlValueResourcesForMacosMain") + check.taskSkipped(":prepareComposeResourcesTaskForMacosMain") + check.taskSkipped(":generateResourceAccessorsForMacosMain") + + check.taskSkipped(":convertXmlValueResourcesForMacosX64Main") + check.taskSkipped(":copyNonXmlValueResourcesForMacosX64Main") + check.taskSkipped(":prepareComposeResourcesTaskForMacosX64Main") + check.taskSkipped(":generateResourceAccessorsForMacosX64Main") + + check.taskSkipped(":syncPodComposeResourcesForIos") + } + gradle(":syncPodComposeResourcesForIos").checks { + check.taskNoSource(":convertXmlValueResourcesForCommonMain") + check.taskSuccessful(":copyNonXmlValueResourcesForCommonMain") + check.taskSuccessful(":prepareComposeResourcesTaskForCommonMain") + check.taskSkipped(":generateResourceAccessorsForCommonMain") + + check.taskNoSource(":convertXmlValueResourcesForNativeMain") + check.taskNoSource(":copyNonXmlValueResourcesForNativeMain") + check.taskNoSource(":prepareComposeResourcesTaskForNativeMain") + check.taskSkipped(":generateResourceAccessorsForNativeMain") + + check.taskNoSource(":convertXmlValueResourcesForAppleMain") + check.taskNoSource(":copyNonXmlValueResourcesForAppleMain") + check.taskNoSource(":prepareComposeResourcesTaskForAppleMain") + check.taskSkipped(":generateResourceAccessorsForAppleMain") + + check.taskNoSource(":convertXmlValueResourcesForMacosMain") + check.taskSuccessful(":copyNonXmlValueResourcesForMacosMain") + check.taskSuccessful(":prepareComposeResourcesTaskForMacosMain") + check.taskSkipped(":generateResourceAccessorsForMacosMain") + + check.taskNoSource(":convertXmlValueResourcesForMacosX64Main") + check.taskNoSource(":copyNonXmlValueResourcesForMacosX64Main") + check.taskNoSource(":prepareComposeResourcesTaskForMacosX64Main") + check.taskSkipped(":generateResourceAccessorsForMacosX64Main") + + file("build/compose/cocoapods/compose-resources/composeResources/macosresources.generated.resources/drawable/compose-multiplatform.xml").checkExists() + file("build/compose/cocoapods/compose-resources/composeResources/macosresources.generated.resources/drawable/icon.xml").checkExists() } } } @@ -683,4 +804,41 @@ class ResourcesTest : GradlePluginTestBase() { } } } + + @Test + fun macosTestResources() { + Assumptions.assumeTrue(currentOS == OS.MacOS) + with(testProject("misc/macosResources")) { + gradle(":linkDebugTestMacosX64", "--dry-run").checks { + check.taskSkipped(":copyTestComposeResourcesForMacosX64") + check.taskSkipped(":linkDebugTestMacosX64") + } + gradle(":copyTestComposeResourcesForMacosX64").checks { + file("build/bin/macosX64/debugTest/compose-resources/composeResources/macosresources.generated.resources/drawable/compose-multiplatform.xml").checkExists() + file("build/bin/macosX64/debugTest/compose-resources/composeResources/macosresources.generated.resources/drawable/icon.xml").checkExists() + } + } + } + + @Test + fun checkTestResources() { + with(testProject("misc/testResources")) { + gradle("check").checks { + check.logContains("Configure main resources for 'desktop' target") + check.logContains("Configure test resources for 'desktop' target") + check.logContains("Configure main resources for 'iosX64' target") + check.logContains("Configure test resources for 'iosX64' target") + check.logContains("Configure main resources for 'iosArm64' target") + check.logContains("Configure test resources for 'iosArm64' target") + check.logContains("Configure main resources for 'iosSimulatorArm64' target") + check.logContains("Configure test resources for 'iosSimulatorArm64' target") + check.logContains("Configure main resources for 'macosX64' target") + check.logContains("Configure test resources for 'macosX64' target") + check.logContains("Configure main resources for 'macosArm64' target") + check.logContains("Configure test resources for 'macosArm64' target") + + check.taskSuccessful(":desktopTest") + } + } + } } \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/application/newAndroidTarget/build.gradle b/gradle-plugins/compose/src/test/test-projects/application/newAndroidTarget/build.gradle index ef45b4a99e..9faff0a6f6 100644 --- a/gradle-plugins/compose/src/test/test-projects/application/newAndroidTarget/build.gradle +++ b/gradle-plugins/compose/src/test/test-projects/application/newAndroidTarget/build.gradle @@ -10,7 +10,7 @@ kotlin { androidLibrary { namespace = "com.google.samples.apps.diceroller.shared" - compileSdk = 34 + compileSdk = 35 } jvm() diff --git a/gradle-plugins/compose/src/test/test-projects/application/newAndroidTarget/settings.gradle b/gradle-plugins/compose/src/test/test-projects/application/newAndroidTarget/settings.gradle index 86985a3b8e..895eb5c107 100644 --- a/gradle-plugins/compose/src/test/test-projects/application/newAndroidTarget/settings.gradle +++ b/gradle-plugins/compose/src/test/test-projects/application/newAndroidTarget/settings.gradle @@ -3,7 +3,7 @@ pluginManagement { id 'org.jetbrains.kotlin.multiplatform' version 'KOTLIN_VERSION_PLACEHOLDER' id 'org.jetbrains.kotlin.plugin.compose' version 'KOTLIN_VERSION_PLACEHOLDER' id 'org.jetbrains.compose' version 'COMPOSE_GRADLE_PLUGIN_VERSION_PLACEHOLDER' - id 'com.android.kotlin.multiplatform.library' version '8.2.0-alpha13' + id 'com.android.kotlin.multiplatform.library' version 'AGP_VERSION_PLACEHOLDER' } repositories { mavenLocal() diff --git a/gradle-plugins/compose/src/test/test-projects/application/proguard/main-image.expected.png b/gradle-plugins/compose/src/test/test-projects/application/proguard/main-image.expected.png index 10bbd92667..a8ed1ade6f 100644 Binary files a/gradle-plugins/compose/src/test/test-projects/application/proguard/main-image.expected.png and b/gradle-plugins/compose/src/test/test-projects/application/proguard/main-image.expected.png differ diff --git a/gradle-plugins/compose/src/test/test-projects/beforeKotlin2/custom-compiler-args/main-image.expected.png b/gradle-plugins/compose/src/test/test-projects/beforeKotlin2/custom-compiler-args/main-image.expected.png index 10bbd92667..a8ed1ade6f 100644 Binary files a/gradle-plugins/compose/src/test/test-projects/beforeKotlin2/custom-compiler-args/main-image.expected.png and b/gradle-plugins/compose/src/test/test-projects/beforeKotlin2/custom-compiler-args/main-image.expected.png differ diff --git a/gradle-plugins/compose/src/test/test-projects/beforeKotlin2/custom-compiler/main-image.expected.png b/gradle-plugins/compose/src/test/test-projects/beforeKotlin2/custom-compiler/main-image.expected.png index 10bbd92667..a8ed1ade6f 100644 Binary files a/gradle-plugins/compose/src/test/test-projects/beforeKotlin2/custom-compiler/main-image.expected.png and b/gradle-plugins/compose/src/test/test-projects/beforeKotlin2/custom-compiler/main-image.expected.png differ diff --git a/gradle-plugins/compose/src/test/test-projects/misc/commonResources/build.gradle.kts b/gradle-plugins/compose/src/test/test-projects/misc/commonResources/build.gradle.kts index 5629e0ad3e..26a21ee7e9 100644 --- a/gradle-plugins/compose/src/test/test-projects/misc/commonResources/build.gradle.kts +++ b/gradle-plugins/compose/src/test/test-projects/misc/commonResources/build.gradle.kts @@ -33,13 +33,13 @@ kotlin { } android { - compileSdk = 34 + compileSdk = 35 namespace = "org.jetbrains.compose.resources.test" sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") defaultConfig { applicationId = "org.example.project" minSdk = 21 - targetSdk = 34 + targetSdk = 35 versionCode = 1 versionName = "1.0" } diff --git a/gradle-plugins/compose/src/test/test-projects/misc/jvmOnlyResources/expected/commonResClass/me/app/jvmonlyresources/generated/resources/Res.kt b/gradle-plugins/compose/src/test/test-projects/misc/jvmOnlyResources/expected/commonResClass/me/app/jvmonlyresources/generated/resources/Res.kt index b532771763..27b5aed178 100644 --- a/gradle-plugins/compose/src/test/test-projects/misc/jvmOnlyResources/expected/commonResClass/me/app/jvmonlyresources/generated/resources/Res.kt +++ b/gradle-plugins/compose/src/test/test-projects/misc/jvmOnlyResources/expected/commonResClass/me/app/jvmonlyresources/generated/resources/Res.kt @@ -22,7 +22,8 @@ internal object Res { * @return The content of the file as a byte array. */ @ExperimentalResourceApi - public suspend fun readBytes(path: String): ByteArray = readResourceBytes("" + path) + public suspend fun readBytes(path: String): ByteArray = + readResourceBytes("composeResources/me.app.jvmonlyresources.generated.resources/" + path) /** * Returns the URI string of the resource file at the specified path. @@ -33,7 +34,8 @@ internal object Res { * @return The URI string of the file. */ @ExperimentalResourceApi - public fun getUri(path: String): String = getResourceUri("" + path) + public fun getUri(path: String): String = + getResourceUri("composeResources/me.app.jvmonlyresources.generated.resources/" + path) public object drawable diff --git a/gradle-plugins/compose/src/test/test-projects/misc/jvmOnlyResources/expected/mainResourceAccessors/me/app/jvmonlyresources/generated/resources/Drawable0.main.kt b/gradle-plugins/compose/src/test/test-projects/misc/jvmOnlyResources/expected/mainResourceAccessors/me/app/jvmonlyresources/generated/resources/Drawable0.main.kt index 21c01fd922..2326a5dd63 100644 --- a/gradle-plugins/compose/src/test/test-projects/misc/jvmOnlyResources/expected/mainResourceAccessors/me/app/jvmonlyresources/generated/resources/Drawable0.main.kt +++ b/gradle-plugins/compose/src/test/test-projects/misc/jvmOnlyResources/expected/mainResourceAccessors/me/app/jvmonlyresources/generated/resources/Drawable0.main.kt @@ -24,6 +24,7 @@ internal val Res.drawable.vector: DrawableResource private fun init_vector(): DrawableResource = org.jetbrains.compose.resources.DrawableResource( "drawable:vector", setOf( - org.jetbrains.compose.resources.ResourceItem(setOf(), "drawable/vector.xml", -1, -1), + org.jetbrains.compose.resources.ResourceItem(setOf(), + "composeResources/me.app.jvmonlyresources.generated.resources/drawable/vector.xml", -1, -1), ) ) diff --git a/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/appModule/build.gradle.kts b/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/appModule/build.gradle.kts index aac9ee2149..07f8005434 100644 --- a/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/appModule/build.gradle.kts +++ b/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/appModule/build.gradle.kts @@ -13,6 +13,8 @@ kotlin { iosX64() iosArm64() iosSimulatorArm64() + macosX64() + macosArm64() js { browser() } wasmJs { browser() } @@ -45,12 +47,12 @@ kotlin { android { namespace = "me.sample.app" - compileSdk = 34 + compileSdk = 35 sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") defaultConfig { applicationId = "org.example.project" minSdk = 24 - targetSdk = 34 + targetSdk = 35 versionCode = 1 versionName = "1.0" } diff --git a/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/appModule/src/macosMain/composeResources/values/macos_strings.xml b/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/appModule/src/macosMain/composeResources/values/macos_strings.xml new file mode 100644 index 0000000000..f9f89e586b --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/appModule/src/macosMain/composeResources/values/macos_strings.xml @@ -0,0 +1,3 @@ + + macOS string + \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/appModule/src/macosMain/kotlin/me/sample/app/App.macos.kt b/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/appModule/src/macosMain/kotlin/me/sample/app/App.macos.kt new file mode 100644 index 0000000000..4a4927ee00 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/appModule/src/macosMain/kotlin/me/sample/app/App.macos.kt @@ -0,0 +1,10 @@ +package me.sample.app + +import androidx.compose.runtime.Composable +import kmpresourcepublication.appmodule.generated.resources.Res +import kmpresourcepublication.appmodule.generated.resources.macOS_str +import org.jetbrains.compose.resources.stringResource + +@Composable +actual fun getPlatformSpecificString(): String = + stringResource(Res.string.macOS_str) \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/cmplib/build.gradle.kts b/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/cmplib/build.gradle.kts index ed9522a57c..609f087d4a 100644 --- a/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/cmplib/build.gradle.kts +++ b/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/cmplib/build.gradle.kts @@ -22,6 +22,8 @@ kotlin { iosX64() iosArm64() iosSimulatorArm64() + macosX64() + macosArm64() js { browser() } wasmJs { browser() } @@ -41,7 +43,7 @@ kotlin { android { namespace = "me.sample.library" - compileSdk = 34 + compileSdk = 35 defaultConfig { minSdk = 24 } diff --git a/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/featureModule/build.gradle.kts b/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/featureModule/build.gradle.kts index 3d239458d8..2ae9d3cefa 100644 --- a/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/featureModule/build.gradle.kts +++ b/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/featureModule/build.gradle.kts @@ -11,6 +11,8 @@ kotlin { iosX64() iosArm64() iosSimulatorArm64() + macosX64() + macosArm64() js { browser() } wasmJs { browser() } @@ -30,7 +32,7 @@ kotlin { android { namespace = "me.sample.feature" - compileSdk = 34 + compileSdk = 35 defaultConfig { minSdk = 24 diff --git a/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/gradle.properties b/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/gradle.properties index 9cd73d38eb..3ae7c5803a 100644 --- a/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/gradle.properties +++ b/gradle-plugins/compose/src/test/test-projects/misc/kmpResourcePublication/gradle.properties @@ -5,3 +5,4 @@ android.useAndroidX=true org.jetbrains.compose.experimental.uikit.enabled=true org.jetbrains.compose.experimental.jscanvas.enabled=true org.jetbrains.compose.experimental.wasm.enabled=true +org.jetbrains.compose.experimental.macos.enabled=true diff --git a/gradle-plugins/compose/src/test/test-projects/misc/macosResources/build.gradle.kts b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/build.gradle.kts new file mode 100644 index 0000000000..2e30c124f4 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/build.gradle.kts @@ -0,0 +1,32 @@ +plugins { + kotlin("multiplatform") + kotlin("plugin.compose") + kotlin("native.cocoapods") + id("org.jetbrains.compose") +} + +kotlin { + cocoapods { + version = "1.0" + summary = "Some description for a Kotlin/Native module" + homepage = "Link to a Kotlin/Native module homepage" + pod("Base64", "1.1.2") + framework { + baseName = "shared" + isStatic = true + } + } + + macosX64() + macosArm64() + + sourceSets { + commonMain { + dependencies { + implementation(compose.runtime) + implementation(compose.material) + implementation(compose.components.resources) + } + } + } +} diff --git a/gradle-plugins/compose/src/test/test-projects/misc/macosResources/expected/macosResources.podspec b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/expected/macosResources.podspec new file mode 100644 index 0000000000..b4f476089e --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/expected/macosResources.podspec @@ -0,0 +1,54 @@ +Pod::Spec.new do |spec| + spec.name = 'macosResources' + spec.version = '1.0' + spec.homepage = 'Link to a Kotlin/Native module homepage' + spec.source = { :http=> ''} + spec.authors = '' + spec.license = '' + spec.summary = 'Some description for a Kotlin/Native module' + spec.vendored_frameworks = 'build/cocoapods/framework/shared.framework' + spec.libraries = 'c++' + + spec.dependency 'Base64', '1.1.2' + + if !Dir.exist?('build/cocoapods/framework/shared.framework') || Dir.empty?('build/cocoapods/framework/shared.framework') + raise " + + Kotlin framework 'shared' doesn't exist yet, so a proper Xcode project can't be generated. + 'pod install' should be executed after running ':generateDummyFramework' Gradle task: + + ./gradlew :generateDummyFramework + + Alternatively, proper pod installation is performed during Gradle sync in the IDE (if Podfile location is set)" + end + + spec.xcconfig = { + 'ENABLE_USER_SCRIPT_SANDBOXING' => 'NO', + } + + spec.pod_target_xcconfig = { + 'KOTLIN_PROJECT_PATH' => '', + 'PRODUCT_MODULE_NAME' => 'shared', + } + + spec.script_phases = [ + { + :name => 'Build macosResources', + :execution_position => :before_compile, + :shell_path => '/bin/sh', + :script => <<-SCRIPT + if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then + echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \"YES\"" + exit 0 + fi + set -ev + REPO_ROOT="$PODS_TARGET_SRCROOT" + "$REPO_ROOT/gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \ + -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \ + -Pkotlin.native.cocoapods.archs="$ARCHS" \ + -Pkotlin.native.cocoapods.configuration="$CONFIGURATION" + SCRIPT + } + ] + spec.resources = ['build/compose/cocoapods/compose-resources'] +end \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/macosResources/gradle.properties b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/gradle.properties new file mode 100644 index 0000000000..dc1dcfb61b --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx8096M +org.jetbrains.compose.experimental.macos.enabled=true \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/macosResources/settings.gradle.kts b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/settings.gradle.kts new file mode 100644 index 0000000000..fe637593ae --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/settings.gradle.kts @@ -0,0 +1,24 @@ +rootProject.name = "macosResources" +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + google() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + } + plugins { + id("org.jetbrains.kotlin.multiplatform").version("KOTLIN_VERSION_PLACEHOLDER") + id("org.jetbrains.kotlin.plugin.compose").version("KOTLIN_VERSION_PLACEHOLDER") + id("org.jetbrains.kotlin.native.cocoapods").version("KOTLIN_VERSION_PLACEHOLDER") + id("org.jetbrains.compose").version("COMPOSE_GRADLE_PLUGIN_VERSION_PLACEHOLDER") + } +} +dependencyResolutionManagement { + repositories { + mavenLocal() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + mavenCentral() + gradlePluginPortal() + google() + } +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/macosResources/src/commonMain/composeResources/drawable/compose-multiplatform.xml b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/src/commonMain/composeResources/drawable/compose-multiplatform.xml new file mode 100644 index 0000000000..792ad8f711 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/src/commonMain/composeResources/drawable/compose-multiplatform.xml @@ -0,0 +1,36 @@ + + + + + + + + diff --git a/benchmarks/ios/animation-from-template/shared/src/commonMain/kotlin/App.kt b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/src/commonMain/kotlin/App.kt similarity index 72% rename from benchmarks/ios/animation-from-template/shared/src/commonMain/kotlin/App.kt rename to gradle-plugins/compose/src/test/test-projects/misc/macosResources/src/commonMain/kotlin/App.kt index 79ba129d7f..17641ca754 100644 --- a/benchmarks/ios/animation-from-template/shared/src/commonMain/kotlin/App.kt +++ b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/src/commonMain/kotlin/App.kt @@ -1,39 +1,36 @@ import androidx.compose.animation.AnimatedVisibility import androidx.compose.foundation.Image -import androidx.compose.foundation.MutatePriority import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material.Button import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue -import androidx.compose.runtime.withFrameMillis import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch import org.jetbrains.compose.resources.ExperimentalResourceApi import org.jetbrains.compose.resources.painterResource +import iosResources.generated.resources.* @OptIn(ExperimentalResourceApi::class) @Composable fun App() { MaterialTheme { + var greetingText by remember { mutableStateOf("Hello, World!") } var showImage by remember { mutableStateOf(false) } - LaunchedEffect(showImage) { - delay(200) - showImage = !showImage - } Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) { + Button(onClick = { + showImage = !showImage + }) { + Text(greetingText) + } AnimatedVisibility(showImage) { Image( - painterResource("compose-multiplatform.xml"), + painterResource(Res.drawable.compose_multiplatform), null ) } diff --git a/gradle-plugins/compose/src/test/test-projects/misc/macosResources/src/macosMain/composeResources/drawable/icon.xml b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/src/macosMain/composeResources/drawable/icon.xml new file mode 100644 index 0000000000..792ad8f711 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/macosResources/src/macosMain/composeResources/drawable/icon.xml @@ -0,0 +1,36 @@ + + + + + + + + diff --git a/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/appModule/build.gradle.kts b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/appModule/build.gradle.kts new file mode 100644 index 0000000000..ce7429f97b --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/appModule/build.gradle.kts @@ -0,0 +1,37 @@ +plugins { + id("org.jetbrains.compose") + kotlin("multiplatform") + kotlin("plugin.compose") + id("com.android.application") +} + +kotlin { + jvmToolchain(11) + androidTarget() + jvm() + + sourceSets { + commonMain.dependencies { + implementation(compose.runtime) + implementation(compose.material3) + implementation(compose.components.resources) + implementation(project(":featureModule")) + } + + jvmMain.dependencies { + implementation(compose.desktop.currentOs) + } + } +} + +android { + namespace = "me.sample.app" + compileSdk = 35 + defaultConfig { + applicationId = "org.example.project" + minSdk = 24 + targetSdk = 35 + versionCode = 1 + versionName = "1.0" + } +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/appModule/src/androidMain/AndroidManifest.xml b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/appModule/src/androidMain/AndroidManifest.xml new file mode 100644 index 0000000000..96aa10f056 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/appModule/src/androidMain/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + diff --git a/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/appModule/src/commonMain/composeResources/values/strings.xml b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/appModule/src/commonMain/composeResources/values/strings.xml new file mode 100644 index 0000000000..fa6300c278 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/appModule/src/commonMain/composeResources/values/strings.xml @@ -0,0 +1,3 @@ + + App text str_1 + \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/appModule/src/commonMain/kotlin/me/sample/app/App.kt b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/appModule/src/commonMain/kotlin/me/sample/app/App.kt new file mode 100644 index 0000000000..4c9c113677 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/appModule/src/commonMain/kotlin/me/sample/app/App.kt @@ -0,0 +1,17 @@ +package me.sample.app + +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import newagpresources.appmodule.generated.resources.* +import org.jetbrains.compose.resources.stringResource + +@Composable +fun App() { + Column { + val txt = "text: " + Text(txt + stringResource(Res.string.str_1)) + MyFeatureText(txt = txt) + } +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/build.gradle.kts b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/build.gradle.kts new file mode 100644 index 0000000000..aa6192ad4a --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + id("org.jetbrains.compose").apply(false) + kotlin("multiplatform").apply(false) + kotlin("plugin.compose").apply(false) + id("com.android.kotlin.multiplatform.library").apply(false) + id("com.android.application").apply(false) +} diff --git a/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/featureModule/build.gradle.kts b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/featureModule/build.gradle.kts new file mode 100644 index 0000000000..31cfd0728e --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/featureModule/build.gradle.kts @@ -0,0 +1,26 @@ +plugins { + id("org.jetbrains.compose") + kotlin("multiplatform") + kotlin("plugin.compose") + id("com.android.kotlin.multiplatform.library") +} + +kotlin { + jvmToolchain(11) + jvm() + + androidLibrary { + experimentalProperties["android.experimental.kmp.enableAndroidResources"] = true + namespace = "me.sample.feature" + compileSdk = 35 + minSdk = 24 + } + + sourceSets { + commonMain.dependencies { + implementation(compose.runtime) + implementation(compose.material3) + implementation(compose.components.resources) + } + } +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/featureModule/src/commonMain/composeResources/values/strings.xml b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/featureModule/src/commonMain/composeResources/values/strings.xml new file mode 100644 index 0000000000..a0a5330229 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/featureModule/src/commonMain/composeResources/values/strings.xml @@ -0,0 +1,3 @@ + + Feature text str_1 + \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/featureModule/src/commonMain/kotlin/me/sample/app/Feature.kt b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/featureModule/src/commonMain/kotlin/me/sample/app/Feature.kt new file mode 100644 index 0000000000..fd1b08e734 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/featureModule/src/commonMain/kotlin/me/sample/app/Feature.kt @@ -0,0 +1,12 @@ +package me.sample.app + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import org.jetbrains.compose.resources.stringResource +import newagpresources.featuremodule.generated.resources.* + +@Composable +fun MyFeatureText(modifier: Modifier = Modifier, txt: String) { + Text(txt + stringResource(Res.string.str_1), modifier) +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/gradle.properties b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/gradle.properties new file mode 100644 index 0000000000..dbaa0a8ca8 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx2048M" +kotlin.code.style=official +android.useAndroidX=true diff --git a/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/settings.gradle.kts b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/settings.gradle.kts new file mode 100644 index 0000000000..c7599f1193 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/newAgpResources/settings.gradle.kts @@ -0,0 +1,29 @@ +rootProject.name = "newAgpResources" +include(":featureModule") +include(":appModule") +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + mavenCentral() + google() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") + } + plugins { + id("org.jetbrains.kotlin.multiplatform").version("KOTLIN_VERSION_PLACEHOLDER") + id("org.jetbrains.kotlin.plugin.compose").version("KOTLIN_VERSION_PLACEHOLDER") + id("org.jetbrains.compose").version("COMPOSE_GRADLE_PLUGIN_VERSION_PLACEHOLDER") + id("com.android.kotlin.multiplatform.library").version("AGP_VERSION_PLACEHOLDER") + id("com.android.application").version("AGP_VERSION_PLACEHOLDER") + } +} +dependencyResolutionManagement { + repositories { + mavenCentral() + google() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev/") + mavenLocal() + } +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/testResources/build.gradle.kts b/gradle-plugins/compose/src/test/test-projects/misc/testResources/build.gradle.kts new file mode 100644 index 0000000000..e0886927c1 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/testResources/build.gradle.kts @@ -0,0 +1,42 @@ +import org.jetbrains.compose.ExperimentalComposeLibrary + +plugins { + kotlin("multiplatform") + kotlin("plugin.compose") + id("org.jetbrains.compose") +} + +group = "app.group" + +kotlin { + jvm("desktop") + + iosX64() + iosArm64() + iosSimulatorArm64() + + macosX64() + macosArm64() + + sourceSets { + commonMain { + dependencies { + implementation(compose.runtime) + implementation(compose.material) + implementation(compose.components.resources) + } + } + commonTest { + dependencies { + implementation(kotlin("test")) + @OptIn(ExperimentalComposeLibrary::class) + implementation(compose.uiTest) + } + } + val desktopMain by getting { + dependencies { + implementation(compose.desktop.currentOs) + } + } + } +} diff --git a/gradle-plugins/compose/src/test/test-projects/misc/testResources/gradle.properties b/gradle-plugins/compose/src/test/test-projects/misc/testResources/gradle.properties new file mode 100644 index 0000000000..2f532ce0ea --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/testResources/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx8096M +android.useAndroidX=true +org.jetbrains.compose.experimental.jscanvas.enabled=true +org.jetbrains.compose.experimental.macos.enabled=true \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/testResources/settings.gradle.kts b/gradle-plugins/compose/src/test/test-projects/misc/testResources/settings.gradle.kts new file mode 100644 index 0000000000..292f6220df --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/testResources/settings.gradle.kts @@ -0,0 +1,24 @@ +rootProject.name = "Resources-Test" +pluginManagement { + repositories { + mavenLocal() + gradlePluginPortal() + google() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + } + plugins { + id("com.android.application").version("AGP_VERSION_PLACEHOLDER") + id("org.jetbrains.kotlin.multiplatform").version("KOTLIN_VERSION_PLACEHOLDER") + id("org.jetbrains.kotlin.plugin.compose").version("KOTLIN_VERSION_PLACEHOLDER") + id("org.jetbrains.compose").version("COMPOSE_GRADLE_PLUGIN_VERSION_PLACEHOLDER") + } +} +dependencyResolutionManagement { + repositories { + mavenLocal() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + mavenCentral() + gradlePluginPortal() + google() + } +} diff --git a/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonMain/composeResources/files/common.txt b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonMain/composeResources/files/common.txt new file mode 100644 index 0000000000..3986d02b36 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonMain/composeResources/files/common.txt @@ -0,0 +1 @@ +common 777 \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonMain/composeResources/values/strings.xml b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonMain/composeResources/values/strings.xml new file mode 100644 index 0000000000..cef354128e --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonMain/composeResources/values/strings.xml @@ -0,0 +1,3 @@ + + Compose Resources App + diff --git a/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonMain/kotlin/App.kt b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonMain/kotlin/App.kt new file mode 100644 index 0000000000..ee1f26fd98 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonMain/kotlin/App.kt @@ -0,0 +1,7 @@ +import androidx.compose.material.Text +import androidx.compose.runtime.Composable + +@Composable +fun App() { + Text("app") +} diff --git a/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonTest/composeResources/files/data.txt b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonTest/composeResources/files/data.txt new file mode 100644 index 0000000000..6a537b5b36 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonTest/composeResources/files/data.txt @@ -0,0 +1 @@ +1234567890 \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonTest/composeResources/values/strings.xml b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonTest/composeResources/values/strings.xml new file mode 100644 index 0000000000..b34f38cdbf --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonTest/composeResources/values/strings.xml @@ -0,0 +1,3 @@ + + Common test + diff --git a/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonTest/kotlin/CommonUiTest.kt b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonTest/kotlin/CommonUiTest.kt new file mode 100644 index 0000000000..45c2cf78c8 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/commonTest/kotlin/CommonUiTest.kt @@ -0,0 +1,34 @@ +import androidx.compose.ui.test.ExperimentalTestApi +import androidx.compose.ui.test.runComposeUiTest +import app.group.resources_test.generated.resources.Res +import app.group.resources_test.generated.resources.app_name +import app.group.resources_test.generated.resources.test_string +import kotlinx.coroutines.test.runTest +import org.jetbrains.compose.resources.ExperimentalResourceApi +import org.jetbrains.compose.resources.stringResource +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotEquals + +@OptIn(ExperimentalTestApi::class, ExperimentalResourceApi::class) +class CommonUiTest { + + @Test + fun checkTestResources() = runComposeUiTest { + setContent { + val mainStr = stringResource(Res.string.app_name) + val testStr = stringResource(Res.string.test_string) + assertEquals("Compose Resources App", mainStr) + assertEquals("Common test", testStr) + } + } + + @Test + fun checkTestFileResource() = runTest { + val commonFile = Res.readBytes("files/common.txt").decodeToString() + assertEquals("common 777", commonFile) + val testFile = Res.readBytes("files/data.txt").decodeToString() + assertEquals("1234567890", testFile) + } + +} \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/desktopMain/composeResources/values/desktop_strings.xml b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/desktopMain/composeResources/values/desktop_strings.xml new file mode 100644 index 0000000000..e3ea685b42 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/desktopMain/composeResources/values/desktop_strings.xml @@ -0,0 +1,3 @@ + + Desktop string + \ No newline at end of file diff --git a/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/desktopTest/composeResources/values/desktop_strings.xml b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/desktopTest/composeResources/values/desktop_strings.xml new file mode 100644 index 0000000000..43e8cbf6c5 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/desktopTest/composeResources/values/desktop_strings.xml @@ -0,0 +1,3 @@ + + Desktop test string + diff --git a/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/desktopTest/kotlin/DesktopUiTest.kt b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/desktopTest/kotlin/DesktopUiTest.kt new file mode 100644 index 0000000000..77a9435ba6 --- /dev/null +++ b/gradle-plugins/compose/src/test/test-projects/misc/testResources/src/desktopTest/kotlin/DesktopUiTest.kt @@ -0,0 +1,29 @@ +import androidx.compose.ui.test.ExperimentalTestApi +import androidx.compose.ui.test.runComposeUiTest +import app.group.resources_test.generated.resources.Res +import app.group.resources_test.generated.resources.app_name +import app.group.resources_test.generated.resources.desktop_str +import app.group.resources_test.generated.resources.desktop_test_str +import app.group.resources_test.generated.resources.test_string +import org.jetbrains.compose.resources.stringResource +import kotlin.test.Test +import kotlin.test.assertEquals + +@OptIn(ExperimentalTestApi::class) +class DesktopUiTest { + + @Test + fun checkTestResources() = runComposeUiTest { + setContent { + val mainStr = stringResource(Res.string.app_name) + val testStr = stringResource(Res.string.test_string) + val desktopMainStr = stringResource(Res.string.desktop_str) + val desktopTestStr = stringResource(Res.string.desktop_test_str) + assertEquals("Compose Resources App", mainStr) + assertEquals("Common test", testStr) + assertEquals("Desktop string", desktopMainStr) + assertEquals("Desktop test string", desktopTestStr) + } + } + +} \ No newline at end of file diff --git a/gradle-plugins/gradle.properties b/gradle-plugins/gradle.properties index 7f087451cd..e70f99e810 100644 --- a/gradle-plugins/gradle.properties +++ b/gradle-plugins/gradle.properties @@ -8,15 +8,15 @@ kotlin.code.style=official dev.junit.parallel=false # Default version of Compose Libraries used by Gradle plugin -compose.version=1.7.0-alpha01 +compose.version=1.7.1 # The latest version of Kotlin compatible with compose.tests.compiler.version. Used only in tests/CI. compose.tests.kotlin.version=2.0.0 # __SUPPORTED_GRADLE_VERSIONS__ # Don't forget to edit versions in .github/workflows/gradle-plugin.yml as well # and Publish.Subtasks.buildTypes.gradle.GradlePluginTestKt#gradleVersions in the TC config # minimal and current gradle version -compose.tests.gradle.versions=7.4, 8.8 -compose.tests.agp.versions=8.1.0, 8.5.0 +compose.tests.gradle.versions=7.4, 8.10.2 +compose.tests.agp.versions=8.1.0, 8.5.0, 8.8.0-alpha08 # A version of Gradle plugin, that will be published, # unless overridden by COMPOSE_GRADLE_PLUGIN_VERSION env var. diff --git a/gradle-plugins/gradle/libs.versions.toml b/gradle-plugins/gradle/libs.versions.toml index b8f8f04a8c..8678dd57b3 100644 --- a/gradle-plugins/gradle/libs.versions.toml +++ b/gradle-plugins/gradle/libs.versions.toml @@ -2,7 +2,7 @@ kotlin = "2.0.0" gradle-download-plugin = "5.5.0" kotlin-poet = "1.16.0" -plugin-android = "7.3.0" +plugin-android = "8.8.0-alpha08" shadow-jar = "8.1.1" publish-plugin = "1.2.1" diff --git a/gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/PreviewManager.kt b/gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/PreviewManager.kt index 7e5309e74b..032330c120 100644 --- a/gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/PreviewManager.kt +++ b/gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/PreviewManager.kt @@ -290,7 +290,7 @@ class PreviewManagerImpl( } } }.also { - it.uncaughtExceptionHandler = Thread.UncaughtExceptionHandler { thread, e -> + it.uncaughtExceptionHandler = Thread.UncaughtExceptionHandler { _, e -> onError(e) } threads.add(it) diff --git a/gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/RemotePreviewHost.kt b/gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/RemotePreviewHost.kt index 8d96ab8b16..cb3ebc40dd 100644 --- a/gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/RemotePreviewHost.kt +++ b/gradle-plugins/preview-rpc/src/main/kotlin/org/jetbrains/compose/desktop/ui/tooling/preview/rpc/RemotePreviewHost.kt @@ -101,7 +101,7 @@ internal class PreviewHost(private val log: PreviewLogger, connection: RemoteCon }.setUpUnhandledExceptionHandler(ExitCodes.RECEIVER_FATAL_ERROR) private fun Thread.setUpUnhandledExceptionHandler(exitCode: Int): Thread = apply { - uncaughtExceptionHandler = Thread.UncaughtExceptionHandler { t, e -> + uncaughtExceptionHandler = Thread.UncaughtExceptionHandler { _, e -> try { System.err.println() System.err.println(PREVIEW_START_OF_STACKTRACE_MARKER) @@ -151,7 +151,7 @@ internal class PreviewHost(private val log: PreviewLogger, connection: RemoteCon val possibleCandidates = previewFacade.methods.filter { it.name == "render" } throw RuntimeException("Could not find method '$signature'. Possible candidates: \n${possibleCandidates.joinToString("\n") { "* ${it}" }}", e) } - val (id, fqName, frameConfig) = request + val (_, fqName, frameConfig) = request val scaledWidth = frameConfig.scaledWidth val scaledHeight = frameConfig.scaledHeight val scale = frameConfig.scale diff --git a/html/benchmark-core/build.gradle.kts b/html/benchmark-core/build.gradle.kts index 67146b1934..9acf6a4add 100644 --- a/html/benchmark-core/build.gradle.kts +++ b/html/benchmark-core/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.compose.gradle.standardConf + plugins { id("org.jetbrains.kotlin.multiplatform") id("org.jetbrains.compose") @@ -9,7 +11,8 @@ kotlin { browser { testTask { useKarma { - useChromeHeadless() + standardConf() + // useChromeHeadless() // useFirefox() } } diff --git a/html/compose-compiler-integration/main-template/settings.gradle.kts b/html/compose-compiler-integration/main-template/settings.gradle.kts index c554a78781..87635f4242 100644 --- a/html/compose-compiler-integration/main-template/settings.gradle.kts +++ b/html/compose-compiler-integration/main-template/settings.gradle.kts @@ -15,7 +15,7 @@ pluginManagement { val useVersion = if (extra.has("compose.version")) { extra["compose.version"].toString() } else { - "0.0.0-SNASPHOT" + "0.0.0-SNAPSHOT" } println("COMPOSE_INTEGRATION_VERSION=[$useVersion]") useVersion(useVersion) diff --git a/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/CSSEnums.kt b/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/CSSEnums.kt index 4cbdd24652..7fdcf35684 100644 --- a/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/CSSEnums.kt +++ b/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/CSSEnums.kt @@ -260,4 +260,22 @@ object GridAutoFlow : StylePropertyString { inline val Dense get() = "dense".unsafeCast() inline val RowDense get() = "row dense".unsafeCast() inline val ColumnDense get() = "column dense".unsafeCast() -} \ No newline at end of file +} + +interface VisibilityStyle: StylePropertyEnum { + companion object { + inline val Visible get() = VisibilityStyle("visible") + inline val Hidden get() = VisibilityStyle("hidden") + inline val Collapse get() = VisibilityStyle("collapse") + + + inline val Inherit get() = VisibilityStyle("inherit") + inline val Initial get() = VisibilityStyle("initial") + + inline val Revert get() = VisibilityStyle("revert") + inline val RevertLayer get() = VisibilityStyle("revert-layer") + + inline val Unset get() = VisibilityStyle("unset") + } +} +inline fun VisibilityStyle(value: String) = value.unsafeCast() diff --git a/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/properties/visibility.kt b/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/properties/visibility.kt new file mode 100644 index 0000000000..de0fc6fc00 --- /dev/null +++ b/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/css/properties/visibility.kt @@ -0,0 +1,12 @@ +/* + * Copyright 2020-2024 JetBrains s.r.o. and respective authors and developers. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + +@file:Suppress("Unused", "NOTHING_TO_INLINE", "NESTED_CLASS_IN_EXTERNAL_INTERFACE", "INLINE_EXTERNAL_DECLARATION", "WRONG_BODY_OF_EXTERNAL_DECLARATION", "NESTED_EXTERNAL_DECLARATION") + +package org.jetbrains.compose.web.css + +fun StyleScope.visibility(visibilityStyle: VisibilityStyle) { + property("visibility", visibilityStyle.value) +} diff --git a/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/Base.kt b/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/Base.kt similarity index 100% rename from html/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/Base.kt rename to html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/Base.kt diff --git a/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/ElementScope.kt b/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/ElementScope.kt similarity index 100% rename from html/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/ElementScope.kt rename to html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/ElementScope.kt diff --git a/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/Elements.kt b/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/Elements.kt similarity index 100% rename from html/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/Elements.kt rename to html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/Elements.kt diff --git a/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/InputElements.kt b/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/InputElements.kt similarity index 100% rename from html/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/InputElements.kt rename to html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/InputElements.kt diff --git a/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/RadioGroup.kt b/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/RadioGroup.kt similarity index 100% rename from html/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/RadioGroup.kt rename to html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/RadioGroup.kt diff --git a/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/Style.kt b/html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/Style.kt similarity index 100% rename from html/core/src/jsMain/kotlin/org/jetbrains/compose/web/elements/Style.kt rename to html/core/src/jsMain/kotlin/org/jetbrains/compose/web/dom/Style.kt diff --git a/html/core/src/jsTest/kotlin/CSSEnums.kt b/html/core/src/jsTest/kotlin/CSSEnums.kt index 4f430db8f9..87923a6ac6 100644 --- a/html/core/src/jsTest/kotlin/CSSEnums.kt +++ b/html/core/src/jsTest/kotlin/CSSEnums.kt @@ -114,3 +114,14 @@ fun Position.Companion.values() = listOf( Position.Sticky, Position.Fixed ) + +fun VisibilityStyle.Companion.values() = listOf( + VisibilityStyle.Visible, + VisibilityStyle.Hidden, + VisibilityStyle.Collapse, + VisibilityStyle.Inherit, + VisibilityStyle.Initial, + VisibilityStyle.Revert, + VisibilityStyle.RevertLayer, + VisibilityStyle.Unset +) diff --git a/html/core/src/jsTest/kotlin/css/CSSVisibilityTests.kt b/html/core/src/jsTest/kotlin/css/CSSVisibilityTests.kt new file mode 100644 index 0000000000..359deb302e --- /dev/null +++ b/html/core/src/jsTest/kotlin/css/CSSVisibilityTests.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2020-2021 JetBrains s.r.o. and respective authors and developers. + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE.txt file. + */ + +package org.jetbrains.compose.web.core.tests.css + +import org.jetbrains.compose.web.testutils.* +import org.jetbrains.compose.web.core.tests.values +import org.jetbrains.compose.web.css.VisibilityStyle +import org.jetbrains.compose.web.css.visibility +import org.jetbrains.compose.web.css.value +import org.jetbrains.compose.web.dom.Div +import kotlin.test.Test +import kotlin.test.assertEquals + +class CSSVisibilityTests { + + @Test + fun stylesDisplay() = runTest { + val enumValues = VisibilityStyle.values() + + composition { + enumValues.forEach { displayStyle -> + Div( + { + style { + visibility(displayStyle) + } + } + ) + } + } + + enumValues.forEach { visibilityStyle -> + assertEquals( + visibilityStyle.value, + (nextChild()).style.visibility + ) + } + } + +} diff --git a/html/test-utils/conf/karma.config.common.d/patch.js b/html/test-utils/conf/karma.config.common.d/patch.js index 9a91dc9e6b..df6c21a370 100644 --- a/html/test-utils/conf/karma.config.common.d/patch.js +++ b/html/test-utils/conf/karma.config.common.d/patch.js @@ -10,3 +10,12 @@ config.browserDisconnectTimeout = 10000; config.browserDisconnectTolerance = 3; config.browserConsoleLogOptions = {level: "debug", format: "%b %T: %m", terminal: true}; config.logLevel = config.LOG_DEBUG; + +config.customLaunchers = { + ChromeForComposeTests: { + base: "ChromeHeadless", + flags: ["--no-sandbox", "--disable-search-engine-choice-screen"] + } +} + +config.browsers = ["ChromeForComposeTests"] \ No newline at end of file diff --git a/idea-plugin/.gitignore b/idea-plugin/.gitignore index 7c0a052ec7..00fa5ce75e 100644 --- a/idea-plugin/.gitignore +++ b/idea-plugin/.gitignore @@ -1,3 +1,4 @@ build/ .gradle/ -.idea \ No newline at end of file +.idea +.intellijPlatform \ No newline at end of file diff --git a/idea-plugin/build.gradle.kts b/idea-plugin/build.gradle.kts index c5af9c2bef..c199720b35 100644 --- a/idea-plugin/build.gradle.kts +++ b/idea-plugin/build.gradle.kts @@ -1,76 +1,79 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile plugins { id("java") alias(libs.plugins.kotlin.jvm) - alias(libs.plugins.intellij.sdk) + alias(libs.plugins.intellij.plugin) alias(libs.plugins.intellij.changelog) } val projectProperties = ProjectProperties(project) group = "org.jetbrains.compose.desktop.ide" + version = projectProperties.deployVersion repositories { mavenCentral() + + intellijPlatform { defaultRepositories() } } dependencies { implementation("org.jetbrains.compose:preview-rpc") -} -intellij { - pluginName.set("Compose Multiplatform IDE Support") - type.set(projectProperties.platformType) - version.set(projectProperties.platformVersion) - downloadSources.set(projectProperties.platformDownloadSources) - updateSinceUntilBuild.set(false) - - plugins.set( - listOf( - "java", - "com.intellij.gradle", - "org.jetbrains.kotlin" - ) - ) -} + intellijPlatform { + intellijIdeaCommunity(libs.versions.idea) + instrumentationTools() + pluginVerifier() -tasks.buildSearchableOptions { - // temporary workaround - enabled = false + bundledPlugins("com.intellij.java", "org.jetbrains.kotlin", "com.intellij.gradle") + } } -tasks { - // Set the compatibility versions to 1.8 - withType { - sourceCompatibility = "11" - targetCompatibility = "11" +intellijPlatform { + pluginConfiguration { name = "Compose Multiplatform IDE Support" } + buildSearchableOptions = false + autoReload = false + + publishing { + token = System.getenv("IDE_PLUGIN_PUBLISH_TOKEN") + channels = projectProperties.pluginChannels } - withType { - kotlinOptions.jvmTarget = "11" + + pluginVerification { + ides { + recommended() + } } +} - publishPlugin { - token.set(System.getenv("IDE_PLUGIN_PUBLISH_TOKEN")) - channels.set(projectProperties.pluginChannels) +tasks { + withType { + sourceCompatibility = "21" + targetCompatibility = "21" } + withType { compilerOptions.jvmTarget.set(JvmTarget.JVM_21) } - runPluginVerifier { - ideVersions.set(projectProperties.pluginVerifierIdeVersions) + runIde { + systemProperty("idea.is.internal", true) + systemProperty("idea.kotlin.plugin.use.k2", true) + jvmArgumentProviders += CommandLineArgumentProvider { + listOf("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005") + } } } class ProjectProperties(private val project: Project) { - val deployVersion get() = stringProperty("deploy.version") - val platformType get() = stringProperty("platform.type") - val platformVersion get() = stringProperty("platform.version") - val platformDownloadSources get() = stringProperty("platform.download.sources").toBoolean() - val pluginChannels get() = listProperty("plugin.channels") - val pluginVerifierIdeVersions get() = listProperty("plugin.verifier.ide.versions") - - private fun stringProperty(key: String): String = - project.findProperty(key)!!.toString() + val deployVersion + get() = stringProperty("deploy.version") + + val pluginChannels + get() = listProperty("plugin.channels") + + private fun stringProperty(key: String): String = project.findProperty(key)!!.toString() + private fun listProperty(key: String): List = stringProperty(key).split(",").map { it.trim() } } diff --git a/idea-plugin/gradle.properties b/idea-plugin/gradle.properties index 0ee97128d8..e9c5385943 100644 --- a/idea-plugin/gradle.properties +++ b/idea-plugin/gradle.properties @@ -5,10 +5,3 @@ kotlin.stdlib.default.dependency=false deploy.version=0.1-SNAPSHOT plugin.channels=snapshots -# Intellij since-build should be updated directly in src/main/resources/META-INF/plugin.xml -# See https://jb.gg/intellij-platform-builds-list for available build versions. -plugin.verifier.ide.versions=2022.1, 2022.2, 2022.3 - -platform.type=IC -platform.version=2022.1.1 -platform.download.sources=true diff --git a/idea-plugin/gradle/libs.versions.toml b/idea-plugin/gradle/libs.versions.toml index cb3034a5a8..b4f88efcb3 100644 --- a/idea-plugin/gradle/libs.versions.toml +++ b/idea-plugin/gradle/libs.versions.toml @@ -1,9 +1,10 @@ [versions] -kotlin = "1.9.0" - -[libraries] +kotlin = "1.9.23" +ideaPlugin = "2.1.0" +idea = "2024.2.1" +changelog = "2.2.0" [plugins] kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -intellij-sdk = "org.jetbrains.intellij:1.15.0" -intellij-changelog = "org.jetbrains.changelog:2.2.0" +intellij-plugin = { id = "org.jetbrains.intellij.platform", version.ref = "ideaPlugin" } +intellij-changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" } diff --git a/idea-plugin/gradle/wrapper/gradle-wrapper.properties b/idea-plugin/gradle/wrapper/gradle-wrapper.properties index db9a6b825d..9a0a0e28c9 100644 --- a/idea-plugin/gradle/wrapper/gradle-wrapper.properties +++ b/idea-plugin/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/ConfigurePreviewTaskNameCache.kt b/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/ConfigurePreviewTaskNameCache.kt index f5e07fc90f..83cd4ad345 100644 --- a/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/ConfigurePreviewTaskNameCache.kt +++ b/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/ConfigurePreviewTaskNameCache.kt @@ -15,6 +15,7 @@ import com.intellij.openapi.project.Project import com.intellij.util.concurrency.annotations.RequiresReadLock import org.jetbrains.plugins.gradle.settings.GradleSettings import org.jetbrains.plugins.gradle.util.GradleConstants +import java.util.Locale internal val DEFAULT_CONFIGURE_PREVIEW_TASK_NAME = "configureDesktopPreview" @@ -38,8 +39,11 @@ internal class ConfigurePreviewTaskNameProviderImpl : ConfigurePreviewTaskNamePr return null } - private fun previewTaskName(targetName: String = "") = - "$DEFAULT_CONFIGURE_PREVIEW_TASK_NAME${targetName.capitalize()}" + private fun previewTaskName(targetName: String = ""): String { + val capitalizedTargetName = + targetName.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() } + return "$DEFAULT_CONFIGURE_PREVIEW_TASK_NAME$capitalizedTargetName" + } private fun moduleDataNodeOrNull(project: Project, modulePath: String): DataNode? { val projectDataManager = ProjectDataManager.getInstance() @@ -87,4 +91,4 @@ internal class ConfigurePreviewTaskNameCache( cachedTaskName = null } } -} \ No newline at end of file +} diff --git a/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewLocation.kt b/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewLocation.kt index bf8920b006..8c801ca03a 100644 --- a/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewLocation.kt +++ b/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewLocation.kt @@ -5,6 +5,7 @@ package org.jetbrains.compose.desktop.ide.preview +import com.intellij.openapi.components.service import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil import com.intellij.openapi.roots.ProjectFileIndex import com.intellij.util.concurrency.annotations.RequiresReadLock @@ -20,7 +21,7 @@ internal fun KtNamedFunction.asPreviewFunctionOrNull(): PreviewLocation? { val module = ProjectFileIndex.getInstance(project).getModuleForFile(containingFile.virtualFile) if (module == null || module.isDisposed) return null - val service = project.getService(PreviewStateService::class.java) + val service = project.service() val previewTaskName = service.configurePreviewTaskNameOrNull(module) ?: DEFAULT_CONFIGURE_PREVIEW_TASK_NAME val modulePath = ExternalSystemApiUtil.getExternalProjectPath(module) ?: return null return PreviewLocation(fqName = fqName, modulePath = modulePath, taskName = previewTaskName) diff --git a/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewStateService.kt b/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewStateService.kt index 74a6d248ca..6e0b6dd399 100644 --- a/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewStateService.kt +++ b/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewStateService.kt @@ -7,11 +7,9 @@ package org.jetbrains.compose.desktop.ide.preview import com.intellij.openapi.Disposable import com.intellij.openapi.components.Service -import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.externalSystem.model.task.* import com.intellij.openapi.externalSystem.service.notification.ExternalSystemProgressNotificationManager import com.intellij.openapi.module.Module -import com.intellij.openapi.project.Project import com.intellij.openapi.util.Disposer import com.intellij.ui.components.JBLoadingPanel import com.intellij.util.concurrency.annotations.RequiresReadLock @@ -22,9 +20,8 @@ import javax.swing.JComponent import javax.swing.event.AncestorEvent import javax.swing.event.AncestorListener -@Service -class PreviewStateService(private val myProject: Project) : Disposable { - private val idePreviewLogger = Logger.getInstance("org.jetbrains.compose.desktop.ide.preview") +@Service(Service.Level.PROJECT) +class PreviewStateService : Disposable { private val previewListener = CompositePreviewListener() private val previewManager: PreviewManager = PreviewManagerImpl(previewListener) val gradleCallbackPort: Int @@ -35,7 +32,7 @@ class PreviewStateService(private val myProject: Project) : Disposable { init { val projectRefreshListener = ConfigurePreviewTaskNameCacheInvalidator(configurePreviewTaskNameCache) ExternalSystemProgressNotificationManager.getInstance() - .addNotificationListener(projectRefreshListener, myProject) + .addNotificationListener(projectRefreshListener, this) } @RequiresReadLock @@ -80,7 +77,6 @@ private class PreviewResizeListener(private val previewManager: PreviewManager) override fun ancestorAdded(event: AncestorEvent) { updateFrameSize(event.component) - } override fun ancestorRemoved(event: AncestorEvent) { @@ -136,4 +132,4 @@ private class ConfigurePreviewTaskNameCacheInvalidator( configurePreviewTaskNameCache.invalidate() } } -} \ No newline at end of file +} diff --git a/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewToolWindow.kt b/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewToolWindow.kt index c3a10cd449..d4c0606b22 100644 --- a/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewToolWindow.kt +++ b/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/PreviewToolWindow.kt @@ -11,23 +11,20 @@ import com.intellij.openapi.project.Project import com.intellij.openapi.wm.ToolWindow import com.intellij.openapi.wm.ToolWindowFactory import com.intellij.ui.components.JBLoadingPanel -import org.jetbrains.compose.desktop.ide.preview.ui.PreviewPanel import java.awt.BorderLayout +import org.jetbrains.compose.desktop.ide.preview.ui.PreviewPanel class PreviewToolWindow : ToolWindowFactory, DumbAware { - override fun isApplicable(project: Project): Boolean = - isPreviewCompatible(project) + override suspend fun isApplicableAsync(project: Project): Boolean = isPreviewCompatible(project) override fun init(toolWindow: ToolWindow) { - ApplicationManager.getApplication().invokeLater { - toolWindow.setIcon(PreviewIcons.COMPOSE) - } + ApplicationManager.getApplication().invokeLater { toolWindow.setIcon(PreviewIcons.COMPOSE) } } override fun createToolWindowContent(project: Project, toolWindow: ToolWindow) { toolWindow.contentManager.let { content -> val panel = PreviewPanel(project) - val loadingPanel = JBLoadingPanel(BorderLayout(), project) + val loadingPanel = JBLoadingPanel(BorderLayout(), toolWindow.disposable) loadingPanel.add(panel, BorderLayout.CENTER) content.addContent(content.factory.createContent(loadingPanel, null, false)) project.service().registerPreviewPanels(panel, loadingPanel) @@ -35,6 +32,5 @@ class PreviewToolWindow : ToolWindowFactory, DumbAware { } // don't show the toolwindow until a preview is requested - override fun shouldBeAvailable(project: Project): Boolean = - false -} \ No newline at end of file + override fun shouldBeAvailable(project: Project): Boolean = false +} diff --git a/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/locationUtils.kt b/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/locationUtils.kt index c802e6369d..fec6f8fd53 100644 --- a/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/locationUtils.kt +++ b/idea-plugin/src/main/kotlin/org/jetbrains/compose/desktop/ide/preview/locationUtils.kt @@ -21,32 +21,39 @@ import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValuesManager import com.intellij.psi.util.parentOfType import com.intellij.util.concurrency.annotations.RequiresReadLock +import org.jetbrains.kotlin.analysis.api.analyze +import org.jetbrains.kotlin.analysis.api.symbols.KaClassLikeSymbol import org.jetbrains.kotlin.asJava.findFacadeClass -import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.ClassKind -import org.jetbrains.kotlin.idea.caches.resolve.analyze -import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtClass +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.KtNamedFunction +import org.jetbrains.kotlin.psi.allConstructors import org.jetbrains.kotlin.psi.psiUtil.containingClass -import org.jetbrains.kotlin.resolve.BindingContext -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -internal const val DESKTOP_PREVIEW_ANNOTATION_FQN = "androidx.compose.desktop.ui.tooling.preview.Preview" +internal const val DESKTOP_PREVIEW_ANNOTATION_FQN = + "androidx.compose.desktop.ui.tooling.preview.Preview" internal const val COMPOSABLE_FQ_NAME = "androidx.compose.runtime.Composable" +private val ComposableAnnotationClassId = ClassId.topLevel(FqName(COMPOSABLE_FQ_NAME)) +private val DesktopPreviewAnnotationClassId = + ClassId.topLevel(FqName(DESKTOP_PREVIEW_ANNOTATION_FQN)) + /** * Utils based on functions from AOSP, taken from * tools/adt/idea/compose-designer/src/com/android/tools/idea/compose/preview/util/PreviewElement.kt */ /** - * Returns whether a `@Composable` [PREVIEW_ANNOTATION_FQN] is defined in a valid location, which can be either: + * Returns whether a `@Composable` [DESKTOP_PREVIEW_ANNOTATION_FQN] is defined in a valid location, + * which can be either: * 1. Top-level functions - * 2. Non-nested functions defined in top-level classes that have a default (no parameter) constructor - * + * 2. Non-nested functions defined in top-level classes that have a default (no parameter) + * constructor */ private fun KtNamedFunction.isValidPreviewLocation(): Boolean { - if (valueParameters.size > 0) return false + if (valueParameters.isNotEmpty()) return false if (receiverTypeReference != null) return false if (isTopLevel) return true @@ -55,7 +62,8 @@ private fun KtNamedFunction.isValidPreviewLocation(): Boolean { // This is not a nested method val containingClass = containingClass() if (containingClass != null) { - // We allow functions that are not top level defined in top level classes that have a default (no parameter) constructor. + // We allow functions that are not top level defined in top level classes that have a + // default (no parameter) constructor. if (containingClass.isTopLevel() && containingClass.hasDefaultConstructor()) { return true } @@ -64,84 +72,67 @@ private fun KtNamedFunction.isValidPreviewLocation(): Boolean { return false } - /** * Computes the qualified name of the class containing this [KtNamedFunction]. * - * For functions defined within a Kotlin class, returns the qualified name of that class. For top-level functions, returns the JVM name of - * the Java facade class generated instead. - * + * For functions defined within a Kotlin class, returns the qualified name of that class. For + * top-level functions, returns the JVM name of the Java facade class generated instead. */ internal fun KtNamedFunction.getClassName(): String? = - if (isTopLevel) ((parent as? KtFile)?.findFacadeClass())?.qualifiedName else parentOfType()?.getQualifiedName() - + if (isTopLevel) ((parent as? KtFile)?.findFacadeClass())?.qualifiedName + else parentOfType()?.getQualifiedName() -/** Computes the qualified name for a Kotlin Class. Returns null if the class is a kotlin built-in. */ -private fun KtClass.getQualifiedName(): String? { - val classDescriptor = analyze(BodyResolveMode.PARTIAL).get(BindingContext.CLASS, this) ?: return null - return if (KotlinBuiltIns.isUnderKotlinPackage(classDescriptor) || classDescriptor.kind != ClassKind.CLASS) { - null - } else { - classDescriptor.fqNameSafe.asString() +/** + * Computes the qualified name for a Kotlin Class. Returns null if the class is a kotlin built-in. + */ +private fun KtClass.getQualifiedName(): String? = + analyze(this) { + val classSymbol = symbol + return when { + classSymbol !is KaClassLikeSymbol -> null + classSymbol.classId.isKotlinPackage() -> null + else -> classSymbol.classId?.asFqNameString() + } } -} + +private fun ClassId?.isKotlinPackage() = + this != null && startsWith(org.jetbrains.kotlin.builtins.StandardNames.BUILT_INS_PACKAGE_NAME) private fun KtClass.hasDefaultConstructor() = allConstructors.isEmpty().or(allConstructors.any { it.valueParameters.isEmpty() }) -/** - * Determines whether this [KtAnnotationEntry] has the specified qualified name. - * Careful: this does *not* currently take into account Kotlin type aliases (https://kotlinlang.org/docs/reference/type-aliases.html). - * Fortunately, type aliases are extremely uncommon for simple annotation types. - */ -private fun KtAnnotationEntry.fqNameMatches(fqName: String): Boolean { - // For inspiration, see IDELightClassGenerationSupport.KtUltraLightSupportImpl.findAnnotation in the Kotlin plugin. - val shortName = shortName?.asString() ?: return false - return fqName.endsWith(shortName) && fqName == getQualifiedName() -} - -/** - * Computes the qualified name of this [KtAnnotationEntry]. - * Prefer to use [fqNameMatches], which checks the short name first and thus has better performance. - */ -private fun KtAnnotationEntry.getQualifiedName(): String? = - analyze(BodyResolveMode.PARTIAL).get(BindingContext.ANNOTATION, this)?.fqName?.asString() - internal fun KtNamedFunction.composePreviewFunctionFqn() = "${getClassName()}.${name}" @RequiresReadLock internal fun KtNamedFunction.isValidComposablePreviewFunction(): Boolean { - fun isValidComposablePreviewImpl(): Boolean { - if (!isValidPreviewLocation()) return false - - var hasComposableAnnotation = false - var hasPreviewAnnotation = false - val annotationIt = annotationEntries.iterator() - while (annotationIt.hasNext() && !(hasComposableAnnotation && hasPreviewAnnotation)) { - val annotation = annotationIt.next() - hasComposableAnnotation = hasComposableAnnotation || annotation.fqNameMatches(COMPOSABLE_FQ_NAME) - hasPreviewAnnotation = hasPreviewAnnotation || annotation.fqNameMatches(DESKTOP_PREVIEW_ANNOTATION_FQN) - } + fun isValidComposablePreviewImpl(): Boolean = + analyze(this) { + if (!isValidPreviewLocation()) return false - return hasComposableAnnotation && hasPreviewAnnotation - } + val mySymbol = symbol + val hasComposableAnnotation = mySymbol.annotations.contains(ComposableAnnotationClassId) + val hasPreviewAnnotation = + mySymbol.annotations.contains(DesktopPreviewAnnotationClassId) - return CachedValuesManager.getCachedValue(this) { - cachedResult(isValidComposablePreviewImpl()) - } + return hasComposableAnnotation && hasPreviewAnnotation + } + + return CachedValuesManager.getCachedValue(this) { cachedResult(isValidComposablePreviewImpl()) } } // based on AndroidComposePsiUtils.kt from AOSP -internal fun KtNamedFunction.isComposableFunction(): Boolean { - return CachedValuesManager.getCachedValue(this) { - cachedResult(annotationEntries.any { it.fqNameMatches(COMPOSABLE_FQ_NAME) }) +internal fun KtNamedFunction.isComposableFunction(): Boolean = + CachedValuesManager.getCachedValue(this) { + val hasComposableAnnotation = + analyze(this) { symbol.annotations.contains(ComposableAnnotationClassId) } + + cachedResult(hasComposableAnnotation) } -} private fun KtNamedFunction.cachedResult(value: T) = CachedValueProvider.Result.create( // TODO: see if we can handle alias imports without ruining performance. value, this.containingKtFile, - ProjectRootModificationTracker.getInstance(project) - ) \ No newline at end of file + ProjectRootModificationTracker.getInstance(project), + ) diff --git a/idea-plugin/src/main/kotlin/org/jetbrains/compose/web/ide/run/WebRunLineMarkerContributor.kt b/idea-plugin/src/main/kotlin/org/jetbrains/compose/web/ide/run/WebRunLineMarkerContributor.kt index 0bcf204512..14c1a0d1ea 100644 --- a/idea-plugin/src/main/kotlin/org/jetbrains/compose/web/ide/run/WebRunLineMarkerContributor.kt +++ b/idea-plugin/src/main/kotlin/org/jetbrains/compose/web/ide/run/WebRunLineMarkerContributor.kt @@ -15,9 +15,9 @@ class WebRunLineMarkerContributor : RunLineMarkerContributor() { override fun getInfo(element: PsiElement): Info? { if (element !is LeafPsiElement) return null if (element.node.elementType != KtTokens.IDENTIFIER) return null + if (element.parent.getAsJsMainFunctionOrNull() == null) return null - val jsMain = element.parent.getAsJsMainFunctionOrNull() ?: return null val icon = AllIcons.RunConfigurations.TestState.Run - return Info(icon, null, ExecutorAction.getActions()[0]) + return Info(icon, arrayOf(ExecutorAction.getActions()[0])) } } diff --git a/idea-plugin/src/main/kotlin/org/jetbrains/compose/web/ide/run/psiUtils.kt b/idea-plugin/src/main/kotlin/org/jetbrains/compose/web/ide/run/psiUtils.kt index 9f81b3d4fc..3e9b3ec8cd 100644 --- a/idea-plugin/src/main/kotlin/org/jetbrains/compose/web/ide/run/psiUtils.kt +++ b/idea-plugin/src/main/kotlin/org/jetbrains/compose/web/ide/run/psiUtils.kt @@ -6,45 +6,169 @@ package org.jetbrains.compose.web.ide.run import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny -import org.jetbrains.kotlin.idea.project.platform -import org.jetbrains.kotlin.idea.util.module +import com.intellij.util.concurrency.annotations.RequiresReadLock +import org.jetbrains.kotlin.analysis.api.KaSession +import org.jetbrains.kotlin.analysis.api.analyze +import org.jetbrains.kotlin.analysis.api.symbols.KaNamedFunctionSymbol +import org.jetbrains.kotlin.analysis.api.types.KaClassType +import org.jetbrains.kotlin.analysis.api.types.KaType +import org.jetbrains.kotlin.analysis.api.types.KaTypeNullability +import org.jetbrains.kotlin.config.LanguageFeature +import org.jetbrains.kotlin.idea.base.facet.platform.platform +import org.jetbrains.kotlin.idea.base.projectStructure.languageVersionSettings +import org.jetbrains.kotlin.idea.base.psi.KotlinPsiHeuristics +import org.jetbrains.kotlin.idea.base.util.module +import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.platform.js.JsPlatforms import org.jetbrains.kotlin.psi.KtNamedFunction -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode -import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.types.Variance internal fun PsiElement.getAsJsMainFunctionOrNull(): KtNamedFunction? = (this as? KtNamedFunction)?.takeIf { it.isValidJsMain() } -internal fun KtNamedFunction.isValidJsMain(): Boolean = - isTopLevel && isJsPlatform() && isMainFun() +internal fun KtNamedFunction.isValidJsMain(): Boolean = isTopLevel && isJsPlatform() && isMainFun() internal fun KtNamedFunction.isJsPlatform(): Boolean = - module?.platform?.let { platform -> - platform in JsPlatforms.allJsPlatforms - } ?: false + module?.platform?.let { platform -> platform in JsPlatforms.allJsPlatforms } == true -internal fun KtNamedFunction.isMainFun(): Boolean { - if (name != "main") return false +internal fun KtNamedFunction.isMainFun(): Boolean = + isMainFromPsiOnly(this) && isMainFromAnalysis(this) - val parameters = valueParameters.toList() - if (parameters.size > 1) return false +////////////////////////////////////////////////////////////////// +// Copied and simplified from PsiOnlyKotlinMainFunctionDetector // +////////////////////////////////////////////////////////////////// +@RequiresReadLock +private fun isMainFromPsiOnly(function: KtNamedFunction): Boolean { + if (function.isLocal || function.typeParameters.isNotEmpty()) { + return false + } - val descriptor = resolveToDescriptorIfAny(BodyResolveMode.PARTIAL_NO_ADDITIONAL) - return descriptor is FunctionDescriptor - && isUnit(descriptor.returnType) - && (parameters.isEmpty() || descriptor.hasSingleArrayOfStringsParameter()) + val isTopLevel = function.isTopLevel + val parameterCount = + function.valueParameters.size + (if (function.receiverTypeReference != null) 1 else 0) + + if (parameterCount == 0) { + if (!isTopLevel) { + return false + } + + if ( + !function.languageVersionSettings.supportsFeature( + LanguageFeature.ExtendedMainConvention + ) + ) { + return false + } + } else if (parameterCount == 1 && !isMainCheckParameter(function)) { + return false + } else { + return false + } + + if ((KotlinPsiHeuristics.findJvmName(function) ?: function.name) != "main") { + return false + } + + if (!isTopLevel && !KotlinPsiHeuristics.hasJvmStaticAnnotation(function)) { + return false + } + + val returnTypeReference = function.typeReference + return !(returnTypeReference != null && + !KotlinPsiHeuristics.typeMatches(returnTypeReference, StandardClassIds.Unit)) +} + +private fun isMainCheckParameter(function: KtNamedFunction): Boolean { + val receiverTypeReference = function.receiverTypeReference + if (receiverTypeReference != null) { + return KotlinPsiHeuristics.typeMatches( + receiverTypeReference, + StandardClassIds.Array, + StandardClassIds.String, + ) + } + + val parameter = function.valueParameters.singleOrNull() ?: return false + val parameterTypeReference = parameter.typeReference ?: return false + + return when { + parameter.isVarArg -> + KotlinPsiHeuristics.typeMatches(parameterTypeReference, StandardClassIds.String) + else -> + KotlinPsiHeuristics.typeMatches( + parameterTypeReference, + StandardClassIds.Array, + StandardClassIds.String, + ) + } +} + +////////////////////////////////////////////////////////////////////// +// Copied and simplified from SymbolBasedKotlinMainFunctionDetector // +////////////////////////////////////////////////////////////////////// +private fun isMainFromAnalysis(function: KtNamedFunction): Boolean { + if (function.isLocal || function.typeParameters.isNotEmpty()) { + return false + } + + val supportsExtendedMainConvention = + function.languageVersionSettings.supportsFeature(LanguageFeature.ExtendedMainConvention) + + val isTopLevel = function.isTopLevel + val parameterCount = + function.valueParameters.size + (if (function.receiverTypeReference != null) 1 else 0) + + if (parameterCount == 0) { + if (!isTopLevel || !supportsExtendedMainConvention) { + return false + } + } else if (parameterCount > 1) { + return false + } + + analyze(function) { + if (parameterCount == 1) { + val parameterTypeReference = + function.receiverTypeReference + ?: function.valueParameters[0].typeReference + ?: return false + + val parameterType = parameterTypeReference.type + if ( + !parameterType.isResolvedClassType() || + !parameterType.isSubtypeOf(buildMainParameterType()) + ) { + return false + } + } + + val functionSymbol = function.symbol + if (functionSymbol !is KaNamedFunctionSymbol) { + return false + } + + if (functionSymbol.name.identifier != "main") { + return false + } + + if (!function.returnType.isUnitType) { + return false + } + } + return true } -private fun isUnit(type: KotlinType?): Boolean = - type != null && KotlinBuiltIns.isUnit(type) +private fun KaSession.buildMainParameterType(): KaType = + buildClassType(StandardClassIds.Array) { + val argumentType = + buildClassType(StandardClassIds.String) { nullability = KaTypeNullability.NON_NULLABLE } + + argument(argumentType, Variance.OUT_VARIANCE) + nullability = KaTypeNullability.NULLABLE + } -private fun FunctionDescriptor.hasSingleArrayOfStringsParameter(): Boolean { - val parameter = valueParameters.singleOrNull() ?: return false - val type = parameter.type - val typeArgument = type.arguments.singleOrNull()?.type - return KotlinBuiltIns.isArray(type) && KotlinBuiltIns.isString(typeArgument) -} \ No newline at end of file +private fun KaType.isResolvedClassType(): Boolean = + when (this) { + is KaClassType -> typeArguments.mapNotNull { it.type }.all { it.isResolvedClassType() } + else -> false + } diff --git a/idea-plugin/src/main/resources/META-INF/plugin.xml b/idea-plugin/src/main/resources/META-INF/plugin.xml index 947d927ea3..6accf89e54 100644 --- a/idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/idea-plugin/src/main/resources/META-INF/plugin.xml @@ -23,6 +23,10 @@ com.intellij.gradle org.jetbrains.kotlin + + + + + appendLine("## $section") + appendLine() + + sectionEntries + .sortedBy { it.subsectionOrder() } + .groupBy { it.subsectionName() } + .forEach { (subsection, subsectionEntries) -> + appendLine("### $subsection") + appendLine() + subsectionEntries.forEach { + appendLine(it.format()) + } + appendLine() + } + } + + append( + """ + ## Dependencies + + - Gradle Plugin `org.jetbrains.compose`, version `$lastVersion`. Based on Jetpack Compose libraries: + - [Runtime REDIRECT_PLACEHOLDER](https://developer.android.com/jetpack/androidx/releases/compose-runtime#REDIRECT_PLACEHOLDER) + - [UI REDIRECT_PLACEHOLDER](https://developer.android.com/jetpack/androidx/releases/compose-ui#REDIRECT_PLACEHOLDER) + - [Foundation REDIRECT_PLACEHOLDER](https://developer.android.com/jetpack/androidx/releases/compose-foundation#REDIRECT_PLACEHOLDER) + - [Material REDIRECT_PLACEHOLDER](https://developer.android.com/jetpack/androidx/releases/compose-material#REDIRECT_PLACEHOLDER) + - [Material3 REDIRECT_PLACEHOLDER](https://developer.android.com/jetpack/androidx/releases/compose-material3#REDIRECT_PLACEHOLDER) + + - Lifecycle libraries `org.jetbrains.androidx.lifecycle:lifecycle-*:RELEASE_PLACEHOLDER`. Based on [Jetpack Lifecycle REDIRECT_PLACEHOLDER](https://developer.android.com/jetpack/androidx/releases/lifecycle#REDIRECT_PLACEHOLDER) + - Navigation libraries `org.jetbrains.androidx.navigation:navigation-*:RELEASE_PLACEHOLDER`. Based on [Jetpack Navigation REDIRECT_PLACEHOLDER](https://developer.android.com/jetpack/androidx/releases/navigation#REDIRECT_PLACEHOLDER) + - Material3 Adaptive libraries `org.jetbrains.compose.material3.adaptive:adaptive*:RELEASE_PLACEHOLDER`. Based on [Jetpack Material3 Adaptive REDIRECT_PLACEHOLDER](https://developer.android.com/jetpack/androidx/releases/compose-material3-adaptive#REDIRECT_PLACEHOLDER) + + --- + """.trimIndent() + ) + + appendLine() + appendLine() + + val nonstandardSectionEntries = entries + .filter { + it.section != null && it.subsection != null + && it.section !in standardSections && it.subsection !in standardSubsections + } + + if (nonstandardSectionEntries.isNotEmpty()) { + println() + println("WARNING! Changelog contains nonstandard sections. Please change them to the standard ones, or enhance the list in the PR template.") + + for (entry in nonstandardSectionEntries) { + println("${entry.section} - ${entry.subsection} in ${entry.link}") + } + } + } +} + +/** + * September 2024 + */ +fun currentChangelogDate() = LocalDate.now().format(DateTimeFormatter.ofPattern("MMMM yyyy", Locale.ENGLISH)) + +/** + * Formats: + * - A new approach to implementation of `platformLayers`. Now extra layers (such as Dialogs and Popups) drawing is merged into a single screen size canvas. + * + * to: + * - [A new approach to implementation of `platformLayers`](link). Now extra layers (such as Dialogs and Popups) drawing is merged into a single screen size canvas. + */ +fun ChangelogEntry.format(): String { + return if (link != null) { + val linkStartIndex = maxOf( + message.indexOfFirst { !it.isWhitespace() && it != '-' }.ifNegative { 0 }, + message.endIndexOf("_(prerelease fix)_ ").ifNegative { 0 }, + message.endIndexOf("(prerelease fix) ").ifNegative { 0 }, + ) + val linkLastIndex = message.indexOfAny(listOf(". ", " (")).ifNegative { message.length } + + val beforeLink = message.substring(0, linkStartIndex) + val inLink = message.substring(linkStartIndex, linkLastIndex).removeLinks() + val afterLink = message.substring(linkLastIndex, message.length) + + "$beforeLink[$inLink]($link)$afterLink" + } else { + message + } +} + +fun Int.ifNegative(value: () -> Int): Int = if (this < 0) value() else this + +fun String.endIndexOf(value: String): Int = indexOf(value).let { + if (it >= 0) { + it + value.length + } else { + it + } +} + +/** + * Converts: + * Message (title)[some link], message + * + * to: + * Message title, message + */ +fun String.removeLinks(): String = replace(Regex("\\[([^)]*)\\]\\([^\\]]*\\)"), "$1") + +/** + * Extract by format https://github.com/JetBrains/compose-multiplatform/blob/master/.github/PULL_REQUEST_TEMPLATE.md?plain=1 + */ +fun GitHubPullEntry.extractReleaseNotes(link: String): List { + // extract body inside "## Release Notes" + val relNoteBody = run { + val after = body?.substringAfter("## Release Notes", "")?.ifBlank { null } + ?: body?.substringAfter("## Release notes", "")?.ifBlank { null } ?: body?.substringAfter( + "## RelNote", + "" + )?.ifBlank { null } + + val before = after?.substringBefore("\n## ", "")?.ifBlank { null } ?: after?.substringBefore("\n# ", "") + ?.ifBlank { null } ?: after + + before?.trim() + } + + val list = mutableListOf() + var section: String? = null + var subsection: String? = null + + for (line in relNoteBody.orEmpty().split("\n")) { + // parse "### Section - Subsection" + if (line.startsWith("### ")) { + val s = line.removePrefix("### ") + section = s.substringBefore("-", "").trim().normalizeSectionName().ifEmpty { null } + subsection = s.substringAfter("-", "").trim().normalizeSubsectionName().ifEmpty { null } + } else if (section != null && line.isNotBlank()) { + val isTopLevel = line.startsWith("-") + val trimmedLine = line.trimEnd().removeSuffix(".") + list.add( + ChangelogEntry( + trimmedLine, + section, + subsection, + link.takeIf { isTopLevel } + ) + ) + } + } + + return list +} + +/** + * @param repo Example: + * JetBrains/compose-multiplatform-core + */ +fun entriesForRepo(repo: String, firstCommit: String, lastCommit: String): List { + val pulls = (1..5) + .flatMap { + request>("https://api.github.com/repos/$repo/pulls?state=closed&per_page=100&page=$it").toList() + } + + val pullNumberToPull = pulls.associateBy { it.number } + val pullTitleToPull = pulls.associateBy { it.title } + + fun prForCommit(commit: GitHubCompareResponse.CommitEntry): GitHubPullEntry? { + val (repoTitle, repoNumber) = repoTitleAndNumberForCommit(commit) + return repoNumber?.let(pullNumberToPull::get) ?: pullTitleToPull[repoTitle] + } + + fun changelogEntriesFor( + pullRequest: GitHubPullEntry? + ): List { + return if (pullRequest != null) { + val prTitle = pullRequest.title + val prNumber = pullRequest.number + val prLink = "https://github.com/$repo/pull/$prNumber" + val prList = pullRequest.extractReleaseNotes(prLink) + val changelogMessage = "- $prTitle" + prList.ifEmpty { + listOf(ChangelogEntry(changelogMessage, null, null, prLink)) + } + } else { + listOf() + } + } + + class CommitsResult(val commits: List, val mergeBaseSha: String) + + fun fetchCommits(firsCommitSha: String, lastCommitSha: String): CommitsResult { + lateinit var mergeBaseCommit: String + val commits = fetchPagedUntilEmpty { page -> + val result = + request("https://api.github.com/repos/$repo/compare/$firsCommitSha...$lastCommitSha?per_page=1000&page=$page") + mergeBaseCommit = result.merge_base_commit.sha + result.commits + } + return CommitsResult(commits, mergeBaseCommit) + } + + val main = fetchCommits(firstCommit, lastCommit) + val previous = fetchCommits(main.mergeBaseSha, firstCommit) + val pullRequests = main.commits.mapNotNull { prForCommit(it) }.toSet() + val previousVersionPullRequests = previous.commits.mapNotNull { prForCommit(it) }.toSet() + return (pullRequests - previousVersionPullRequests).flatMap { changelogEntriesFor(it) } +} + +/** + * Extract the PR number from the commit. + */ +fun repoTitleAndNumberForCommit(commit: GitHubCompareResponse.CommitEntry): Pair { + val commitTitle = commit.commit.message.substringBefore("\n") + // check title similar to `Fix import android flavors with compose resources (#4319)` + val title = commitTitle.substringBeforeLast(" (#") + val number = commitTitle.substringAfterLast(" (#").substringBefore(")").toIntOrNull() + return title to number +} + +data class ChangelogEntry( + val message: String, + val section: String?, + val subsection: String?, + val link: String?, +) + +fun ChangelogEntry.sectionOrder(): Int = section?.let(standardSections::indexOf) ?: standardSections.size +fun ChangelogEntry.subsectionOrder(): Int = subsection?.let(standardSubsections::indexOf) ?: standardSubsections.size +fun ChangelogEntry.sectionName(): String = section ?: "Unknown" +fun ChangelogEntry.subsectionName(): String = subsection ?: "Unknown" +fun String.normalizeSectionName() = standardSections.find { it.lowercase() == this.lowercase() } ?: this +fun String.normalizeSubsectionName() = standardSubsections.find { it.lowercase() == this.lowercase() } ?: this + +// example https://api.github.com/repos/JetBrains/compose-multiplatform-core/compare/v1.6.0-rc02...release/1.6.0 +data class GitHubCompareResponse(val commits: List, val merge_base_commit: CommitEntry) { + data class CommitEntry(val sha: String, val commit: Commit) + data class Commit(val message: String) +} + +// example https://api.github.com/repos/JetBrains/compose-multiplatform-core/pulls?state=closed +data class GitHubPullEntry(val number: Int, val title: String, val body: String?, val labels: List