From 44f2d51158d34d402dce55b689d27ae1c7a40082 Mon Sep 17 00:00:00 2001 From: Ilya Ryzhenkov Date: Tue, 21 May 2024 12:21:45 +0400 Subject: [PATCH] Support tvOS (#719) --- .github/workflows/ci.yml | 25 +++++- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../SkiaMultiplatformSample/build.gradle.kts | 52 +++++++++-- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../plists/tvOS/Info.plist | 24 +++++ samples/SkiaMultiplatformSample/project.yml | 30 ++++++- .../org/jetbrains/skiko/sample/App.ios.kt | 0 .../org/jetbrains/skiko/sample/IosClocks.kt | 0 skiko/build.gradle.kts | 88 +++++++++++++++---- .../src/main/kotlin/SkikoProjectContext.kt | 21 ++++- skiko/buildSrc/src/main/kotlin/properties.kt | 21 ++--- .../configuration/CommonTasksConfiguration.kt | 10 ++- .../configuration/JvmTasksConfiguration.kt | 4 +- .../configuration/NativeTasksConfiguration.kt | 68 +++++++++----- skiko/ci/build.gradle.kts | 5 +- skiko/gradle.properties | 4 + .../kotlin/org/jetbrains/skiko/Actuals.awt.kt | 4 +- .../org/jetbrains/skiko/PlatformOperations.kt | 2 +- .../kotlin/org/jetbrains/skiko/OsArch.kt | 1 + .../org/jetbrains/skia/BreakIteratorTests.kt | 2 +- .../kotlin/org/jetbrains/skiko/Actuals.ios.kt | 26 ++---- .../kotlin/org/jetbrains/skiko/TextActions.kt | 23 ----- .../org/jetbrains/skiko/SkikoProperties.kt | 4 +- .../org/jetbrains/skiko/OsArch.native.kt | 1 + .../org/jetbrains/skiko/Actuals.tvos.kt | 17 ++++ .../org/jetbrains/skiko/Actuals.uikit.kt | 23 +++++ .../org/jetbrains/skiko/SkiaLayer.uikit.kt} | 0 .../kotlin/org/jetbrains/skiko/SkikoUIView.kt | 20 ++--- .../org/jetbrains/skiko/SystemTheme.uikit.kt} | 0 .../skiko/redrawer/MetalRedrawer.uikit.kt} | 0 31 files changed, 345 insertions(+), 136 deletions(-) create mode 100644 samples/SkiaMultiplatformSample/plists/tvOS/Info.plist rename samples/SkiaMultiplatformSample/src/{iosMain => uikitMain}/kotlin/org/jetbrains/skiko/sample/App.ios.kt (100%) rename samples/SkiaMultiplatformSample/src/{iosMain => uikitMain}/kotlin/org/jetbrains/skiko/sample/IosClocks.kt (100%) delete mode 100644 skiko/src/iosMain/kotlin/org/jetbrains/skiko/TextActions.kt create mode 100644 skiko/src/tvosMain/kotlin/org/jetbrains/skiko/Actuals.tvos.kt create mode 100644 skiko/src/uikitMain/kotlin/org/jetbrains/skiko/Actuals.uikit.kt rename skiko/src/{iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt => uikitMain/kotlin/org/jetbrains/skiko/SkiaLayer.uikit.kt} (100%) rename skiko/src/{iosMain => uikitMain}/kotlin/org/jetbrains/skiko/SkikoUIView.kt (84%) rename skiko/src/{iosMain/kotlin/org/jetbrains/skiko/SystemTheme.ios.kt => uikitMain/kotlin/org/jetbrains/skiko/SystemTheme.uikit.kt} (100%) rename skiko/src/{iosMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.ios.kt => uikitMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.uikit.kt} (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 323723828..877d78334 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,7 +46,7 @@ jobs: path: ./skiko/build/reports/tests retention-days: 5 - ios: + iOS: runs-on: macos-13 steps: - uses: actions/checkout@v3 @@ -99,6 +99,29 @@ jobs: path: ./skiko/build/reports/tests retention-days: 5 + tvOS: + # TVOS requires macos 13 + runs-on: macos-13 + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + - uses: actions/setup-java@v2 + with: + distribution: 'adopt' + java-version: '11' + - shell: bash + run: | + ./gradlew --stacktrace --info -Pskiko.native.enabled=true -Pskiko.test.onci=true :skiko:tvosX64Test + # tvosSimulatorArm64Test will build the binary but the tests will be skipped due to X64 host machine + ./gradlew --stacktrace --info -Pskiko.native.enabled=true -Pskiko.test.onci=true :skiko:tvosSimulatorArm64Test + - uses: actions/upload-artifact@v2 + if: always() + with: + name: test-reports-macos + path: ./skiko/build/reports/tests + retention-days: 5 + linux: runs-on: ubuntu-20.04 steps: diff --git a/samples/SkiaAwtSample/gradle/wrapper/gradle-wrapper.properties b/samples/SkiaAwtSample/gradle/wrapper/gradle-wrapper.properties index ffed3a254..ae04661ee 100644 --- a/samples/SkiaAwtSample/gradle/wrapper/gradle-wrapper.properties +++ b/samples/SkiaAwtSample/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/samples/SkiaJsSample/gradle/wrapper/gradle-wrapper.properties b/samples/SkiaJsSample/gradle/wrapper/gradle-wrapper.properties index ffed3a254..ae04661ee 100644 --- a/samples/SkiaJsSample/gradle/wrapper/gradle-wrapper.properties +++ b/samples/SkiaJsSample/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/samples/SkiaMultiplatformSample/build.gradle.kts b/samples/SkiaMultiplatformSample/build.gradle.kts index d62297bd2..2da3ca302 100644 --- a/samples/SkiaMultiplatformSample/build.gradle.kts +++ b/samples/SkiaMultiplatformSample/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget +import org.jetbrains.kotlin.gradle.plugin.mpp.* buildscript { repositories { @@ -82,11 +82,19 @@ kotlin { macosArm64() { configureToLaunchFromXcode() } - ios() { + iosSimulatorArm64() { configureToLaunchFromAppCode() configureToLaunchFromXcode() } - iosSimulatorArm64() { + tvosX64() { + configureToLaunchFromAppCode() + configureToLaunchFromXcode() + } + tvosArm64() { + configureToLaunchFromAppCode() + configureToLaunchFromXcode() + } + tvosSimulatorArm64() { configureToLaunchFromAppCode() configureToLaunchFromXcode() } @@ -165,12 +173,27 @@ kotlin { val macosArm64Main by getting { dependsOn(macosMain) } - val iosMain by getting { + val uikitMain by creating { dependsOn(darwinMain) } + val iosMain by creating { + dependsOn(uikitMain) + } val iosSimulatorArm64Main by getting { dependsOn(iosMain) } + val tvosMain by creating { + dependsOn(uikitMain) + } + val tvosX64Main by getting { + dependsOn(tvosMain) + } + val tvosArm64Main by getting { + dependsOn(tvosMain) + } + val tvosSimulatorArm64Main by getting { + dependsOn(tvosMain) + } } } } @@ -213,7 +236,7 @@ if (hostOs == "macos") { } project.tasks.register("runAwt") { - val kotlinTask = project.tasks.named("compileKotlinAwt") + val kotlinTask = project.tasks.named("compileKotlinAwt") dependsOn(kotlinTask) systemProperty("skiko.fps.enabled", "true") systemProperty("skiko.linux.autodpi", "true") @@ -237,8 +260,14 @@ tasks.withType().configureEach } enum class Target(val simulator: Boolean, val key: String) { - WATCHOS_X86(true, "watchos"), WATCHOS_ARM64(false, "watchos"), - IOS_X64(true, "iosX64"), IOS_ARM64(false, "iosArm64"), IOS_SIMULATOR_ARM64(true, "iosSimulatorArm64") + WATCHOS_X86(true, "watchos"), + WATCHOS_ARM64(false, "watchos"), + IOS_X64(true, "iosX64"), + IOS_ARM64(false, "iosArm64"), + IOS_SIMULATOR_ARM64(true, "iosSimulatorArm64"), + TVOS_X64(true, "tvosX64"), + TVOS_ARM64(true, "tvosArm64"), + TVOS_SIMULATOR_ARM64(true, "tvosSimulatorArm64"), } @@ -246,9 +275,16 @@ if (hostOs == "macos") { // Create Xcode integration tasks. val sdkName: String? = System.getenv("SDK_NAME") + println("Configuring XCode for $sdkName") val target = sdkName.orEmpty().let { when { it.startsWith("iphoneos") -> Target.IOS_ARM64 + it.startsWith("appletvsimulator") -> when (host) { + "macos-x64" -> Target.TVOS_X64 + "macos-arm64" -> Target.TVOS_SIMULATOR_ARM64 + else -> throw GradleException("Host OS is not supported") + } + it.startsWith("appletvos") -> Target.TVOS_ARM64 it.startsWith("watchos") -> Target.WATCHOS_ARM64 it.startsWith("watchsimulator") -> Target.WATCHOS_X86 else -> when (host) { @@ -279,6 +315,8 @@ if (hostOs == "macos") { // Otherwise copy the executable into the Xcode output directory. tasks.create("packForXCode", Copy::class.java) { dependsOn(kotlinBinary.linkTask) + + println("Packing for XCode: ${kotlinBinary.target}") destinationDir = file(targetBuildDir) diff --git a/samples/SkiaMultiplatformSample/gradle/wrapper/gradle-wrapper.properties b/samples/SkiaMultiplatformSample/gradle/wrapper/gradle-wrapper.properties index ffed3a254..ae04661ee 100644 --- a/samples/SkiaMultiplatformSample/gradle/wrapper/gradle-wrapper.properties +++ b/samples/SkiaMultiplatformSample/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/samples/SkiaMultiplatformSample/plists/tvOS/Info.plist b/samples/SkiaMultiplatformSample/plists/tvOS/Info.plist new file mode 100644 index 000000000..96c5411cf --- /dev/null +++ b/samples/SkiaMultiplatformSample/plists/tvOS/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + UILaunchStoryboardName + + + diff --git a/samples/SkiaMultiplatformSample/project.yml b/samples/SkiaMultiplatformSample/project.yml index 100923c45..81593516e 100644 --- a/samples/SkiaMultiplatformSample/project.yml +++ b/samples/SkiaMultiplatformSample/project.yml @@ -1,15 +1,15 @@ -name: SkikoSample +name: Skiko Sample options: bundleIdPrefix: org.jetbrains settings: DEVELOPMENT_TEAM: N462MKSJ7M - CODE_SIGN_IDENTITY: "iPhone Developer" + CODE_SIGN_IDENTITY: "Apple Development" CODE_SIGN_STYLE: Automatic MARKETING_VERSION: "1.0" CURRENT_PROJECT_VERSION: "4" SDKROOT: iphoneos targets: - SkikoSample: + Skiko Sample iOS: type: application platform: iOS deploymentTarget: "12.0" @@ -32,3 +32,27 @@ targets: ENABLE_BITCODE: "YES" ONLY_ACTIVE_ARCH: "NO" VALID_ARCHS: "arm64" + Skiko Sample tvOS: + type: application + platform: tvOS + deploymentTarget: "14.0" + prebuildScripts: + - script: cd "$SRCROOT" && ./gradlew -p . packForXCode + name: GradleCompile + info: + path: plists/tvOS/Info.plist + properties: + UILaunchStoryboardName: "" + sources: + - path: "src/" + excludes: + - "android*/**" + - "awt*/**" + - "iosApp*/**" + - "js*/**" + settings: + LIBRARY_SEARCH_PATHS: "$(inherited)" + ENABLE_BITCODE: "YES" + ONLY_ACTIVE_ARCH: "NO" + VALID_ARCHS: "arm64" + diff --git a/samples/SkiaMultiplatformSample/src/iosMain/kotlin/org/jetbrains/skiko/sample/App.ios.kt b/samples/SkiaMultiplatformSample/src/uikitMain/kotlin/org/jetbrains/skiko/sample/App.ios.kt similarity index 100% rename from samples/SkiaMultiplatformSample/src/iosMain/kotlin/org/jetbrains/skiko/sample/App.ios.kt rename to samples/SkiaMultiplatformSample/src/uikitMain/kotlin/org/jetbrains/skiko/sample/App.ios.kt diff --git a/samples/SkiaMultiplatformSample/src/iosMain/kotlin/org/jetbrains/skiko/sample/IosClocks.kt b/samples/SkiaMultiplatformSample/src/uikitMain/kotlin/org/jetbrains/skiko/sample/IosClocks.kt similarity index 100% rename from samples/SkiaMultiplatformSample/src/iosMain/kotlin/org/jetbrains/skiko/sample/IosClocks.kt rename to samples/SkiaMultiplatformSample/src/uikitMain/kotlin/org/jetbrains/skiko/sample/IosClocks.kt diff --git a/skiko/build.gradle.kts b/skiko/build.gradle.kts index 3506d0b52..12da2264a 100644 --- a/skiko/build.gradle.kts +++ b/skiko/build.gradle.kts @@ -140,6 +140,15 @@ kotlin { if (supportNativeIosX64) { skikoProjectContext.configureNativeTarget(OS.IOS, Arch.X64, iosX64()) } + if (supportNativeTvosArm64) { + skikoProjectContext.configureNativeTarget(OS.TVOS, Arch.Arm64, tvosArm64()) + } + if (supportNativeTvosSimulatorArm64) { + skikoProjectContext.configureNativeTarget(OS.TVOS, Arch.Arm64, tvosSimulatorArm64()) + } + if (supportNativeTvosX64) { + skikoProjectContext.configureNativeTarget(OS.TVOS, Arch.X64, tvosX64()) + } sourceSets { val commonMain by getting { @@ -299,35 +308,76 @@ kotlin { dependsOn(macosTest) } } - if (supportAnyNativeIos) { - val iosMain by creating { + if (supportAnyNativeIos || supportAllNativeTvos) { + val uikitMain by creating { dependsOn(darwinMain) } - val iosTest by creating { + val uikitTest by creating { dependsOn(darwinTest) } - if (supportNativeIosArm64) { - val iosArm64Main by getting { - dependsOn(iosMain) + + if (supportAnyNativeIos) { + val iosMain by creating { + dependsOn(uikitMain) } - val iosArm64Test by getting { - dependsOn(iosTest) + val iosTest by creating { + dependsOn(uikitTest) } - } - if (supportNativeIosSimulatorArm64) { - val iosSimulatorArm64Main by getting { - dependsOn(iosMain) + if (supportNativeIosArm64) { + val iosArm64Main by getting { + dependsOn(iosMain) + } + val iosArm64Test by getting { + dependsOn(iosTest) + } } - val iosSimulatorArm64Test by getting { - dependsOn(iosTest) + if (supportNativeIosSimulatorArm64) { + val iosSimulatorArm64Main by getting { + dependsOn(iosMain) + } + val iosSimulatorArm64Test by getting { + dependsOn(iosTest) + } + } + if (supportNativeIosX64) { + val iosX64Main by getting { + dependsOn(iosMain) + } + val iosX64Test by getting { + dependsOn(iosTest) + } } } - if (supportNativeIosX64) { - val iosX64Main by getting { - dependsOn(iosMain) + if (supportAnyNativeTvos) { + val tvosMain by creating { + dependsOn(uikitMain) + } + val tvosTest by creating { + dependsOn(uikitTest) + } + if (supportNativeTvosArm64) { + val tvosArm64Main by getting { + dependsOn(tvosMain) + } + val tvosArm64Test by getting { + dependsOn(tvosTest) + } + } + if (supportNativeTvosSimulatorArm64) { + val tvosSimulatorArm64Main by getting { + dependsOn(tvosMain) + } + val tvosSimulatorArm64Test by getting { + dependsOn(tvosTest) + } } - val iosX64Test by getting { - dependsOn(iosTest) + if (supportNativeTvosX64) { + val tvosX64Main by getting { + dependsOn(tvosMain) + } + val tvosX64Test by getting { + dependsOn(tvosTest) + } } } } diff --git a/skiko/buildSrc/src/main/kotlin/SkikoProjectContext.kt b/skiko/buildSrc/src/main/kotlin/SkikoProjectContext.kt index 651f6abd4..3415a4a79 100644 --- a/skiko/buildSrc/src/main/kotlin/SkikoProjectContext.kt +++ b/skiko/buildSrc/src/main/kotlin/SkikoProjectContext.kt @@ -30,10 +30,10 @@ class SkikoProjectContext( * (tasks' registration during other task's registration is prohibited) */ fun SkikoProjectContext.registerOrGetSkiaDirProvider( - os: OS, arch: Arch, isIosSim: Boolean = false + os: OS, arch: Arch, isUikitSim: Boolean = false ): Provider = with(this.project) { - val taskNameSuffix = joinToTitleCamelCase(buildType.id, os.idWithSuffix(isIosSim = isIosSim), arch.id) - val skiaRelease = skiko.skiaReleaseFor(os, arch, buildType, isIosSim) + val taskNameSuffix = joinToTitleCamelCase(buildType.id, os.idWithSuffix(isUikitSim = isUikitSim), arch.id) + val skiaRelease = skiko.skiaReleaseFor(os, arch, buildType, isUikitSim) val downloadSkia = tasks.registerOrGetTask("downloadSkia$taskNameSuffix") { onlyIf { !dest.exists() } onlyIfModified(true) @@ -89,6 +89,21 @@ val Project.supportNativeIosX64: Boolean val Project.supportAnyNativeIos: Boolean get() = supportAllNativeIos || supportNativeIosArm64 || supportNativeIosSimulatorArm64 || supportNativeIosX64 +val Project.supportAllNativeTvos: Boolean + get() = supportAllNative || findProperty("skiko.native.tvos.enabled") == "true" || isInIdea + +val Project.supportNativeTvosArm64: Boolean + get() = supportAllNativeTvos || findProperty("skiko.native.tvos.arm64.enabled") == "true" || isInIdea + +val Project.supportNativeTvosSimulatorArm64: Boolean + get() = supportAllNativeTvos || findProperty("skiko.native.tvos.simulatorArm64.enabled") == "true" || isInIdea + +val Project.supportNativeTvosX64: Boolean + get() = supportAllNativeTvos || findProperty("skiko.native.tvos.x64.enabled") == "true" || isInIdea + +val Project.supportAnyNativeTvos: Boolean + get() = supportAllNativeTvos || supportNativeTvosArm64 || supportNativeTvosSimulatorArm64 || supportNativeTvosX64 + val Project.supportNativeMac: Boolean get() = supportAllNative || findProperty("skiko.native.mac.enabled") == "true" || isInIdea diff --git a/skiko/buildSrc/src/main/kotlin/properties.kt b/skiko/buildSrc/src/main/kotlin/properties.kt index 5f62da04a..9a2f5eca8 100644 --- a/skiko/buildSrc/src/main/kotlin/properties.kt +++ b/skiko/buildSrc/src/main/kotlin/properties.kt @@ -10,7 +10,8 @@ enum class OS( Windows("windows", arrayOf()), MacOS("macos", arrayOf("-mmacosx-version-min=10.13")), Wasm("wasm", arrayOf()), - IOS("ios", arrayOf()) + IOS("ios", arrayOf()), + TVOS("tvos", arrayOf()) ; val isWindows @@ -19,8 +20,8 @@ enum class OS( val isMacOs get() = this == MacOS - fun idWithSuffix(isIosSim: Boolean = false): String { - return id + if (isIosSim) "Sim" else "" + fun idWithSuffix(isUikitSim: Boolean = false): String { + return id + if (isUikitSim) "Sim" else "" } } @@ -28,7 +29,7 @@ val OS.isCompatibleWithHost: Boolean get() = when (this) { OS.Linux -> hostOs == OS.Linux OS.Windows -> hostOs == OS.Windows - OS.MacOS, OS.IOS -> hostOs == OS.MacOS + OS.MacOS, OS.IOS, OS.TVOS -> hostOs == OS.MacOS OS.Wasm -> true OS.Android -> true } @@ -42,7 +43,7 @@ fun compilerForTarget(os: OS, arch: Arch): String = } OS.Android -> "clang++" OS.Windows -> "cl.exe" - OS.MacOS, OS.IOS -> "clang++" + OS.MacOS, OS.IOS, OS.TVOS -> "clang++" OS.Wasm -> "emcc" } @@ -53,7 +54,7 @@ val OS.dynamicLibExt: String get() = when (this) { OS.Linux, OS.Android -> ".so" OS.Windows -> ".dll" - OS.MacOS, OS.IOS -> ".dylib" + OS.MacOS, OS.IOS, OS.TVOS -> ".dylib" OS.Wasm -> ".wasm" } @@ -141,9 +142,9 @@ class SkikoProperties(private val myProject: Project) { get() = !isRelease fun skiaReleaseFor(os: OS, arch: Arch, buildType: SkiaBuildType, isIosSim: Boolean = false): String { - val target = "${os.idWithSuffix(isIosSim = isIosSim)}-${arch.id}" + val target = "${os.idWithSuffix(isUikitSim = isIosSim)}-${arch.id}" val tag = myProject.property("dependencies.skia.$target") as String - return "${tag}/Skia-${tag}-${os.idWithSuffix(isIosSim = isIosSim)}-${buildType.id}-${arch.id}" + return "${tag}/Skia-${tag}-${os.idWithSuffix(isUikitSim = isIosSim)}-${buildType.id}-${arch.id}" } val releaseGithubVersion: String @@ -208,6 +209,6 @@ object SkikoArtifacts { // does not seem possible (at least without adding a dash to a target's tasks), // so we're using the default naming pattern instead. // See https://youtrack.jetbrains.com/issue/KT-50001. - fun nativeArtifactIdFor(os: OS, arch: Arch, isIosSim: Boolean = false) = - "skiko-${os.id + if (isIosSim) "simulator" else ""}${arch.id}" + fun nativeArtifactIdFor(os: OS, arch: Arch, isUikitSim: Boolean = false) = + "skiko-${os.id + if (isUikitSim) "simulator" else ""}${arch.id}" } diff --git a/skiko/buildSrc/src/main/kotlin/tasks/configuration/CommonTasksConfiguration.kt b/skiko/buildSrc/src/main/kotlin/tasks/configuration/CommonTasksConfiguration.kt index 6bfd8a1d4..8f23031a6 100644 --- a/skiko/buildSrc/src/main/kotlin/tasks/configuration/CommonTasksConfiguration.kt +++ b/skiko/buildSrc/src/main/kotlin/tasks/configuration/CommonTasksConfiguration.kt @@ -75,6 +75,12 @@ fun skiaPreprocessorFlags(os: OS, buildType: SkiaBuildType): Array { "-DSK_SHAPER_CORETEXT_AVAILABLE", "-DSK_METAL" ) + OS.TVOS -> listOf( + "-DSK_BUILD_FOR_IOS", + "-DSK_BUILD_FOR_TVOS", + "-DSK_SHAPER_CORETEXT_AVAILABLE", + "-DSK_METAL" + ) OS.Windows -> listOf( "-DSK_BUILD_FOR_WIN", "-D_CRT_SECURE_NO_WARNINGS", @@ -155,10 +161,10 @@ fun KotlinTarget.generateVersion( skikoProperties: SkikoProperties ) { val targetName = this.name - val isArm64Simulator = isIosSimArm64() + val isUikitSim = isUikitSimulator() val generatedDir = project.layout.buildDirectory.dir("generated/$targetName") val generateVersionTask = project.registerSkikoTask( - "generateVersion${toTitleCase(platformType.name)}".withSuffix(isIosSim = isArm64Simulator), + "generateVersion${toTitleCase(platformType.name)}".withSuffix(isUikitSim = isUikitSim), targetOs, targetArch ) { diff --git a/skiko/buildSrc/src/main/kotlin/tasks/configuration/JvmTasksConfiguration.kt b/skiko/buildSrc/src/main/kotlin/tasks/configuration/JvmTasksConfiguration.kt index 998089d09..6cb0f7bbd 100644 --- a/skiko/buildSrc/src/main/kotlin/tasks/configuration/JvmTasksConfiguration.kt +++ b/skiko/buildSrc/src/main/kotlin/tasks/configuration/JvmTasksConfiguration.kt @@ -119,7 +119,7 @@ fun SkikoProjectContext.createCompileJvmBindingsTask( "-fPIC" ) } - OS.Wasm, OS.IOS -> error("Should not reach here") + OS.Wasm, OS.IOS, OS.TVOS -> error("Should not reach here") } flags.set( @@ -322,7 +322,7 @@ fun SkikoProjectContext.createLinkJvmBindings( ) linker.set(project.androidClangFor(targetArch)) } - OS.Wasm, OS.IOS -> { + OS.Wasm, OS.IOS, OS.TVOS -> { throw GradleException("This task shalln't be used with $targetOs") } } diff --git a/skiko/buildSrc/src/main/kotlin/tasks/configuration/NativeTasksConfiguration.kt b/skiko/buildSrc/src/main/kotlin/tasks/configuration/NativeTasksConfiguration.kt index 243accc2d..574e8df19 100644 --- a/skiko/buildSrc/src/main/kotlin/tasks/configuration/NativeTasksConfiguration.kt +++ b/skiko/buildSrc/src/main/kotlin/tasks/configuration/NativeTasksConfiguration.kt @@ -5,43 +5,38 @@ import CompileSkikoCppTask import OS import SkiaBuildType import SkikoProjectContext -import SkikoProperties import WriteCInteropDefFile import compilerForTarget import isCompatibleWithHost import joinToTitleCamelCase import listOfFrameworks import mutableListOfLinkerOptions -import org.gradle.api.DefaultTask import org.gradle.api.GradleException import org.gradle.api.Project import org.gradle.api.tasks.Exec import org.gradle.api.tasks.TaskProvider -import org.gradle.kotlin.dsl.get import org.gradle.kotlin.dsl.getByName import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.KotlinTarget import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget import org.jetbrains.kotlin.gradle.tasks.CInteropProcess -import org.jetbrains.kotlin.gradle.tasks.KotlinCompileTool import projectDirs import registerOrGetSkiaDirProvider import registerSkikoTask -import toTitleCase import java.io.File -fun String.withSuffix(isIosSim: Boolean = false) = - this + if (isIosSim) "Sim" else "" +fun String.withSuffix(isUikitSim: Boolean = false) = + this + if (isUikitSim) "Sim" else "" -fun KotlinTarget.isIosSimArm64() = - name.contains("iosSimulatorArm64", ignoreCase = true) +fun KotlinTarget.isUikitSimulator() = + name.contains("Simulator", ignoreCase = true) || name == "tvosX64" // x64 tvOS is implicitly a simulator fun SkikoProjectContext.compileNativeBridgesTask( - os: OS, arch: Arch, isArm64Simulator: Boolean + os: OS, arch: Arch, isUikitSim: Boolean ): TaskProvider = with (this.project) { - val skiaNativeDir = registerOrGetSkiaDirProvider(os, arch, isIosSim = isArm64Simulator) + val skiaNativeDir = registerOrGetSkiaDirProvider(os, arch, isUikitSim = isUikitSim) - val actionName = "compileNativeBridges".withSuffix(isIosSim = isArm64Simulator) + val actionName = "compileNativeBridges".withSuffix(isUikitSim = isUikitSim) return project.registerSkikoTask(actionName, os, arch) { dependsOn(skiaNativeDir) @@ -49,7 +44,7 @@ fun SkikoProjectContext.compileNativeBridgesTask( compiler.set(compilerForTarget(os, arch)) buildTargetOS.set(os) - if (isArm64Simulator) { + if (isUikitSim) { buildSuffix.set("sim") } buildTargetArch.set(arch) @@ -62,8 +57,8 @@ fun SkikoProjectContext.compileNativeBridgesTask( val iphoneSimSdk = "$sdkRoot/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk" val iosArchFlags = when (arch) { Arch.Arm64 -> arrayOf( - "-target", if (isArm64Simulator) "arm64-apple-ios-simulator" else "arm64-apple-ios", - "-isysroot", if (isArm64Simulator) iphoneSimSdk else iphoneOsSdk, + "-target", if (isUikitSim) "arm64-apple-ios-simulator" else "arm64-apple-ios", + "-isysroot", if (isUikitSim) iphoneSimSdk else iphoneOsSdk, "-miphoneos-version-min=12.0" ) Arch.X64 -> arrayOf( @@ -80,6 +75,30 @@ fun SkikoProjectContext.compileNativeBridgesTask( *skiaPreprocessorFlags(OS.IOS, buildType), )) } + OS.TVOS -> { + val sdkRoot = "/Applications/Xcode.app/Contents/Developer/Platforms" + val tvOsSdk = "$sdkRoot/AppleTVOS.platform/Developer/SDKs/AppleTVOS.sdk" + val tvSimSdk = "$sdkRoot/AppleTVSimulator.platform/Developer/SDKs/AppleTVSimulator.sdk" + val tvosArchFlags = when (arch) { + Arch.Arm64 -> arrayOf( + "-target", if (isUikitSim) "arm64-apple-tvos-simulator" else "arm64-apple-tvos", + if (isUikitSim) "-mappletvsimulator-version-min=12.0" else "-mappletvos-version-min=12.0" , + "-isysroot", if (isUikitSim) tvSimSdk else tvOsSdk, + ) + Arch.X64 -> arrayOf( + "-target", "x86_64-apple-tvos-simulator", + "-mappletvsimulator-version-min=12.0", + "-isysroot", tvSimSdk + ) + else -> throw GradleException("Unsupported arch: $arch") + } + flags.set(listOf( + *tvosArchFlags, + *buildType.clangFlags, + "-stdlib=libc++", + *skiaPreprocessorFlags(OS.TVOS, buildType), + )) + } OS.MacOS -> { flags.set(listOf( *buildType.clangFlags, @@ -120,7 +139,7 @@ fun configureCinterop( linkerOpts: List, ) { val tasks = target.project.tasks - val taskNameSuffix = joinToTitleCamelCase(os.idWithSuffix(isIosSim = target.isIosSimArm64()), arch.id) + val taskNameSuffix = joinToTitleCamelCase(os.idWithSuffix(isUikitSim = target.isUikitSimulator()), arch.id) val writeCInteropDef = tasks.register("writeCInteropDef$taskNameSuffix", WriteCInteropDefFile::class.java) { this.linkerOpts.set(linkerOpts) outputFile.set(project.layout.buildDirectory.file("cinterop/$targetString/skiko.def")) @@ -167,11 +186,11 @@ fun SkikoProjectContext.configureNativeTarget(os: OS, arch: Arch, target: Kotlin if (!os.isCompatibleWithHost) return target.generateVersion(os, arch, skiko) - val isArm64Simulator = target.isIosSimArm64() + val isUikitSim = target.isUikitSimulator() - val targetString = "${os.idWithSuffix(isIosSim = isArm64Simulator)}-${arch.id}" + val targetString = "${os.idWithSuffix(isUikitSim = isUikitSim)}-${arch.id}" - val unzipper = registerOrGetSkiaDirProvider(os, arch, isArm64Simulator) + val unzipper = registerOrGetSkiaDirProvider(os, arch, isUikitSim) val unpackedSkia = unzipper.get() val skiaDir = unpackedSkia.absolutePath @@ -194,6 +213,11 @@ fun SkikoProjectContext.configureNativeTarget(os: OS, arch: Arch, target: Kotlin configureCinterop("uikit", os, arch, target, targetString, iosFrameworks) mutableListOfLinkerOptions(iosFrameworks) } + OS.TVOS -> { + val tvosFrameworks = listOfFrameworks("Metal", "CoreGraphics", "CoreText", "UIKit") + configureCinterop("uikit", os, arch, target, targetString, tvosFrameworks) + mutableListOfLinkerOptions(tvosFrameworks) + } OS.Linux -> mutableListOfLinkerOptions( "-L/usr/lib/x86_64-linux-gnu", "-lfontconfig", @@ -226,10 +250,10 @@ fun SkikoProjectContext.configureNativeTarget(os: OS, arch: Arch, target: Kotlin } } - val crossCompileTask = compileNativeBridgesTask(os, arch, isArm64Simulator = isArm64Simulator) + val crossCompileTask = compileNativeBridgesTask(os, arch, isUikitSim = isUikitSim) // TODO: move to LinkSkikoTask. - val actionName = "linkNativeBridges".withSuffix(isIosSim = isArm64Simulator) + val actionName = "linkNativeBridges".withSuffix(isUikitSim = isUikitSim) val linkTask = project.registerSkikoTask(actionName, os, arch) { dependsOn(crossCompileTask) val objectFilesDir = crossCompileTask.map { it.outDir.get() } @@ -245,7 +269,7 @@ fun SkikoProjectContext.configureNativeTarget(os: OS, arch: Arch, target: Kotlin executable = "ar" argumentProviders.add { listOf("-crs", staticLib) } } - OS.MacOS, OS.IOS -> { + OS.MacOS, OS.IOS, OS.TVOS -> { executable = "libtool" argumentProviders.add { listOf("-static", "-o", staticLib) } } diff --git a/skiko/ci/build.gradle.kts b/skiko/ci/build.gradle.kts index cd7510ec9..72c2e02c1 100644 --- a/skiko/ci/build.gradle.kts +++ b/skiko/ci/build.gradle.kts @@ -23,7 +23,10 @@ val skikoArtifactIds: List = SkikoArtifacts.nativeArtifactIdFor(OS.MacOS, Arch.X64), SkikoArtifacts.nativeArtifactIdFor(OS.IOS, Arch.X64), SkikoArtifacts.nativeArtifactIdFor(OS.IOS, Arch.Arm64), - SkikoArtifacts.nativeArtifactIdFor(OS.IOS, Arch.Arm64, isIosSim = true), + SkikoArtifacts.nativeArtifactIdFor(OS.IOS, Arch.Arm64, isUikitSim = true), + SkikoArtifacts.nativeArtifactIdFor(OS.TVOS, Arch.X64), + SkikoArtifacts.nativeArtifactIdFor(OS.TVOS, Arch.Arm64), + SkikoArtifacts.nativeArtifactIdFor(OS.TVOS, Arch.Arm64, isUikitSim = true), ) val downloadSkikoArtifactsFromComposeDev by tasks.registering(DownloadFromSpaceMavenRepoTask::class) { diff --git a/skiko/gradle.properties b/skiko/gradle.properties index ba5d35bcb..89324cf30 100644 --- a/skiko/gradle.properties +++ b/skiko/gradle.properties @@ -14,6 +14,10 @@ dependencies.skia.iosSim-arm64=m116-47d3027-1 dependencies.skia.iosSim-x64=m116-47d3027-1 dependencies.skia.android-x64=m116-47d3027-1 dependencies.skia.android-arm64=m116-47d3027-1 +dependencies.skia.tvos-x64=m116-47d3027-1 +dependencies.skia.tvos-arm64=m116-47d3027-1 +dependencies.skia.tvosSim-arm64=m116-47d3027-1 +dependencies.skia.tvosSim-x64=m116-47d3027-1 org.gradle.jvmargs=-Xmx3G -XX:MaxMetaspaceSize=512m diff --git a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/Actuals.awt.kt b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/Actuals.awt.kt index 5269440a9..c50307876 100644 --- a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/Actuals.awt.kt +++ b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/Actuals.awt.kt @@ -38,7 +38,7 @@ internal actual fun makeDefaultRenderFactory(): RenderFactory = GraphicsApi.SOFTWARE_FAST -> LinuxSoftwareRedrawer(layer, analytics, properties) else -> LinuxOpenGLRedrawer(layer, analytics, properties) } - OS.Android, OS.JS, OS.Ios, OS.Unknown -> throw UnsupportedOperationException("The AWT target doesn't support $hostOs") + OS.Android, OS.JS, OS.Ios, OS.Tvos, OS.Unknown -> throw UnsupportedOperationException("The awt target doesn't support $hostOs") } } @@ -51,7 +51,7 @@ internal actual fun URIHandler_openUri(uri: String) { URI(uri) // Validate URI for exception behavior consistent with the Desktop.browse() case (throwing URISyntaxException) Runtime.getRuntime().exec(arrayOf("xdg-open", URL(uri).toString())) } - OS.Android, OS.Windows, OS.MacOS, OS.Ios, OS.JS, OS.Unknown -> { + OS.Android, OS.Windows, OS.MacOS, OS.Ios, OS.Tvos, OS.JS, OS.Unknown -> { throw UnsupportedOperationException("AWT does not support the BROWSE action on this platform") } } diff --git a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/PlatformOperations.kt b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/PlatformOperations.kt index 64775e17f..209d250e8 100644 --- a/skiko/src/awtMain/kotlin/org/jetbrains/skiko/PlatformOperations.kt +++ b/skiko/src/awtMain/kotlin/org/jetbrains/skiko/PlatformOperations.kt @@ -125,7 +125,7 @@ internal val platformOperations: PlatformOperations by lazy { } } OS.Android -> TODO() - OS.JS, OS.Ios, OS.Unknown -> { + OS.JS, OS.Ios, OS.Tvos, OS.Unknown -> { TODO("Commonize me") } } diff --git a/skiko/src/commonMain/kotlin/org/jetbrains/skiko/OsArch.kt b/skiko/src/commonMain/kotlin/org/jetbrains/skiko/OsArch.kt index 128b69ee3..7ff3af68a 100644 --- a/skiko/src/commonMain/kotlin/org/jetbrains/skiko/OsArch.kt +++ b/skiko/src/commonMain/kotlin/org/jetbrains/skiko/OsArch.kt @@ -6,6 +6,7 @@ enum class OS(val id: String) { Windows("windows"), MacOS("macos"), Ios("ios"), + Tvos("tvos"), @Deprecated("JS is invalid host OS name. Consider using enum KotlinBackend to detect JS.") JS("js"), diff --git a/skiko/src/commonTest/kotlin/org/jetbrains/skia/BreakIteratorTests.kt b/skiko/src/commonTest/kotlin/org/jetbrains/skia/BreakIteratorTests.kt index 49de77d6a..1e2194723 100644 --- a/skiko/src/commonTest/kotlin/org/jetbrains/skia/BreakIteratorTests.kt +++ b/skiko/src/commonTest/kotlin/org/jetbrains/skia/BreakIteratorTests.kt @@ -17,7 +17,7 @@ class BreakIteratorTests { fun breakIteratorWordInstanceTest() { // Wasm and iOS builds of Skia do not include required data to implement those iterators, // see `third_party/externals/icu/flutter/README.md`. - if (hostOs == OS.Ios) + if (hostOs == OS.Ios || hostOs == OS.Tvos) return val boundary = BreakIterator.makeWordInstance() diff --git a/skiko/src/iosMain/kotlin/org/jetbrains/skiko/Actuals.ios.kt b/skiko/src/iosMain/kotlin/org/jetbrains/skiko/Actuals.ios.kt index a64f69a7f..f27f4dc3c 100644 --- a/skiko/src/iosMain/kotlin/org/jetbrains/skiko/Actuals.ios.kt +++ b/skiko/src/iosMain/kotlin/org/jetbrains/skiko/Actuals.ios.kt @@ -1,12 +1,6 @@ package org.jetbrains.skiko -import platform.Foundation.NSURL.Companion.URLWithString -import platform.UIKit.UIApplication -import platform.UIKit.UIPasteboard - -internal actual fun URIHandler_openUri(uri: String) { - UIApplication.sharedApplication.openURL(URLWithString(uri)!!) -} +import platform.UIKit.* internal actual fun ClipboardManager_setText(text: String) { UIPasteboard.generalPasteboard.string = text @@ -17,17 +11,7 @@ internal actual fun ClipboardManager_getText(): String? { internal actual fun ClipboardManager_hasText(): Boolean = UIPasteboard.generalPasteboard.hasStrings() -// TODO: not sure if correct. -actual typealias Cursor = Any - -internal actual fun CursorManager_setCursor(component: Any, cursor: Cursor) {} - -internal actual fun CursorManager_getCursor(component: Any): Cursor? = null - -internal actual fun getCursorById(id: PredefinedCursorsId): Cursor = - when (id) { - PredefinedCursorsId.DEFAULT -> Any() - PredefinedCursorsId.CROSSHAIR -> Any() - PredefinedCursorsId.HAND -> Any() - PredefinedCursorsId.TEXT -> Any() - } \ No newline at end of file +internal actual fun UIView.skikoInitializeUIView() { + multipleTouchEnabled = true + userInteractionEnabled = true +} diff --git a/skiko/src/iosMain/kotlin/org/jetbrains/skiko/TextActions.kt b/skiko/src/iosMain/kotlin/org/jetbrains/skiko/TextActions.kt deleted file mode 100644 index e31b8d407..000000000 --- a/skiko/src/iosMain/kotlin/org/jetbrains/skiko/TextActions.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.jetbrains.skiko - -interface TextActions { - /** - * Copy action. If null, then copy is not possible in current context - */ - val copy: (() -> Unit)? - - /** - * Paste action. If null, then paste is not possible in current context - */ - val paste: (() -> Unit)? - - /** - * Cut action. If null, then cut is not possible in current context - */ - val cut: (() -> Unit)? - - /** - * SelectAll action. If null, then select all is not possible in current context - */ - val selectAll: (() -> Unit)? -} diff --git a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/SkikoProperties.kt b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/SkikoProperties.kt index cf06a066c..621e92c61 100644 --- a/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/SkikoProperties.kt +++ b/skiko/src/jvmMain/kotlin/org/jetbrains/skiko/SkikoProperties.kt @@ -96,7 +96,7 @@ object SkikoProperties { OS.Linux -> return GraphicsApi.OPENGL OS.Windows -> return GraphicsApi.DIRECT3D OS.Android -> return GraphicsApi.OPENGL - OS.JS, OS.Ios, OS.Unknown -> TODO("commonize me") + OS.JS, OS.Ios, OS.Tvos, OS.Unknown -> TODO("commonize me") } } @@ -110,7 +110,7 @@ object SkikoProperties { else -> listOf(GraphicsApi.DIRECT3D, GraphicsApi.OPENGL, GraphicsApi.SOFTWARE_FAST, GraphicsApi.SOFTWARE_COMPAT) } OS.Android -> return listOf(GraphicsApi.OPENGL) - OS.JS, OS.Ios, OS.Unknown -> TODO("commonize me") + OS.JS, OS.Ios, OS.Tvos, OS.Unknown -> TODO("commonize me") } val indexOfInitialApi = fallbackApis.indexOf(initialApi) diff --git a/skiko/src/nativeMain/kotlin/org/jetbrains/skiko/OsArch.native.kt b/skiko/src/nativeMain/kotlin/org/jetbrains/skiko/OsArch.native.kt index d59d946bd..00ddaab58 100644 --- a/skiko/src/nativeMain/kotlin/org/jetbrains/skiko/OsArch.native.kt +++ b/skiko/src/nativeMain/kotlin/org/jetbrains/skiko/OsArch.native.kt @@ -9,6 +9,7 @@ actual val hostOs: OS by lazy { OsFamily.LINUX -> OS.Linux OsFamily.WINDOWS -> OS.Windows OsFamily.IOS -> OS.Ios + OsFamily.TVOS -> OS.Tvos else -> throw Error("Unsupported OS ${Platform.osFamily}") } } diff --git a/skiko/src/tvosMain/kotlin/org/jetbrains/skiko/Actuals.tvos.kt b/skiko/src/tvosMain/kotlin/org/jetbrains/skiko/Actuals.tvos.kt new file mode 100644 index 000000000..264c66edc --- /dev/null +++ b/skiko/src/tvosMain/kotlin/org/jetbrains/skiko/Actuals.tvos.kt @@ -0,0 +1,17 @@ +package org.jetbrains.skiko + +import platform.UIKit.* + +// tvOS doesn't have support for clipboard +internal actual fun ClipboardManager_setText(text: String) { +} + +internal actual fun ClipboardManager_getText(): String? { + return null +} + +internal actual fun ClipboardManager_hasText(): Boolean = false + +internal actual fun UIView.skikoInitializeUIView() { + userInteractionEnabled = true +} diff --git a/skiko/src/uikitMain/kotlin/org/jetbrains/skiko/Actuals.uikit.kt b/skiko/src/uikitMain/kotlin/org/jetbrains/skiko/Actuals.uikit.kt new file mode 100644 index 000000000..fa5220a65 --- /dev/null +++ b/skiko/src/uikitMain/kotlin/org/jetbrains/skiko/Actuals.uikit.kt @@ -0,0 +1,23 @@ +package org.jetbrains.skiko + +import platform.Foundation.NSURL.Companion.URLWithString +import platform.UIKit.UIApplication + +internal actual fun URIHandler_openUri(uri: String) { + UIApplication.sharedApplication.openURL(URLWithString(uri)!!) +} + +// TODO: not sure if correct. +actual typealias Cursor = Any + +internal actual fun CursorManager_setCursor(component: Any, cursor: Cursor) {} + +internal actual fun CursorManager_getCursor(component: Any): Cursor? = null + +internal actual fun getCursorById(id: PredefinedCursorsId): Cursor = + when (id) { + PredefinedCursorsId.DEFAULT -> Any() + PredefinedCursorsId.CROSSHAIR -> Any() + PredefinedCursorsId.HAND -> Any() + PredefinedCursorsId.TEXT -> Any() + } \ No newline at end of file diff --git a/skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt b/skiko/src/uikitMain/kotlin/org/jetbrains/skiko/SkiaLayer.uikit.kt similarity index 100% rename from skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkiaLayer.ios.kt rename to skiko/src/uikitMain/kotlin/org/jetbrains/skiko/SkiaLayer.uikit.kt diff --git a/skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkikoUIView.kt b/skiko/src/uikitMain/kotlin/org/jetbrains/skiko/SkikoUIView.kt similarity index 84% rename from skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkikoUIView.kt rename to skiko/src/uikitMain/kotlin/org/jetbrains/skiko/SkikoUIView.kt index 8ff5167b3..94e6e25e5 100644 --- a/skiko/src/iosMain/kotlin/org/jetbrains/skiko/SkikoUIView.kt +++ b/skiko/src/uikitMain/kotlin/org/jetbrains/skiko/SkikoUIView.kt @@ -1,21 +1,15 @@ package org.jetbrains.skiko import kotlinx.cinterop.* -import org.jetbrains.skia.Point -import org.jetbrains.skia.Rect -import org.jetbrains.skiko.ios.SkikoUITextInputTraits -import org.jetbrains.skiko.redrawer.MetalRedrawer +import org.jetbrains.skiko.redrawer.* import platform.CoreGraphics.* import platform.Foundation.* -import platform.Metal.MTLCreateSystemDefaultDevice -import platform.Metal.MTLDeviceProtocol -import platform.Metal.MTLPixelFormatBGRA8Unorm -import platform.QuartzCore.CAMetalLayer +import platform.Metal.* +import platform.QuartzCore.* import platform.UIKit.* -import platform.darwin.NSInteger -import kotlin.math.max -import kotlin.math.min -import kotlin.native.ref.WeakReference +import kotlin.native.ref.* + +internal expect fun UIView.skikoInitializeUIView(): Unit @Suppress("CONFLICTING_OVERLOADS") @ExportObjCClass @@ -37,7 +31,7 @@ class SkikoUIView : UIView { private lateinit var _redrawer: MetalRedrawer init { - multipleTouchEnabled = true + skikoInitializeUIView() opaque = false // For UIKit interop through a "Hole" _metalLayer.also { diff --git a/skiko/src/iosMain/kotlin/org/jetbrains/skiko/SystemTheme.ios.kt b/skiko/src/uikitMain/kotlin/org/jetbrains/skiko/SystemTheme.uikit.kt similarity index 100% rename from skiko/src/iosMain/kotlin/org/jetbrains/skiko/SystemTheme.ios.kt rename to skiko/src/uikitMain/kotlin/org/jetbrains/skiko/SystemTheme.uikit.kt diff --git a/skiko/src/iosMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.ios.kt b/skiko/src/uikitMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.uikit.kt similarity index 100% rename from skiko/src/iosMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.ios.kt rename to skiko/src/uikitMain/kotlin/org/jetbrains/skiko/redrawer/MetalRedrawer.uikit.kt