IJPL-174294 remote dev: update Mac application image when starting frontend process

A custom icns file for remote dev mode is copied to Resources/frontend.icns in the build scripts, and path to it is passed as `apple.awt.application.icon` system property in JVM arguments for the frontend process to override the value from the bundle.

GitOrigin-RevId: 9bd9db95cf5f54df29d59bc35f4073eca24f417a
This commit is contained in:
Nikolay Chashnikov
2026-02-13 23:07:34 +00:00
committed by intellij-monorepo-bot
parent ee70408efe
commit 7bb876b50c
5 changed files with 27 additions and 9 deletions
@@ -20,8 +20,8 @@ import org.jetbrains.intellij.build.NativeBinaryDownloader
import org.jetbrains.intellij.build.OsFamily
import org.jetbrains.intellij.build.executeStep
import org.jetbrains.intellij.build.impl.OsSpecificDistributionBuilder.Companion.suffix
import org.jetbrains.intellij.build.impl.client.ADDITIONAL_EMBEDDED_CLIENT_VM_OPTIONS
import org.jetbrains.intellij.build.impl.client.createFrontendContextForLaunchers
import org.jetbrains.intellij.build.impl.client.getAdditionalEmbeddedClientVmOptions
import org.jetbrains.intellij.build.impl.productInfo.PRODUCT_INFO_FILE_NAME
import org.jetbrains.intellij.build.impl.productInfo.generateEmbeddedFrontendLaunchData
import org.jetbrains.intellij.build.impl.productInfo.generateProductInfoJson
@@ -87,7 +87,7 @@ class LinuxDistributionBuilder(
createFrontendContextForLaunchers(context)?.let { clientContext ->
writeLinuxVmOptions(distBinDir, clientContext)
generateLauncherScript(
distBinDir, arch, ADDITIONAL_EMBEDDED_CLIENT_VM_OPTIONS, targetLibcImpl, clientContext
distBinDir, arch, getAdditionalEmbeddedClientVmOptions(OsFamily.LINUX, context), targetLibcImpl, clientContext
)
}
generateReadme(targetPath)
@@ -58,7 +58,6 @@ import java.util.zip.Deflater
import kotlin.io.path.ExperimentalPathApi
import kotlin.io.path.createDirectories
import kotlin.io.path.deleteRecursively
import kotlin.io.path.exists
import kotlin.io.path.extension
import kotlin.io.path.isRegularFile
import kotlin.io.path.listDirectoryEntries
@@ -286,6 +285,13 @@ class MacDistributionBuilder(
if (alternativeIcon != null) {
copyFile(alternativeIcon, resourcesDistDir.resolve("custom.icns"))
}
if (context.isEmbeddedFrontendEnabled) {
val icnsForFrontendApp = locateIcnsForFrontendMacApp(context)
if (icnsForFrontendApp != null) {
//path to the copied file will be passed as the value of `apple.awt.application.icon` property in `getAdditionalEmbeddedClientVmOptions`
copyFile(icnsForFrontendApp, resourcesDistDir.resolve("frontend.icns"))
}
}
for (fileAssociation in customizer.fileAssociations) {
if (!fileAssociation.iconPath.isEmpty()) {
@@ -29,7 +29,7 @@ internal fun locateIcoFileForWindowsLauncher(customizer: WindowsDistributionCust
internal fun locateIcnsForMacApp(customizer: MacDistributionCustomizer, context: BuildContext): Path {
if (context.productProperties.productMode == ProductMode.FRONTEND) {
val frontendIcnsPath = locateFrontendImageFile(filePath = MAC_ICNS_FRONTEND_PATH, eapFilePath = MAC_ICNS_FRONTEND_EAP_PATH, context = context)
val frontendIcnsPath = locateIcnsForFrontendMacApp(context)
if (frontendIcnsPath != null) {
return frontendIcnsPath
}
@@ -43,6 +43,10 @@ internal fun locateIcnsForMacApp(customizer: MacDistributionCustomizer, context:
return customizer.icnsPath ?: context.productProperties.imagesDirectoryPath?.resolve(MAC_ICNS_PATH) ?: error("Path to icns file is not specified")
}
internal fun locateIcnsForFrontendMacApp(context: BuildContext): Path? {
return locateFrontendImageFile(filePath = MAC_ICNS_FRONTEND_PATH, eapFilePath = MAC_ICNS_FRONTEND_EAP_PATH, context = context)
}
internal fun locateDmgImageForMacApp(customizer: MacDistributionCustomizer, context: BuildContext): Path {
if (context.applicationInfo.isEAP) {
val eapDmgImagePath = customizer.dmgImagePathForEAP ?: context.productProperties.imagesDirectoryPath?.resolve(MAC_DMG_BACKGROUND_EAP_PATH)?.takeIf { it.exists() }
@@ -2,6 +2,8 @@
package org.jetbrains.intellij.build.impl.client
import org.jetbrains.intellij.build.BuildContext
import org.jetbrains.intellij.build.OsFamily
import org.jetbrains.intellij.build.impl.locateIcnsForFrontendMacApp
/**
* Creates a copy of [originalContext] with [org.jetbrains.intellij.build.ProductProperties] changed to a frontend variant (JetBrains Client) properties.
@@ -17,6 +19,12 @@ internal suspend fun createFrontendContextForLaunchers(originalContext: BuildCon
return null
}
internal val ADDITIONAL_EMBEDDED_CLIENT_VM_OPTIONS: List<String> = listOf(
"-Dintellij.platform.load.app.info.from.resources=true",
)
internal fun getAdditionalEmbeddedClientVmOptions(os: OsFamily, ideContext: BuildContext): List<String> {
val result = mutableListOf(
"-Dintellij.platform.load.app.info.from.resources=true",
)
if (os == OsFamily.MACOS && locateIcnsForFrontendMacApp(ideContext) != null) {
result.add($$"-Dapple.awt.application.icon=$APP_PACKAGE/Contents/Resources/frontend.icns")
}
return result
}
@@ -16,8 +16,8 @@ import org.jetbrains.intellij.build.BuiltinModulesFileData
import org.jetbrains.intellij.build.JvmArchitecture
import org.jetbrains.intellij.build.OsFamily
import org.jetbrains.intellij.build.impl.Git
import org.jetbrains.intellij.build.impl.client.ADDITIONAL_EMBEDDED_CLIENT_VM_OPTIONS
import org.jetbrains.intellij.build.impl.client.createFrontendContextForLaunchers
import org.jetbrains.intellij.build.impl.client.getAdditionalEmbeddedClientVmOptions
import org.jetbrains.jps.model.java.JpsJavaExtensionService
import java.nio.file.Files
import java.nio.file.Path
@@ -135,7 +135,7 @@ internal suspend fun generateEmbeddedFrontendLaunchData(
commands = listOf("thinClient", "thinClient-headless", "installFrontendPlugins"),
vmOptionsFilePath = vmOptionsFilePath(clientContext),
bootClassPathJarNames = clientContext.bootClassPathJarNames,
additionalJvmArguments = clientContext.getAdditionalJvmArguments(os, arch) + ADDITIONAL_EMBEDDED_CLIENT_VM_OPTIONS,
additionalJvmArguments = clientContext.getAdditionalJvmArguments(os, arch) + getAdditionalEmbeddedClientVmOptions(os, ideContext),
mainClass = clientContext.ideMainClassName,
envVarBaseName = "JETBRAINS_CLIENT",
dataDirectoryName = clientContext.systemSelector,