Revert "[compose] IJPL-527: Unbundle Compose from IntelliJ Platform"

This reverts commit 991f28b1

GitOrigin-RevId: 118f1b208ccb94e62784da92a2a850da8f0da817
This commit is contained in:
Jakub Senohrabek
2024-07-01 12:48:17 +02:00
committed by intellij-monorepo-bot
parent a634057bc9
commit dc82835a8a
23 changed files with 950 additions and 40 deletions

View File

@@ -0,0 +1,126 @@
<component name="libraryTable">
<library name="jetbrains.compose.foundation.desktop" type="repository">
<properties maven-id="org.jetbrains.compose.foundation:foundation-desktop:1.7.0-dev1703">
<verification>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/compose/foundation/foundation-desktop/1.7.0-dev1703/foundation-desktop-1.7.0-dev1703.jar">
<sha256sum>6e0393b0d6b9308a0fbc359a1732593322b8b4108e6d033469f1dedbbbdf5031</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/androidx/annotation/annotation-jvm/1.8.0/annotation-jvm-1.8.0.jar">
<sha256sum>9aab326d9492800991854360ac248f493ce7f7c3183519309b78ace9e240f6f6</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/androidx/collection/collection-jvm/1.4.0/collection-jvm-1.4.0.jar">
<sha256sum>d5cf7b72647c7995071588fe870450ff9c8f127f253d2d4851e161b800f67ae0</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/compose/animation/animation-desktop/1.7.0-dev1703/animation-desktop-1.7.0-dev1703.jar">
<sha256sum>98e329d2e50ec465c7e3150f572487b5b6afb0ed4ab978630cb233aecc26fd63</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/compose/animation/animation-core-desktop/1.7.0-dev1703/animation-core-desktop-1.7.0-dev1703.jar">
<sha256sum>444f9d9c0fccbf8ec5b9efc79c4039de3921975612e13d71b21df836956aee0a</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-geometry-desktop/1.7.0-dev1703/ui-geometry-desktop-1.7.0-dev1703.jar">
<sha256sum>4b86c961c0b4bce7995329fd57d4339ede11cb75d7ec90bc1b9913396addb30f</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/compose/foundation/foundation-layout-desktop/1.7.0-dev1703/foundation-layout-desktop-1.7.0-dev1703.jar">
<sha256sum>f229a89e4be8c7289b100e3f1cab616f97e9a361964aafb5e2290958935fbb21</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/compose/runtime/runtime-desktop/1.7.0-dev1703/runtime-desktop-1.7.0-dev1703.jar">
<sha256sum>afb8d12e503081d5b83a65bfe7184ff6248c8c6e03119249638cbbe9dd3c8e8a</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-desktop/1.7.0-dev1703/ui-desktop-1.7.0-dev1703.jar">
<sha256sum>86113f6063e4e8647dcbd07c3cbebb19c98b3c9525faa1e807d5da226ca41b94</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/androidx/lifecycle/lifecycle-common-jvm/2.8.0/lifecycle-common-jvm-2.8.0.jar">
<sha256sum>61c873a7327c946ec033c310bb98f3f92eeabcede0e1a5200ab8a1896483c7bf</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/androidx/lifecycle/lifecycle-runtime-desktop/2.8.0/lifecycle-runtime-desktop-2.8.0.jar">
<sha256sum>10bfe53bb2752f967751a5102cdb785eeea54e1d4df6bde88fb0f50b0a49156c</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/androidx/arch/core/core-common/2.2.0/core-common-2.2.0.jar">
<sha256sum>65308a06b1c00ee186cb9e19321383f043b993813f1522c47f4a3e3303bdba41</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/androidx/annotation/annotation/1.1.0/annotation-1.1.0.jar">
<sha256sum>d38d63edb30f1467818d50aaf05f8a692dea8b31392a049bfa991b159ad5b692</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/androidx/lifecycle/lifecycle-viewmodel-desktop/2.8.0/lifecycle-viewmodel-desktop-2.8.0.jar">
<sha256sum>5c28f3ba9732f2180685038dbe674059fd9b7843c721cd0f6c73f3dbfcb2683c</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/androidx/lifecycle/lifecycle-runtime-compose-desktop/2.8.0-dev1703/lifecycle-runtime-compose-desktop-2.8.0-dev1703.jar">
<sha256sum>a86a4faee71844ab986c6e1af67aae412b802f99b4a611113305e9f9d04fc271</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/compose/runtime/runtime-saveable-desktop/1.7.0-dev1703/runtime-saveable-desktop-1.7.0-dev1703.jar">
<sha256sum>bc30d93dce0bdf9c8ea707227ebb85b82694e4a0ddab618aa5bb5613c3b87cc0</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-graphics-desktop/1.7.0-dev1703/ui-graphics-desktop-1.7.0-dev1703.jar">
<sha256sum>5acc2058c905ceca092cfe8cd91bb082df7fce6126c971d826ca64b538dc7b92</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-unit-desktop/1.7.0-dev1703/ui-unit-desktop-1.7.0-dev1703.jar">
<sha256sum>598b52e257ed674145694b9790a7383a90fed2ec7154ba09ace4aa983c65b1a2</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-text-desktop/1.7.0-dev1703/ui-text-desktop-1.7.0-dev1703.jar">
<sha256sum>faccd4d5e86a3ab2741cdf5dc82e8e765cf0ada911ec929436940eae0a6807ef</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-util-desktop/1.7.0-dev1703/ui-util-desktop-1.7.0-dev1703.jar">
<sha256sum>161dcc73b929da61cee50045e96fb02f1633c36f18a2ef38b5c2c44c38606b52</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/skiko/skiko-awt/0.8.9/skiko-awt-0.8.9.jar">
<sha256sum>c7f5c1253a1f7ea5876aa122309b517cce1b4d1522eb65eedd8579ec83e5a083</sha256sum>
</artifact>
</verification>
<exclude>
<dependency maven-id="org.jetbrains.kotlin:kotlin-stdlib" />
<dependency maven-id="org.jetbrains.kotlin:kotlin-stdlib-common" />
<dependency maven-id="org.jetbrains.kotlinx:atomicfu-jvm" />
<dependency maven-id="org.jetbrains.kotlinx:kotlinx-coroutines-core" />
<dependency maven-id="org.jetbrains.kotlin:kotlin-stdlib-jdk8" />
<dependency maven-id="org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm" />
</exclude>
</properties>
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/foundation/foundation-desktop/1.7.0-dev1703/foundation-desktop-1.7.0-dev1703.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/annotation/annotation-jvm/1.8.0/annotation-jvm-1.8.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/collection/collection-jvm/1.4.0/collection-jvm-1.4.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/animation/animation-desktop/1.7.0-dev1703/animation-desktop-1.7.0-dev1703.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/animation/animation-core-desktop/1.7.0-dev1703/animation-core-desktop-1.7.0-dev1703.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-geometry-desktop/1.7.0-dev1703/ui-geometry-desktop-1.7.0-dev1703.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/foundation/foundation-layout-desktop/1.7.0-dev1703/foundation-layout-desktop-1.7.0-dev1703.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/runtime/runtime-desktop/1.7.0-dev1703/runtime-desktop-1.7.0-dev1703.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-desktop/1.7.0-dev1703/ui-desktop-1.7.0-dev1703.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/lifecycle/lifecycle-common-jvm/2.8.0/lifecycle-common-jvm-2.8.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/lifecycle/lifecycle-runtime-desktop/2.8.0/lifecycle-runtime-desktop-2.8.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/arch/core/core-common/2.2.0/core-common-2.2.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/annotation/annotation/1.1.0/annotation-1.1.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/lifecycle/lifecycle-viewmodel-desktop/2.8.0/lifecycle-viewmodel-desktop-2.8.0.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/androidx/lifecycle/lifecycle-runtime-compose-desktop/2.8.0-dev1703/lifecycle-runtime-compose-desktop-2.8.0-dev1703.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/runtime/runtime-saveable-desktop/1.7.0-dev1703/runtime-saveable-desktop-1.7.0-dev1703.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-graphics-desktop/1.7.0-dev1703/ui-graphics-desktop-1.7.0-dev1703.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-unit-desktop/1.7.0-dev1703/ui-unit-desktop-1.7.0-dev1703.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-text-desktop/1.7.0-dev1703/ui-text-desktop-1.7.0-dev1703.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-util-desktop/1.7.0-dev1703/ui-util-desktop-1.7.0-dev1703.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/skiko/skiko-awt/0.8.9/skiko-awt-0.8.9.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/foundation/foundation-desktop/1.7.0-dev1703/foundation-desktop-1.7.0-dev1703-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/annotation/annotation-jvm/1.8.0/annotation-jvm-1.8.0-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/collection/collection-jvm/1.4.0/collection-jvm-1.4.0-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/animation/animation-desktop/1.7.0-dev1703/animation-desktop-1.7.0-dev1703-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/animation/animation-core-desktop/1.7.0-dev1703/animation-core-desktop-1.7.0-dev1703-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-geometry-desktop/1.7.0-dev1703/ui-geometry-desktop-1.7.0-dev1703-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/foundation/foundation-layout-desktop/1.7.0-dev1703/foundation-layout-desktop-1.7.0-dev1703-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/runtime/runtime-desktop/1.7.0-dev1703/runtime-desktop-1.7.0-dev1703-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-desktop/1.7.0-dev1703/ui-desktop-1.7.0-dev1703-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/lifecycle/lifecycle-common-jvm/2.8.0/lifecycle-common-jvm-2.8.0-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/lifecycle/lifecycle-runtime-desktop/2.8.0/lifecycle-runtime-desktop-2.8.0-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/arch/core/core-common/2.2.0/core-common-2.2.0-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/annotation/annotation/1.1.0/annotation-1.1.0-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/androidx/lifecycle/lifecycle-viewmodel-desktop/2.8.0/lifecycle-viewmodel-desktop-2.8.0-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/androidx/lifecycle/lifecycle-runtime-compose-desktop/2.8.0-dev1703/lifecycle-runtime-compose-desktop-2.8.0-dev1703-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/runtime/runtime-saveable-desktop/1.7.0-dev1703/runtime-saveable-desktop-1.7.0-dev1703-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-graphics-desktop/1.7.0-dev1703/ui-graphics-desktop-1.7.0-dev1703-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-unit-desktop/1.7.0-dev1703/ui-unit-desktop-1.7.0-dev1703-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-text-desktop/1.7.0-dev1703/ui-text-desktop-1.7.0-dev1703-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/ui/ui-util-desktop/1.7.0-dev1703/ui-util-desktop-1.7.0-dev1703-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/skiko/skiko-awt/0.8.9/skiko-awt-0.8.9-sources.jar!/" />
</SOURCES>
</library>
</component>

