Browse Source

Allow adding extra keys to Info.plist (#845)

Resolves #795
pull/860/head
Alexey Tsvetkov 3 years ago committed by GitHub
parent
commit
6038da77ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/PlatformSettings.kt
  2. 4
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/InfoPlistBuilder.kt
  3. 1
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/configureApplication.kt
  4. 7
      gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJPackageTask.kt
  5. 12
      gradle-plugins/compose/src/test/test-projects/application/macOptions/Expected-Info.plist
  6. 16
      gradle-plugins/compose/src/test/test-projects/application/macOptions/build.gradle
  7. 79
      tutorials/Native_distributions_and_local_execution/README.md

9
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/dsl/PlatformSettings.kt

@ -41,6 +41,15 @@ open class MacOSPlatformSettings @Inject constructor(objects: ObjectFactory): Pl
fun notarization(fn: Action<MacOSNotarizationSettings>) {
fn.execute(notarization)
}
internal val infoPlistSettings = InfoPlistSettings()
fun infoPlist(fn: Action<InfoPlistSettings>) {
fn.execute(infoPlistSettings)
}
}
open class InfoPlistSettings {
var extraKeysRawXml: String? = null
}
open class LinuxPlatformSettings @Inject constructor(objects: ObjectFactory): PlatformSettings(objects) {

4
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/InfoPlistBuilder.kt

@ -5,10 +5,11 @@
package org.jetbrains.compose.desktop.application.internal
import org.jetbrains.compose.desktop.application.dsl.InfoPlistSettings
import java.io.File
import kotlin.reflect.KProperty
internal class InfoPlistBuilder {
internal class InfoPlistBuilder(private val extraPlistKeysRawXml: String?) {
private val values = LinkedHashMap<InfoPlistKey, String>()
operator fun get(key: InfoPlistKey): String? = values[key]
@ -27,6 +28,7 @@ internal class InfoPlistBuilder {
appendLine(" <key>${k.name}</key>")
appendLine(" <string>$v</string>")
}
extraPlistKeysRawXml?.let { appendLine(it) }
appendLine(" </dict>")
appendLine("</plist>")
}

1
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/internal/configureApplication.kt

@ -275,6 +275,7 @@ internal fun AbstractJPackageTask.configurePlatformSettings(app: Application) {
provider { mac.dockName }
)
nonValidatedMacBundleID.set(provider { mac.bundleID })
macExtraPlistKeysRawXml.set(provider { mac.infoPlistSettings.extraKeysRawXml })
nonValidatedMacSigningSettings = app.nativeDistributions.macOS.signing
iconFile.set(mac.iconFile.orElse(DefaultIcons.forMac(project)))
installationPath.set(mac.installationPath)

7
gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/desktop/application/tasks/AbstractJPackageTask.kt

@ -15,6 +15,7 @@ import org.gradle.api.tasks.Optional
import org.gradle.process.ExecResult
import org.gradle.work.ChangeType
import org.gradle.work.InputChanges
import org.jetbrains.compose.desktop.application.dsl.InfoPlistSettings
import org.jetbrains.compose.desktop.application.dsl.MacOSSigningSettings
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
import org.jetbrains.compose.desktop.application.internal.*
@ -169,6 +170,10 @@ abstract class AbstractJPackageTask @Inject constructor(
@get:Optional
internal val nonValidatedMacBundleID: Property<String?> = objects.nullableProperty()
@get:Input
@get:Optional
internal val macExtraPlistKeysRawXml: Property<String?> = objects.nullableProperty()
@get:Optional
@get:Nested
internal var nonValidatedMacSigningSettings: MacOSSigningSettings? = null
@ -361,7 +366,7 @@ abstract class AbstractJPackageTask @Inject constructor(
fileOperations.delete(resourcesDir)
fileOperations.mkdir(resourcesDir)
if (currentOS == OS.MacOS) {
InfoPlistBuilder()
InfoPlistBuilder(macExtraPlistKeysRawXml.orNull)
.also { setInfoPlistValues(it) }
.writeToFile(resourcesDir.ioFile.resolve("Info.plist"))
}

12
gradle-plugins/compose/src/test/test-projects/application/macOptions/Expected-Info.plist

@ -32,5 +32,17 @@
<string>true</string>
<key>NSHighResolutionCapable</key>
<string>true</string>
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Exameple URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>exampleUrl</string>
</array>
</dict>
</array>
</dict>
</plist>

16
gradle-plugins/compose/src/test/test-projects/application/macOptions/build.gradle

@ -18,6 +18,19 @@ dependencies {
implementation compose.desktop.currentOs
}
def extraInfoPlistKeys = """
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Exameple URL</string>
<key>CFBundleURLSchemes</key>
<array>
<string>exampleUrl</string>
</array>
</dict>
</array>"""
compose.desktop {
application {
mainClass = "MainKt"
@ -25,6 +38,9 @@ compose.desktop {
packageName = "TestPackage"
macOS {
dockName = "CustomDockName"
infoPlist {
extraKeysRawXml = extraInfoPlistKeys
}
}
}
}

79
tutorials/Native_distributions_and_local_execution/README.md

@ -370,6 +370,7 @@ The following platform-specific options are available
(see the section `Specifying package version` for details);
* `pkgPackageVersion = "PKG_VERSION"` — a pkg-specific package version
(see the section `Specifying package version` for details);
* `infoPlist` — see the section `Customizing Info.plist on macOS` for details;
* Windows:
* `console = true` adds a console launcher for the application;
* `dirChooser = true` enables customizing the installation path during installation;
@ -383,7 +384,7 @@ The following platform-specific options are available
(see the section `Specifying package version` for details);
* `exePackageVersion = "EXE_VERSION"` — a pkg-specific package version
(see the section `Specifying package version` for details);
## App icon
The app icon needs to be provided in OS-specific formats:
@ -408,3 +409,79 @@ compose.desktop {
}
}
```
## Customizing Info.plist on macOS
We aim to support important platform-specific customization use-cases via declarative DSL.
However, the provided DSL is not enough sometimes. If you need to specify `Info.plist`
values, that are not modeled in the DSL, you can work around by specifying a piece
of raw XML, that will be appended to the application's `Info.plist`.
### Example: deep linking into macOS apps
1. Specify a custom URL scheme:
``` kotlin
// build.gradle.kts
compose.desktop {
application {
mainClass = "MainKt"
nativeDistributions {
targetFormats(TargetFormat.Dmg)
packageName = "Deep Linking Example App"
macOS {
bundleID = "org.jetbrains.compose.examples.deeplinking"
infoPlist {
extraKeysRawXml = macExtraPlistKeys
}
}
}
}
}
val macExtraPlistKeys: String
get() = """
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>Example deep link</string>
<key>CFBundleURLSchemes</key>
<array>
<string>compose</string>
</array>
</dict>
</array>
"""
"""
```
2. Use `java.awt.Desktop` to set up a URI handler:
``` kotlin
// src/main/main.kt
import androidx.compose.desktop.Window
import androidx.compose.material.Text
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import java.awt.Desktop
fun main() {
val text = mutableStateOf("Hello, World!")
Desktop.getDesktop().setOpenURIHandler { event ->
text.value = "Open URI: " + event.uri
}
Window {
var text by remember { text }
MaterialTheme {
Text(text)
}
}
}
```
3. Run `./gradlew runDistributable`.
4. Links like `compose://foo/bar` are now redirected from a browser to your application.

Loading…
Cancel
Save