6
.idea/modules.xml generated
View File

@@ -581,6 +581,12 @@
<module fileurl="file://$PROJECT_DIR$/platform/collaboration-tools/intellij.platform.collaborationTools.iml" filepath="$PROJECT_DIR$/platform/collaboration-tools/intellij.platform.collaborationTools.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/collaboration-tools/auth/intellij.platform.collaborationTools.auth.iml" filepath="$PROJECT_DIR$/platform/collaboration-tools/auth/intellij.platform.collaborationTools.auth.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/collaboration-tools/auth-base/intellij.platform.collaborationTools.auth.base.iml" filepath="$PROJECT_DIR$/platform/collaboration-tools/auth-base/intellij.platform.collaborationTools.auth.base.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/compose/intellij.platform.compose.iml" filepath="$PROJECT_DIR$/platform/compose/intellij.platform.compose.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/compose/intellij.platform.compose.iml" filepath="$PROJECT_DIR$/platform/compose/intellij.platform.compose.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/compose/compiler-plugin/intellij.platform.compose.compilerPlugin.iml" filepath="$PROJECT_DIR$/platform/compose/compiler-plugin/intellij.platform.compose.compilerPlugin.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/compose/compiler-plugin/intellij.platform.compose.compilerPlugin.iml" filepath="$PROJECT_DIR$/platform/compose/compiler-plugin/intellij.platform.compose.compilerPlugin.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/compose/skiko-runtime/intellij.platform.compose.skikoRuntime.iml" filepath="$PROJECT_DIR$/platform/compose/skiko-runtime/intellij.platform.compose.skikoRuntime.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/compose/skiko-runtime/intellij.platform.compose.skikoRuntime.iml" filepath="$PROJECT_DIR$/platform/compose/skiko-runtime/intellij.platform.compose.skikoRuntime.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/util/concurrency/intellij.platform.concurrency.iml" filepath="$PROJECT_DIR$/platform/util/concurrency/intellij.platform.concurrency.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/configuration-store-impl/intellij.platform.configurationStore.impl.iml" filepath="$PROJECT_DIR$/platform/configuration-store-impl/intellij.platform.configurationStore.impl.iml" />
<module fileurl="file://$PROJECT_DIR$/platform/configuration-store-impl/intellij.platform.configurationStore.tests.iml" filepath="$PROJECT_DIR$/platform/configuration-store-impl/intellij.platform.configurationStore.tests.iml" />

View File

@@ -220,5 +220,6 @@
<orderEntry type="module" module-name="intellij.yaml.editing" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.platform.whatsNew" scope="TEST" />
<orderEntry type="module" module-name="intellij.java.compiler.charts" scope="RUNTIME" />
<orderEntry type="module" module-name="intellij.platform.compose" scope="RUNTIME" />
</component>
</module>

View File

@@ -218,6 +218,14 @@ object CommunityLibraryLicenses {
LibraryLicense(name = "Compose Animation Tooling", libraryName = "ui-animation-tooling-internal", version = "0.1.0-SNAPSHOT",
url = "https://source.android.com/").apache()
.suppliedByOrganizations(Suppliers.GOOGLE),
LibraryLicense(name = "Compose Multiplatform", libraryName = "jetbrains.compose.foundation.desktop",
url = "https://github.com/JetBrains/compose-multiplatform")
.apache("https://github.com/JetBrains/compose-multiplatform/blob/master/LICENSE.txt")
.suppliedByOrganizations(Suppliers.JETBRAINS),
LibraryLicense(name = "Compose Multiplatform Compiler", libraryName = "jetbrains.compose.compiler.hosted",
url = "https://github.com/JetBrains/compose-multiplatform")
.apache("https://github.com/JetBrains/compose-multiplatform/blob/master/LICENSE.txt")
.suppliedByOrganizations(Suppliers.JETBRAINS),
// For ADB wireless QR Code generation
LibraryLicense(name = "Core barcode encoding/decoding library", url = "https://github.com/zxing/zxing/tree/master/core",
libraryName = "zxing-core").apache("https://github.com/zxing/zxing/blob/master/LICENSE")
@@ -579,6 +587,9 @@ object CommunityLibraryLicenses {
LibraryLicense(name = "jetCheck", libraryName = "jetCheck", url = "https://github.com/JetBrains/jetCheck")
.apache("https://github.com/JetBrains/jetCheck/blob/master/LICENSE")
.suppliedByOrganizations(Suppliers.JETBRAINS),
LibraryLicense(name = "Jewel", libraryName = "jetbrains.jewel", url = "https://github.com/JetBrains/jewel")
.apache("https://github.com/JetBrains/jewel/blob/main/LICENSE")
.suppliedByOrganizations(Suppliers.JETBRAINS),
LibraryLicense(name = "JGit (Settings Sync and SettingsRepo)", libraryName = "jetbrains.intellij.deps.eclipse.jgit",
license = "Eclipse Distribution License 1.0",
licenseUrl = "https://www.eclipse.org/org/documents/edl-v10.php", url = "https://www.eclipse.org/jgit/")
@@ -978,6 +989,9 @@ object CommunityLibraryLicenses {
url = "https://six.readthedocs.io/",
licenseUrl = "https://github.com/benjaminp/six/blob/master/LICENSE")
.mit("https://github.com/benjaminp/six/blob/master/LICENSE"),
LibraryLicense(name = "Skiko Runtime", libraryName = "jetbrains.skiko.awt.runtime.all",
url = "https://github.com/JetBrains/skiko/")
.apache("https://github.com/JetBrains/skiko/blob/master/LICENSE"),
LibraryLicense(libraryName = "slf4j-api", url = "https://slf4j.org/")
.mit("https://www.slf4j.org/license.html")
.suppliedByOrganizations("QOS.ch Sarl"),

View File

@@ -46,7 +46,9 @@ fun getIdeSystemProperties(runDir: Path): VmProperties {
// require bundled JNA dispatcher lib
"jna.nosys" to "true",
"jna.noclasspath" to "true",
"jb.vmOptionsFile" to "${Files.newDirectoryStream(runDir.parent, "*.vmoptions").use { it.singleOrNull() }}"
"jb.vmOptionsFile" to "${Files.newDirectoryStream(runDir.parent, "*.vmoptions").use { it.singleOrNull() }}",
"skiko.library.path" to "$libDir/skiko-awt-runtime-all",
"compose.swing.render.on.graphics" to "true",
)
)
return VmProperties(result)

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@file:Suppress("ReplaceGetOrSet", "ReplaceJavaStaticMethodWithKotlinAnalog")
package org.jetbrains.intellij.build.impl
@@ -331,6 +331,9 @@ class BuildContextImpl internal constructor(
// https://youtrack.jetbrains.com/issue/IDEA-269280
jvmArgs.add("-Daether.connector.resumeDownloads=false")
jvmArgs.add("-Dskiko.library.path=${macroName}/lib/skiko-awt-runtime-all".let { if (isScript) '"' + it + '"' else it })
jvmArgs.add("-Dcompose.swing.render.on.graphics=true")
jvmArgs.addAll(getCommandLineArgumentsForOpenPackages(this, os))
return jvmArgs

View File

@@ -64,7 +64,7 @@ private val libsThatUsedInJps = java.util.Set.of(
@Suppress("ReplaceJavaStaticMethodWithKotlinAnalog")
private val presignedLibNames = java.util.Set.of(
"pty4j", "jna", "sqlite-native", "async-profiler"
"pty4j", "jna", "sqlite-native", "async-profiler", "jetbrains.skiko.awt.runtime.all"
)
private fun isLibPreSigned(library: JpsLibrary) = presignedLibNames.contains(library.name)
@@ -835,7 +835,8 @@ private class NativeFileHandlerImpl(private val context: BuildContext, private v
return isMacLibrary(name) ||
name.endsWith(".exe") ||
name.endsWith(".dll") ||
name.endsWith("pty4j-unix-spawn-helper")
name.endsWith("pty4j-unix-spawn-helper") ||
name.endsWith("icudtl.dat")
}
@Suppress("SpellCheckingInspection", "GrazieInspection")
@@ -846,7 +847,7 @@ private class NativeFileHandlerImpl(private val context: BuildContext, private v
// we allow to use .so for macOS binraries (binaries/macos/libasyncProfiler.so), but removing obvious linux binaries
// (binaries/linux-aarch64/libasyncProfiler.so) to avoid detecting by binary content
if (name.endsWith(".dll") || name.endsWith(".exe") || name.contains("/linux/") || name.contains("/linux-")) {
if (name.endsWith(".dll") || name.endsWith(".exe") || name.contains("/linux/") || name.contains("/linux-") || name.contains("icudtl.dat")) {
return null
}

View File

@@ -86,6 +86,9 @@ private val PLATFORM_IMPLEMENTATION_MODULES = java.util.List.of(
"intellij.platform.vcs.log",
"intellij.platform.compose",
"intellij.platform.compose.skikoRuntime",
"intellij.platform.markdown.utils",
"intellij.platform.util.commonsLangV2Shim",
@@ -146,6 +149,12 @@ internal suspend fun createPlatformLayout(projectLibrariesUsedByPlugins: SortedS
), productLayout = productLayout, layout = layout)
layout.withProjectLibrary(libraryName = "ion", jarName = UTIL_8_JAR)
layout.withModuleLibrary(
libraryName = "jetbrains.skiko.awt.runtime.all",
moduleName = "intellij.platform.compose.skikoRuntime",
relativeOutputPath = "skiko-runtime.jar"
)
// maven uses JDOM in an external process
addModule(UTIL_8_JAR, listOf(
"intellij.platform.util.jdom",

View File

@@ -20,15 +20,43 @@ import java.nio.file.attribute.PosixFilePermission
import java.nio.file.attribute.PosixFilePermissions
import java.util.*
/**
* Set of native files that shouldn't be signed.
*/
@Suppress("SpellCheckingInspection")
private val nonSignFiles = java.util.Set.of(
// Native file used by skiko (Compose backend) for Windows.
// It cannot be signed.
"icudtl.dat"
)
@VisibleForTesting
object OsFamilyDetector {
private val regex = "(^|/)((?<macos>(darwin|mac|macos)[-/])|(?<win>win32-|(win|windows)[-/])|(?<android>Linux-(Android|Musl)/)|(?<linux>linux[-/]))".toRegex(RegexOption.IGNORE_CASE)
private val macosRegex = "(darwin|mac|macos)".toRegex(RegexOption.IGNORE_CASE)
private val windowsRegex = "(windows|win32-|win)".toRegex(RegexOption.IGNORE_CASE)
private val linuxRegex = "linux".toRegex(RegexOption.IGNORE_CASE)
private val regex = "(^|-|/)((?<macos>(darwin|mac|macos)[-/])|(?<win>win32-|(win|windows)[-/])|(?<android>Linux-(Android|Musl)/)|(?<linux>linux[-/]))".toRegex(RegexOption.IGNORE_CASE)
fun detectOsFamily(path: String): Pair<OsFamily, String>? {
if (!path.contains("/")) { // support for dirless natives like skiko
return when {
macosRegex.containsMatchIn(path) -> OsFamily.MACOS to ""
windowsRegex.containsMatchIn(path) -> OsFamily.WINDOWS to ""
linuxRegex.containsMatchIn(path) -> OsFamily.LINUX to ""
path == "icudtl.dat" -> OsFamily.WINDOWS to ""
else -> null
}
}
fun detectOsFamily(path: String): Pair<OsFamily, Int>? {
val result = regex.find(path) ?: return null
return result.groups["macos"]?.run { OsFamily.MACOS to range.first }
?: result.groups["win"]?.run { OsFamily.WINDOWS to range.first }
?: result.groups["linux"]?.run { OsFamily.LINUX to range.first }
return result.groups["macos"]?.run { OsFamily.MACOS to path.extractPrefix(range) }
?: result.groups["win"]?.run { OsFamily.WINDOWS to path.extractPrefix(range) }
?: result.groups["linux"]?.run { OsFamily.LINUX to path.extractPrefix(range) }
}
private fun String.extractPrefix(range: IntRange): String {
return subSequence(startIndex = 0, endIndex = range.first).toString()
}
}
@@ -40,13 +68,16 @@ class NativeFilesMatcher(paths: List<String>, private val targetOs: Iterable<OsF
fun findNext(): Match? {
while (iterator.hasNext()) {
val pathWithPrefix = iterator.next()
val osAndIndex = OsFamilyDetector.detectOsFamily(pathWithPrefix) ?: continue
val prefix = commonPathPrefix?.apply {
assert(length == osAndIndex.second) {
val (osFamily, newPrefix) = OsFamilyDetector.detectOsFamily(pathWithPrefix) ?: continue
if (commonPathPrefix != null) {
assert(commonPathPrefix == newPrefix) {
"All native runtimes should have common path prefix. Failed to match $pathWithPrefix to $this"
}
} ?: pathWithPrefix.subSequence(startIndex = 0, endIndex = osAndIndex.second).also { commonPathPrefix = it }
val osFamily = osAndIndex.first
}
val prefix = commonPathPrefix ?: newPrefix.also { commonPathPrefix = it }
if (targetOs != null && !targetOs.contains(osFamily)) {
continue
}
@@ -72,11 +103,13 @@ class NativeFilesMatcher(paths: List<String>, private val targetOs: Iterable<OsF
}
}
private val posixExecutableFileAttribute = PosixFilePermissions.asFileAttribute(EnumSet.of(
PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE,
PosixFilePermission.GROUP_READ, PosixFilePermission.GROUP_EXECUTE,
PosixFilePermission.OTHERS_READ, PosixFilePermission.OTHERS_EXECUTE
))
private val posixExecutableFileAttribute = PosixFilePermissions.asFileAttribute(
EnumSet.of(
PosixFilePermission.OWNER_READ, PosixFilePermission.OWNER_WRITE, PosixFilePermission.OWNER_EXECUTE,
PosixFilePermission.GROUP_READ, PosixFilePermission.GROUP_EXECUTE,
PosixFilePermission.OTHERS_READ, PosixFilePermission.OTHERS_EXECUTE
)
)
internal suspend fun packNativePresignedFiles(
nativeFiles: Map<ZipSource, List<String>>,
@@ -138,7 +171,7 @@ private suspend fun unpackNativeLibraries(
val os = match.osFamily
val arch = match.arch
var file: Path? = if (os == OsFamily.LINUX || signTool.signNativeFileMode != SignNativeFileMode.ENABLED) {
var file: Path? = if (os == OsFamily.LINUX || fileName in nonSignFiles || signTool.signNativeFileMode != SignNativeFileMode.ENABLED) {
null
}
else {
@@ -152,17 +185,19 @@ private suspend fun unpackNativeLibraries(
extractFileToDisk(file = file, zipFile = zipFile, pathWithPackage = pathWithPackage)
}
if (os != OsFamily.LINUX) {
if (os != OsFamily.LINUX && fileName !in nonSignFiles) {
unsignedFiles.computeIfAbsent(os) { mutableListOf() }.add(file)
}
}
context.addDistFile(DistFile(
content = LocalDistFileContent(file),
relativePath = toRelativePath(libName, getRelativePath(libName = libName, arch = arch, fileName = fileName, path = path)),
os = os.takeUnless { allPlatformsRequired },
arch = arch.takeUnless { allPlatformsRequired },
))
context.addDistFile(
DistFile(
content = LocalDistFileContent(file),
relativePath = toRelativePath(libName, getRelativePath(libName = libName, arch = arch, fileName = fileName, path = path)),
os = os.takeUnless { allPlatformsRequired },
arch = arch.takeUnless { allPlatformsRequired },
)
)
}
}
@@ -177,10 +212,12 @@ private suspend fun unpackNativeLibraries(
launch {
unsignedFiles.get(OsFamily.WINDOWS)?.let {
@Suppress("SpellCheckingInspection")
context.signFiles(it, BuildOptions.WIN_SIGN_OPTIONS + versionOption + persistentMapOf(
context.signFiles(
it, BuildOptions.WIN_SIGN_OPTIONS + versionOption + persistentMapOf(
"contentType" to "application/x-exe",
"jsign_replace" to "true"
))
)
)
}
}
}
@@ -212,6 +249,7 @@ private fun extractFileToDisk(file: Path, zipFile: ZipFile, pathWithPackage: Str
private enum class NativeFileArchitecture(@JvmField val jvmArch: JvmArchitecture?) {
X_64(JvmArchitecture.x64),
AARCH_64(JvmArchitecture.aarch64),
// universal native file can be used by any platform
UNIVERSAL(null);
@@ -223,10 +261,19 @@ private enum class NativeFileArchitecture(@JvmField val jvmArch: JvmArchitecture
@Suppress("SpellCheckingInspection")
private fun determineArch(os: OsFamily, path: CharSequence): NativeFileArchitecture? {
// detect architecture from subfolders e.g. "linux-aarch64/libsqliteij.so"
if (!path.contains("/")) {
return when {
path.contains("x64") -> X_64
path.contains("aarch64") || path.contains("arm64") -> AARCH_64
path == "icudtl.dat" -> UNIVERSAL
else -> null
}
}
val osAndArch = path.indexOf('/').takeIf { it != -1 }?.let { path.subSequence(0, it) } ?: return null
return when {
osAndArch.endsWith("-aarch64") || path.contains("/aarch64/") -> AARCH_64
path.contains("x86-64") || path.contains("x86_64") -> X_64
osAndArch.endsWith("-aarch64") || path.contains("/aarch64/") || osAndArch.contains("arm64") -> AARCH_64
path.contains("x86-64") || path.contains("x86_64") || osAndArch.contains("x64") -> X_64
os == OsFamily.MACOS && path.count { it == '/' } == 1 -> UNIVERSAL
!osAndArch.contains('-') && path.count { it == '/' } == 1 -> X_64
else -> null
@@ -235,11 +282,16 @@ private fun determineArch(os: OsFamily, path: CharSequence): NativeFileArchitect
// each library has own implementation of handling path property
private fun getRelativePath(libName: String, arch: JvmArchitecture?, fileName: String, path: String): String {
if (libName == "async-profiler") {
return if (arch == null) fileName else "${arch.dirName}/$fileName"
}
else {
return if (libName == "jna") "${arch!!.dirName}/$fileName" else path
when (libName) {
"async-profiler" -> {
return if (arch == null) fileName else "${arch.dirName}/$fileName"
}
"skiko-awt-runtime-all" -> {
return fileName
}
else -> {
return if (libName == "jna") "${arch!!.dirName}/$fileName" else path
}
}
}

View File

@@ -77,7 +77,13 @@ class NativeFileMatcherTest {
Arguments.of("binaries/windows-aarch64/jniSymbolsResolver.dll", "binaries/", OsFamily.WINDOWS),
Arguments.of("binaries/windows-aarch64/libasyncProfiler.dll", "binaries/", OsFamily.WINDOWS),
Arguments.of("binaries/windows-aarch64/symsrv.dll", "binaries/", OsFamily.WINDOWS),
Arguments.of("runtime/macos-aarch64/RenderDocHost", "runtime/", OsFamily.MACOS)
Arguments.of("runtime/macos-aarch64/RenderDocHost", "runtime/", OsFamily.MACOS),
Arguments.of("libskiko-linux-arm64.so", "", OsFamily.LINUX),
Arguments.of("libskiko-linux-x64.so", "", OsFamily.LINUX),
Arguments.of("libskiko-macos-arm64.so", "", OsFamily.MACOS),
Arguments.of("libskiko-macos-x64.so", "", OsFamily.MACOS),
Arguments.of("skiko-windows-arm64.dll", "", OsFamily.WINDOWS),
Arguments.of("skiko-windows-x64.dll", "", OsFamily.WINDOWS)
)
}
@@ -153,7 +159,7 @@ class NativeFileMatcherTest {
Arguments.of(sqliteMacosFiles, listOf(OsFamily.MACOS), JvmArchitecture.x64, listOf(NativeFilesMatcher.Match("sqlite/mac-x86_64/libsqliteij.jnilib", "mac-x86_64/libsqliteij.jnilib", OsFamily.MACOS, JvmArchitecture.x64)), sqlitePrefix),
Arguments.of(sqliteMacosFiles, listOf(OsFamily.MACOS), JvmArchitecture.aarch64, listOf(NativeFilesMatcher.Match("sqlite/mac-aarch64/libsqliteij.jnilib", "mac-aarch64/libsqliteij.jnilib", OsFamily.MACOS, JvmArchitecture.aarch64)), sqlitePrefix),
Arguments.of(sqliteMacosFiles, listOf(OsFamily.MACOS), null, listOf(NativeFilesMatcher.Match("sqlite/mac-x86_64/libsqliteij.jnilib", "mac-x86_64/libsqliteij.jnilib", OsFamily.MACOS, JvmArchitecture.x64), NativeFilesMatcher.Match("sqlite/mac-aarch64/libsqliteij.jnilib", "mac-aarch64/libsqliteij.jnilib", OsFamily.MACOS, JvmArchitecture.aarch64)), sqlitePrefix),
Arguments.of(listOf("runtime/windows-x86_64/RenderDocHost.exe", "runtime/windows-x86_64/renderdoc.dll"), listOf(OsFamily.WINDOWS), JvmArchitecture.x64, listOf(NativeFilesMatcher.Match("runtime/windows-x86_64/RenderDocHost.exe", "windows-x86_64/RenderDocHost.exe", OsFamily.WINDOWS, JvmArchitecture.x64), NativeFilesMatcher.Match("runtime/windows-x86_64/renderdoc.dll", "windows-x86_64/renderdoc.dll", OsFamily.WINDOWS, JvmArchitecture.x64)), "runtime/")
Arguments.of(listOf("runtime/windows-x86_64/RenderDocHost.exe", "runtime/windows-x86_64/renderdoc.dll"), listOf(OsFamily.WINDOWS), JvmArchitecture.x64, listOf(NativeFilesMatcher.Match("runtime/windows-x86_64/RenderDocHost.exe", "windows-x86_64/RenderDocHost.exe", OsFamily.WINDOWS, JvmArchitecture.x64), NativeFilesMatcher.Match("runtime/windows-x86_64/renderdoc.dll", "windows-x86_64/renderdoc.dll", OsFamily.WINDOWS, JvmArchitecture.x64)), "runtime/"),
)
}
}
@@ -162,7 +168,7 @@ class NativeFileMatcherTest {
@MethodSource("provideTestCasesForOsDetection")
fun `os detection`(path: String, prefix: String?, osFamily: OsFamily?) {
val osAndIndex = OsFamilyDetector.detectOsFamily(path)
assertThat(osAndIndex?.second).isEqualTo(prefix?.length)
assertThat(osAndIndex?.second).isEqualTo(prefix)
assertThat(osAndIndex?.first).isEqualTo(osFamily)
}

View File

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library" scope="PROVIDED">
<library name="jetbrains.compose.compiler.hosted" type="repository">
<properties include-transitive-deps="false" maven-id="org.jetbrains.compose.compiler:compiler-hosted:1.5.14">
<verification>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/compose/compiler/compiler-hosted/1.5.14/compiler-hosted-1.5.14.jar">
<sha256sum>1133b3191ec68f97cf326bf95cbe00cab5d2f39493812e8e36f0e42dad059f64</sha256sum>
</artifact>
</verification>
</properties>
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/compiler/compiler-hosted/1.5.14/compiler-hosted-1.5.14.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/compose/compiler/compiler-hosted/1.5.14/compiler-hosted-1.5.14-sources.jar!/" />
</SOURCES>
</library>
</orderEntry>
</component>
</module>

View File

@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="kotlin-language" name="Kotlin">
<configuration version="5" platform="JVM 17" allPlatforms="JVM [17]" useProjectSettings="false">
<compilerSettings>
<option name="additionalArguments" value="-Xjvm-default=all" />
</compilerSettings>
<compilerArguments>
<stringArguments>
<stringArg name="jvmTarget" arg="17" />
<stringArg name="apiVersion" arg="1.9" />
<stringArg name="languageVersion" arg="1.9" />
</stringArguments>
<arrayArguments>
<arrayArg name="pluginClasspaths">
<args>$MAVEN_REPOSITORY$/org/jetbrains/compose/compiler/compiler-hosted/1.5.14/compiler-hosted-1.5.14.jar</args>
</arrayArg>
</arrayArguments>
</compilerArguments>
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="kotlin-stdlib" level="project" />
<orderEntry type="library" name="jetbrains-annotations" level="project" />
<orderEntry type="module" module-name="intellij.platform.core.ui" />
<orderEntry type="module" module-name="intellij.platform.ide.impl" />
<orderEntry type="library" exported="" name="jetbrains.compose.foundation.desktop" level="project" />
<orderEntry type="module" module-name="intellij.platform.compose.skikoRuntime" />
<orderEntry type="module-library" exported="">
<library name="jetbrains.jewel" type="repository">
<properties maven-id="org.jetbrains.jewel:jewel-ide-laf-bridge-241:0.19.7">
<verification>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/jewel/jewel-ide-laf-bridge-241/0.19.7/jewel-ide-laf-bridge-241-0.19.7.jar">
<sha256sum>4d036de01b2503385a0954a4b9227bc1aa05f74241ba1388bd49dae1ca8c9f4a</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/jewel/jewel-ui-241/0.19.7/jewel-ui-241-0.19.7.jar">
<sha256sum>82ca281594b47d75db6951c12e872e03859ee129c3c898986427b141efaf641a</sha256sum>
</artifact>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/jewel/jewel-foundation-241/0.19.7/jewel-foundation-241-0.19.7.jar">
<sha256sum>9ae37fc841c4bf540120583e4c469fe1f5359228ef304c8a2f7f83a5407c1150</sha256sum>
</artifact>
</verification>
<exclude>
<dependency maven-id="org.jetbrains.compose.foundation:foundation-desktop" />
</exclude>
</properties>
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/jewel/jewel-ide-laf-bridge-241/0.19.7/jewel-ide-laf-bridge-241-0.19.7.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/jewel/jewel-ui-241/0.19.7/jewel-ui-241-0.19.7.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/jewel/jewel-foundation-241/0.19.7/jewel-foundation-241-0.19.7.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/jewel/jewel-ide-laf-bridge-241/0.19.7/jewel-ide-laf-bridge-241-0.19.7-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/jewel/jewel-ui-241/0.19.7/jewel-ui-241-0.19.7-sources.jar!/" />
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/jewel/jewel-foundation-241/0.19.7/jewel-foundation-241-0.19.7-sources.jar!/" />
</SOURCES>
</library>
</orderEntry>
<orderEntry type="library" name="kotlinx-coroutines-core" level="project" />
</component>
</module>

View File

@@ -0,0 +1,12 @@
<idea-plugin>
<actions>
<action id="ComposeShowcaseAction" internal="true" class="com.intellij.platform.compose.showcase.ComposeShowcaseAction"
text="Compose Components Showcase"/>
</actions>
<extensions defaultExtensionNs="com.intellij">
<registryKey defaultValue="true"
description="Allows changing how ComposePanel is rendered using rendering on Graphics (when `true`, it provides smooth Swing interop) or on native AWT texture (when `false`). Works only in internal mode"
key="compose.swing.render.on.graphics"
/>
</extensions>
</idea-plugin>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module-library" scope="RUNTIME">
<library name="jetbrains.skiko.awt.runtime.all" type="repository">
<properties include-transitive-deps="false" maven-id="org.jetbrains.skiko:skiko-awt-runtime-all:0.8.9">
<verification>
<artifact url="file://$MAVEN_REPOSITORY$/org/jetbrains/skiko/skiko-awt-runtime-all/0.8.9/skiko-awt-runtime-all-0.8.9.jar">
<sha256sum>8d1825a1ab736c5eb8fe7b9d4966f82525f1f55dbb8c8a9750da96a7caceb430</sha256sum>
</artifact>
</verification>
</properties>
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/skiko/skiko-awt-runtime-all/0.8.9/skiko-awt-runtime-all-0.8.9.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/org/jetbrains/skiko/skiko-awt-runtime-all/0.8.9/skiko-awt-runtime-all-0.8.9-sources.jar!/" />
</SOURCES>
</library>
</orderEntry>
</component>
</module>

View File

@@ -0,0 +1,86 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.platform.compose
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInWindow
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.round
import com.intellij.ide.DataManager
import com.intellij.openapi.actionSystem.ActionGroup
import com.intellij.openapi.actionSystem.ActionManager
import com.intellij.openapi.actionSystem.ActionPlaces
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.ui.popup.JBPopup
import com.intellij.openapi.ui.popup.JBPopupFactory
import com.intellij.openapi.ui.popup.JBPopupListener
import com.intellij.openapi.ui.popup.LightweightWindowEvent
import org.jetbrains.annotations.ApiStatus.Experimental
import java.awt.Component
@Experimental
internal interface JBPopupPlacer {
fun showPopup(
anchorComponent: Component,
density: Density,
anchorBounds: IntRect,
popupToShow: JBPopup,
)
}
@Suppress("ForbiddenInSuspectContextMethod", "unused")
@Experimental
@Composable
internal fun ActionGroupPopup(
actionGroupId: String,
placer: JBPopupPlacer,
place: String = ActionPlaces.UNKNOWN,
dataContext: DataContext? = null,
onClose: (isOk: Boolean) -> Unit
) {
val component = LocalComponent.current
val density = LocalDensity.current
var layoutParentBoundsInWindow: IntRect? by remember { mutableStateOf(null) }
Layout(
content = {},
modifier = Modifier.onGloballyPositioned { childCoordinates ->
childCoordinates.parentCoordinates?.let {
val layoutPosition = it.positionInWindow().round()
val layoutSize = it.size
layoutParentBoundsInWindow = IntRect(layoutPosition, layoutSize)
}
},
measurePolicy = { _, _ ->
layout(0, 0) {}
}
)
LaunchedEffect(Unit) {
if (layoutParentBoundsInWindow == null) {
return@LaunchedEffect
}
val manager = ActionManager.getInstance()
val actionGroup = manager.getAction(actionGroupId) as ActionGroup
val popup = JBPopupFactory
.getInstance()
.createActionGroupPopup(
null, actionGroup, dataContext ?: DataManager.getInstance().getDataContext(component),
JBPopupFactory.ActionSelectionAid.SPEEDSEARCH,
true, {},
Int.MAX_VALUE,
null,
place
)
popup.addListener(object : JBPopupListener {
override fun onClosed(event: LightweightWindowEvent) {
onClose(event.isOk)
}
})
placer.showPopup(component, density, layoutParentBoundsInWindow!!, popup)
}
}

View File

@@ -0,0 +1,57 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.platform.compose
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.awt.ComposePanel
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.util.registry.Registry
import org.jetbrains.annotations.ApiStatus.Experimental
import org.jetbrains.jewel.bridge.actionSystem.ComponentDataProviderBridge
import org.jetbrains.jewel.bridge.theme.SwingBridgeTheme
import org.jetbrains.jewel.foundation.ExperimentalJewelApi
import org.jetbrains.skiko.ExperimentalSkikoApi
import org.jetbrains.skiko.GraphicsApi
import org.jetbrains.skiko.OS
import org.jetbrains.skiko.SkiaLayerAnalytics
import javax.swing.JComponent
@Suppress("FunctionName")
@OptIn(ExperimentalComposeUiApi::class, ExperimentalJewelApi::class)
@Experimental
internal fun JBComposePanel(
content: @Composable () -> Unit
): JComponent {
if (ApplicationManager.getApplication().isInternal) {
System.setProperty("compose.swing.render.on.graphics", Registry.stringValue("compose.swing.render.on.graphics"))
}
return ComposePanel(ComposeAnalytics()).apply {
setContent {
SwingBridgeTheme {
CompositionLocalProvider(LocalComponent provides this@apply) {
ComponentDataProviderBridge(this@apply) {
content()
}
}
}
}
}
}
@OptIn(ExperimentalSkikoApi::class)
private class ComposeAnalytics : SkiaLayerAnalytics {
override fun renderer(skikoVersion: String, os: OS, api: GraphicsApi): SkiaLayerAnalytics.RendererAnalytics {
return object : SkiaLayerAnalytics.RendererAnalytics {
override fun init() {
LOG.info("Compose panel is initialized with graphicsApi: $api")
}
}
}
companion object {
private val LOG = logger<ComposeAnalytics>()
}
}

View File

@@ -0,0 +1,11 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.platform.compose
import androidx.compose.runtime.staticCompositionLocalOf
import org.jetbrains.annotations.ApiStatus.Experimental
import javax.swing.JComponent
@Experimental
internal val LocalComponent = staticCompositionLocalOf<JComponent> {
error("CompositionLocal LocalComponent not provided")
}

View File

@@ -0,0 +1,348 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.platform.compose.showcase
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.onFocusEvent
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.key.*
import androidx.compose.ui.input.pointer.PointerIcon
import androidx.compose.ui.input.pointer.pointerHoverIcon
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.intellij.icons.AllIcons
import com.intellij.openapi.fileChooser.FileChooser
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
import com.intellij.openapi.keymap.KeymapUtil
import com.intellij.ui.UIBundle
import com.intellij.util.ui.JBUI
import kotlinx.coroutines.*
import kotlinx.coroutines.Dispatchers.IO
import org.jetbrains.jewel.bridge.toComposeColor
import org.jetbrains.jewel.foundation.modifier.onHover
import org.jetbrains.jewel.foundation.theme.JewelTheme
import org.jetbrains.jewel.foundation.theme.OverrideDarkMode
import org.jetbrains.jewel.ui.Orientation
import org.jetbrains.jewel.ui.Outline
import org.jetbrains.jewel.ui.component.*
import org.jetbrains.jewel.ui.theme.tooltipStyle
import org.jetbrains.jewel.ui.util.isDark
import java.awt.event.InputEvent
import java.awt.event.KeyEvent
import java.io.File
import javax.swing.KeyStroke
@Composable
internal fun ComposeShowcase() {
Column(
verticalArrangement = Arrangement.spacedBy(15.dp),
modifier = Modifier.padding(10.dp)
) {
Title()
Text("This is Compose bundled inside IntelliJ Platform!")
Row {
val scrollState = rememberScrollState()
Column(
verticalArrangement = Arrangement.spacedBy(15.dp),
modifier = Modifier.weight(1f).verticalScroll(scrollState)
) {
CheckBox()
RadioButton()
Buttons()
Label()
SelectableText()
Tabs()
LinkLabels()
TextFieldSimple()
TextFieldWithButton()
TooltipAreaSimple()
}
val adapter = rememberScrollbarAdapter(scrollState)
androidx.compose.foundation.VerticalScrollbar(adapter)
}
}
}
@Composable
private fun Title() {
Text("Showcase of Jewel components", fontSize = 15.sp)
Divider(orientation = Orientation.Horizontal, modifier = Modifier.fillMaxWidth())
}
@Composable
private fun CheckBox() {
var checkedState by remember { mutableStateOf(false) }
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(5.dp),
) {
Text("Checkbox:")
CheckboxRow(
"checkBox",
checkedState,
onCheckedChange = {
checkedState = it
}
)
}
}
@Composable
private fun RadioButton() {
var selectedRadioButton by remember { mutableStateOf(1) }
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(5.dp),
) {
Text("radioButton")
RadioButtonRow(
"Value 1",
selected = selectedRadioButton == 0,
onClick = {
selectedRadioButton = 0
}
)
RadioButtonRow(
"Value 2",
selected = selectedRadioButton == 1,
onClick = {
selectedRadioButton = 1
}
)
}
}
@Composable
private fun Label() {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(5.dp)
) {
Text("label:")
Text("Some label")
}
}
@Composable
private fun SelectableText() {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(5.dp)
) {
SelectionContainer {
Text("Selectable text")
}
}
}
@Composable
private fun Buttons() {
Row(
horizontalArrangement = Arrangement.spacedBy(20.dp),
verticalAlignment = Alignment.CenterVertically,
) {
var state1 by remember { mutableStateOf(0) }
OutlinedButton(onClick = {
state1++
}) {
Text("Click me #$state1")
}
var state2 by remember { mutableStateOf(0) }
DefaultButton(onClick = {
state2++
}) {
Text("Click me #$state2")
}
Row(verticalAlignment = Alignment.CenterVertically) {
var state3 by remember { mutableStateOf(0) }
var focused by remember { mutableStateOf(false) }
IconButton(
onClick = { state3++ },
modifier = Modifier
.size(18.dp)
.onFocusEvent { focused = it.isFocused }
.background(if (focused) JBUI.CurrentTheme.Focus.focusColor().toComposeColor() else Color.Unspecified, RoundedCornerShape(4.dp))
) {
Icon("expui/image/fitContent.svg", contentDescription = null, iconClass = AllIcons::class.java)
}
Text("← Click me #$state3")
}
}
}
@Composable
private fun Tabs() {
var selectedTabIndex by remember { mutableStateOf(0) }
val tabIds by remember { mutableStateOf((1..12).toList()) }
val tabs by derivedStateOf {
tabIds.mapIndexed { index, id ->
TabData.Default(
selected = index == selectedTabIndex,
content = {
Text("Tab $id")
},
closable = false,
onClick = { selectedTabIndex = index },
)
}
}
TabStrip(tabs)
}
@Composable
private fun LinkLabels() {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(5.dp),
) {
Text("Labels:")
Link("Link", onClick = {
// do nothing
})
}
}
@Composable
private fun TextFieldSimple() {
var textFieldState by remember { mutableStateOf("") }
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(5.dp),
) {
Text("Text field:")
TextField(
textFieldState,
onValueChange = {
textFieldState = it
},
modifier = Modifier.padding(5.dp)
)
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun TextFieldWithButton() {
var textFieldState by remember { mutableStateOf("") }
var fileExists by remember { mutableStateOf(true) }
LaunchedEffect(textFieldState) {
delay(300)
withContext(IO) {
fileExists = textFieldState.isEmpty() || File(textFieldState).exists()
}
}
fun chooseFile() {
val descriptor = FileChooserDescriptorFactory.createSingleFileOrFolderDescriptor()
descriptor.title = UIBundle.message("file.chooser.default.title")
FileChooser.chooseFile(descriptor, null, null) {
textFieldState = it.path
}
}
val openFileChooserHint = UIBundle.message("component.with.browse.button.browse.button.tooltip.text") + " (${
KeymapUtil.getKeystrokeText(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, InputEvent.SHIFT_DOWN_MASK))
})"
Row(
horizontalArrangement = Arrangement.spacedBy(5.dp),
verticalAlignment = Alignment.CenterVertically,
) {
Text("Choose file or folder:")
TextField(
value = textFieldState,
onValueChange = { textFieldState = it },
modifier = Modifier
.padding(5.dp)
.height(28.dp)
.onKeyEvent {
if (it.isShiftPressed && it.key == Key.Enter) true.also { chooseFile() } else false
},
outline = if (fileExists) Outline.None else Outline.Error,
placeholder = {
Text(
text = openFileChooserHint,
color = JBUI.CurrentTheme.ContextHelp.FOREGROUND.toComposeColor(),
fontSize = (JewelTheme.defaultTextStyle.fontSize.value - 2).sp,
)
},
trailingIcon = {
TooltipArea(
tooltip = { TooltipSimple { Text(openFileChooserHint, color = JewelTheme.tooltipStyle.colors.content) } }
) {
IconButton({ chooseFile() }, Modifier.size(18.dp).pointerHoverIcon(PointerIcon.Hand).focusProperties { canFocus = false }) {
AllIcons.General.OpenDisk
Icon("expui/inline/browse.svg", openFileChooserHint, iconClass = AllIcons::class.java)
}
}
},
)
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun TooltipAreaSimple() {
Row(verticalAlignment = Alignment.CenterVertically) {
Text("Hover with tooltip example:")
TooltipArea({ TooltipSimple { Text("Sample text") } }) {
var hovered by remember { mutableStateOf(false) }
val cornerSize = animateDpAsState(if (hovered) 28.dp else 4.dp)
Box(Modifier
.onHover { hovered = it }
.border(
width = 2.dp,
color = JBUI.CurrentTheme.Button.focusBorderColor(true).toComposeColor(),
shape = RoundedCornerShape(cornerSize.value),
)
) {
Text("Hovered: $hovered", Modifier.padding(horizontal = 12.dp, vertical = 6.dp))
}
}
}
}
@Composable
private fun TooltipSimple(modifier: Modifier = Modifier, content: @Composable () -> Unit) {
Box(
modifier = modifier
.shadow(
elevation = JewelTheme.tooltipStyle.metrics.shadowSize,
shape = RoundedCornerShape(JewelTheme.tooltipStyle.metrics.cornerSize),
ambientColor = JewelTheme.tooltipStyle.colors.shadow,
spotColor = Color.Transparent,
)
.background(
color = JewelTheme.tooltipStyle.colors.background,
shape = RoundedCornerShape(JewelTheme.tooltipStyle.metrics.cornerSize),
)
.border(
width = JewelTheme.tooltipStyle.metrics.borderWidth,
color = JewelTheme.tooltipStyle.colors.border,
shape = RoundedCornerShape(JewelTheme.tooltipStyle.metrics.cornerSize),
)
.padding(JewelTheme.tooltipStyle.metrics.contentPadding),
) {
OverrideDarkMode(JewelTheme.tooltipStyle.colors.background.isDark()) {
content()
}
}
}

View File

@@ -0,0 +1,40 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.platform.compose.showcase
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.project.DumbAwareAction
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.DialogWrapper
import com.intellij.openapi.util.NlsSafe
import com.intellij.platform.compose.JBComposePanel
import com.intellij.ui.PaintingParent.Wrapper
import java.awt.Dimension
import javax.swing.JComponent
private fun createComposeShowcaseComponent(): JComponent {
return JBComposePanel {
ComposeShowcase()
}
}
private class ComposeShowcaseAction : DumbAwareAction() {
override fun actionPerformed(e: AnActionEvent) {
ComposeShowcaseDialog(e.project, e.presentation.text).show()
}
}
private class ComposeShowcaseDialog(project: Project?, @NlsSafe dialogTitle: String) :
DialogWrapper(project, null, true, IdeModalityType.MODELESS, false) {
init {
title = dialogTitle
init()
}
override fun createCenterPanel(): JComponent {
return Wrapper(createComposeShowcaseComponent()).apply {
minimumSize = Dimension(200, 100)
preferredSize = Dimension(800, 600)
}
}
}

View File

@@ -0,0 +1,5 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
@ApiStatus.Internal
package com.intellij.platform.compose.showcase;
import org.jetbrains.annotations.ApiStatus;

View File

@@ -140,6 +140,10 @@
<xi:fallback/>
</xi:include>
<xi:include href="/META-INF/compose.xml">
<xi:fallback/>
</xi:include>
<xi:include href="/META-INF/ml.xml">
<xi:fallback/>
</xi:include>

View File

@@ -197,5 +197,7 @@ private fun getIdeSystemProperties(runDir: Path): Map<String, String> {
// require bundled JNA dispatcher lib
"jna.nosys" to "true",
"jna.noclasspath" to "true",
"skiko.library.path" to "$libDir/skiko-awt-runtime-all",
"compose.swing.render.on.graphics" to "true",
)
}