From e2f30aadf75041737258d4b72ab43b459b7fa109 Mon Sep 17 00:00:00 2001 From: Alex Simons Date: Fri, 14 Jun 2024 22:02:28 -0500 Subject: [PATCH 01/13] Bump supported version to 2024.2 --- gradle.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/gradle.properties b/gradle.properties index 5e4c4116f..8fb1af60a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,16 +2,16 @@ # -> https://www.jetbrains.org/intellij/sdk/docs/reference_guide/intellij_artifacts.html pluginGroup=io.unthrottled -pluginVersion=88.5-1.13.0 +pluginVersion=88.5-1.14.0 pluginSinceBuild=233.8264.8 -pluginUntilBuild=241.* +pluginUntilBuild=242.* # Plugin Verifier integration -> https://github.com/JetBrains/gradle-intellij-plugin#plugin-verifier-dsl # See https://jb.gg/intellij-platform-builds-list for available build versions. -pluginVerifierIdeVersions = 2023.3.2 +pluginVerifierIdeVersions = 2023.3.2, 2024.2 platformType = IU -platformVersion = 2023.3.2 +platformVersion = LATEST-EAP-SNAPSHOT platformDownloadSources = true # Plugin Dependencies -> https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_dependencies.html # Example: platformPlugins = com.intellij.java,com.jetbrains.php:203.4449.22 From 86edb7ff973326637d4a11cd081f70528169dd3d Mon Sep 17 00:00:00 2001 From: Alex Simons Date: Sun, 7 Jul 2024 16:18:46 -0500 Subject: [PATCH 02/13] Removed application info usage. --- .../doki/integrations/ErrorReporter.kt | 8 ++++---- .../unthrottled/doki/service/PluginService.kt | 20 ++++++++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/io/unthrottled/doki/integrations/ErrorReporter.kt b/src/main/kotlin/io/unthrottled/doki/integrations/ErrorReporter.kt index cb239d57c..b78726fbf 100644 --- a/src/main/kotlin/io/unthrottled/doki/integrations/ErrorReporter.kt +++ b/src/main/kotlin/io/unthrottled/doki/integrations/ErrorReporter.kt @@ -3,9 +3,9 @@ package io.unthrottled.doki.integrations import com.google.gson.Gson import com.intellij.ide.IdeBundle import com.intellij.ide.ui.LafManager +import com.intellij.openapi.application.ApplicationInfo import com.intellij.openapi.application.ApplicationNamesInfo import com.intellij.openapi.application.ex.ApplicationInfoEx -import com.intellij.openapi.application.impl.ApplicationInfoImpl import com.intellij.openapi.diagnostic.ErrorReportSubmitter import com.intellij.openapi.diagnostic.IdeaLoggingEvent import com.intellij.openapi.diagnostic.SubmittedReportInfo @@ -120,7 +120,7 @@ class ErrorReporter : ErrorReportSubmitter() { ManagementFactory.getGarbageCollectorMXBeans().stream() .map { it.name }.collect(Collectors.joining(",")) - private fun getBuildInfo(appInfo: ApplicationInfoImpl): String { + private fun getBuildInfo(appInfo: ApplicationInfo): String { var buildInfo = IdeBundle.message("about.box.build.number", appInfo.build.asString()) val cal = appInfo.buildDate var buildDate = "" @@ -132,8 +132,8 @@ class ErrorReporter : ErrorReportSubmitter() { return buildInfo } - private fun getAppName(): Pair { - val appInfo = ApplicationInfoEx.getInstanceEx() as ApplicationInfoImpl + private fun getAppName(): Pair { + val appInfo = ApplicationInfoEx.getInstanceEx() as ApplicationInfo var appName = appInfo.fullApplicationName val edition = ApplicationNamesInfo.getInstance().editionName if (edition != null) appName += " ($edition)" diff --git a/src/main/kotlin/io/unthrottled/doki/service/PluginService.kt b/src/main/kotlin/io/unthrottled/doki/service/PluginService.kt index 41db667a7..8e68fea4b 100644 --- a/src/main/kotlin/io/unthrottled/doki/service/PluginService.kt +++ b/src/main/kotlin/io/unthrottled/doki/service/PluginService.kt @@ -5,15 +5,17 @@ import com.fasterxml.jackson.annotation.JsonProperty import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.databind.ObjectMapper import com.intellij.ide.plugins.PluginManagerCore +import com.intellij.openapi.application.ApplicationInfo import com.intellij.openapi.application.ApplicationManager -import com.intellij.openapi.application.impl.ApplicationInfoImpl +import com.intellij.openapi.application.ex.ApplicationInfoEx import com.intellij.openapi.extensions.PluginId import com.intellij.util.Urls import com.intellij.util.io.HttpRequests import io.unthrottled.doki.util.Logging import io.unthrottled.doki.util.logger import io.unthrottled.doki.util.runSafelyWithResult -import java.util.Collections +import io.unthrottled.doki.util.toOptional +import java.util.* import java.util.concurrent.Callable const val MOTIVATOR_PLUGIN_ID = "zd.zero.waifu-motivator-plugin" @@ -45,8 +47,12 @@ object PluginService : Logging { ) private val PLUGIN_MANAGER_URL by lazy { - ApplicationInfoImpl.getInstanceEx() - .pluginManagerUrl + ApplicationInfo.getInstance() + .toOptional() + .filter { it is ApplicationInfoEx } + .map { it as ApplicationInfoEx } + .map { it.pluginManagerUrl } + .orElseGet { "https://plugins.jetbrains.com" } .trimEnd('/') } private val COMPATIBLE_UPDATE_URL by lazy { "$PLUGIN_MANAGER_URL/api/search/compatibleUpdates" } @@ -81,10 +87,10 @@ object PluginService : Logging { val data = objectMapper.writeValueAsString( CompatibleUpdateRequest( - ApplicationInfoImpl.getInstanceEx() + ApplicationInfo.getInstance() .build.asString(), - ids.map { it.idString }, - ), + ids.map { it.idString } + ) ) HttpRequests .post(Urls.newFromEncoded(COMPATIBLE_UPDATE_URL).toExternalForm(), HttpRequests.JSON_CONTENT_TYPE) From af0fec03ce4cb289706a80098b8f7a6211e6f5f5 Mon Sep 17 00:00:00 2001 From: Alex Simons Date: Sun, 7 Jul 2024 16:32:31 -0500 Subject: [PATCH 03/13] Removed startup activity usage. --- src/main/kotlin/io/unthrottled/doki/TheDokiTheme.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/io/unthrottled/doki/TheDokiTheme.kt b/src/main/kotlin/io/unthrottled/doki/TheDokiTheme.kt index 1c14c102d..e6e304213 100644 --- a/src/main/kotlin/io/unthrottled/doki/TheDokiTheme.kt +++ b/src/main/kotlin/io/unthrottled/doki/TheDokiTheme.kt @@ -7,7 +7,6 @@ import com.intellij.openapi.application.ApplicationActivationListener import com.intellij.openapi.application.ApplicationManager import com.intellij.openapi.extensions.PluginId import com.intellij.openapi.project.Project -import com.intellij.openapi.startup.StartupManager import com.intellij.openapi.wm.IdeFrame import io.unthrottled.doki.config.ThemeConfig import io.unthrottled.doki.hax.HackComponent.hackLAF @@ -30,8 +29,7 @@ import io.unthrottled.doki.stickers.StickerPaneService import io.unthrottled.doki.themes.ThemeManager import io.unthrottled.doki.util.doOrElse import io.unthrottled.doki.util.toOptional -import java.util.Optional -import java.util.UUID +import java.util.* class TheDokiTheme : Disposable { companion object { @@ -114,7 +112,7 @@ class TheDokiTheme : Disposable { LegacyMigration.newVersionMigration(project) ThemeConfig.instance.version = version ThemeManager.instance.currentTheme.ifPresent { - StartupManager.getInstance(project).runAfterOpened { + ApplicationManager.getApplication().invokeLater { UpdateNotification.display( project, version, @@ -124,7 +122,7 @@ class TheDokiTheme : Disposable { } } - StartupManager.getInstance(project).runAfterOpened { + ApplicationManager.getApplication().invokeLater { PromotionManager.registerPromotion(version) } } From fbc8ad6417811d8e5ceda3dd9499551c88fcea80 Mon Sep 17 00:00:00 2001 From: Alex Simons Date: Sun, 7 Jul 2024 16:34:47 -0500 Subject: [PATCH 04/13] Removed expui references. --- src/main/kotlin/io/unthrottled/doki/legacy/EXPUIFixer.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/io/unthrottled/doki/legacy/EXPUIFixer.kt b/src/main/kotlin/io/unthrottled/doki/legacy/EXPUIFixer.kt index 37e5cc00f..d1838f3d7 100644 --- a/src/main/kotlin/io/unthrottled/doki/legacy/EXPUIFixer.kt +++ b/src/main/kotlin/io/unthrottled/doki/legacy/EXPUIFixer.kt @@ -4,7 +4,7 @@ import com.intellij.ide.ui.LafManager import com.intellij.ide.ui.LafManagerListener import com.intellij.openapi.Disposable import com.intellij.openapi.application.ApplicationManager -import com.intellij.ui.ExperimentalUI +import com.intellij.ui.NewUI import com.intellij.util.ui.JBUI import io.unthrottled.doki.themes.ThemeManager import javax.swing.UIDefaults @@ -17,9 +17,8 @@ object EXPUIFixer : LafManagerListener, Disposable { connection.subscribe(LafManagerListener.TOPIC, this) } - @Suppress("UnstableApiUsage") fun fixExperimentalUI() { - if (!ExperimentalUI.isNewUI()) return + if (!NewUI.isEnabled()) return overrideSetProperties(0) } From 1b01c35b1b6073f1c8855b8888ae556b37d375bf Mon Sep 17 00:00:00 2001 From: Alex Simons Date: Sun, 7 Jul 2024 16:55:37 -0500 Subject: [PATCH 05/13] Fix Compile Issue. --- .../kotlin/io/unthrottled/doki/integrations/RestClient.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/io/unthrottled/doki/integrations/RestClient.kt b/src/main/kotlin/io/unthrottled/doki/integrations/RestClient.kt index 61a1eb78e..4eba22ccf 100644 --- a/src/main/kotlin/io/unthrottled/doki/integrations/RestClient.kt +++ b/src/main/kotlin/io/unthrottled/doki/integrations/RestClient.kt @@ -34,8 +34,8 @@ object RestTools { fun performRequest( url: String, - bodyExtractor: (InputStream) -> T, - ): Optional { + bodyExtractor: (InputStream) -> T & Any, + ): Optional { log.info("Attempting to download remote asset: $url") return runSafelyWithResult({ HttpRequests.request(url) @@ -46,7 +46,7 @@ object RestTools { body.toOptional() }) { log.warn("Unable to get remote asset: $url for raisins", it) - Optional.empty() + Optional.empty() } } }) { From b8e9255cb0789d25336832c992d90dcf3c9bb2aa Mon Sep 17 00:00:00 2001 From: Alex Simons Date: Sun, 7 Jul 2024 17:05:23 -0500 Subject: [PATCH 06/13] =?UTF-8?q?First=20Hax=CB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/io/unthrottled/doki/hax/MoreHax.kt | 3 + .../io/unthrottled/doki/hax/SvgLoader.kt | 77 +++++++++++++++++++ .../unthrottled/doki/hax/SvgLoaderHacker.kt | 6 +- .../io/unthrottled/doki/icon/ColorPatcher.kt | 2 +- 4 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/io/unthrottled/doki/hax/MoreHax.kt create mode 100644 src/main/kotlin/io/unthrottled/doki/hax/SvgLoader.kt diff --git a/src/main/kotlin/io/unthrottled/doki/hax/MoreHax.kt b/src/main/kotlin/io/unthrottled/doki/hax/MoreHax.kt new file mode 100644 index 000000000..3b4dbab6d --- /dev/null +++ b/src/main/kotlin/io/unthrottled/doki/hax/MoreHax.kt @@ -0,0 +1,3 @@ +package io.unthrottled.doki.hax + +public fun setSelectionColorPatcherProvider(colorPatcher: SVGLoader.SvgElementColorPatcherProvider?): kotlin.Unit {} \ No newline at end of file diff --git a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoader.kt b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoader.kt new file mode 100644 index 000000000..e4dea77e5 --- /dev/null +++ b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoader.kt @@ -0,0 +1,77 @@ +package io.unthrottled.doki.hax; + +import com.intellij.openapi.util.IconLoader +import com.intellij.ui.svg.* +import org.w3c.dom.Element +import java.awt.* +import java.awt.image.BufferedImage +import java.io.IOException +import java.io.InputStream +import java.net.URL +import kotlin.math.max + +private val iconMaxSize: Float by lazy { + var maxSize = Integer.MAX_VALUE.toFloat() + if (!GraphicsEnvironment.isHeadless()) { + val device = GraphicsEnvironment.getLocalGraphicsEnvironment().defaultScreenDevice + val bounds = device.defaultConfiguration.bounds + val tx = device.defaultConfiguration.defaultTransform + maxSize = max(bounds.width * tx.scaleX, bounds.height * tx.scaleY).toInt().toFloat() + } + maxSize +} + +/** + * Plugins should use [ImageLoader.loadFromResource]. + */ +object SVGLoader { + const val ICON_DEFAULT_SIZE: Int = 16 + + @Throws(IOException::class) + @JvmStatic + fun load(url: URL, scale: Float): Image { + return loadSvg(path = url.path, stream = url.openStream(), scale = scale, colorPatcherProvider = null) + } + + @Throws(IOException::class) + @JvmStatic + fun load(stream: InputStream, scale: Float): Image { + return loadSvg(path = null, stream = stream, scale = scale, colorPatcherProvider = null) + } + + @Throws(IOException::class) + fun load(url: URL?, stream: InputStream, scale: Float): BufferedImage { + return loadSvg(path = url?.path, stream = stream, scale = scale, colorPatcherProvider = null) + } + + @JvmStatic + var colorPatcherProvider: SvgElementColorPatcherProvider? = null + set(colorPatcher) { + field = colorPatcher + IconLoader.clearCache() + } + + @Deprecated("Please use SvgAttributePatcher") + @Suppress("unused") + interface SvgElementColorPatcher { + fun patchColors(svg: Element) { + } + + /** + * @return hash code of the current SVG color patcher or null to disable rendered SVG images caching + */ + fun digest(): ByteArray? + } + + interface SvgElementColorPatcherProvider { + fun attributeForPath(path: String): SvgAttributePatcher? = null + + /** + * Returns a digest of the current SVG color patcher. + * + * Consider using a two-element array, where the first element is a hash of the input data for the patcher, + * and the second is an ID of the patcher (see [com.intellij.ui.icons.ColorPatcherIdGenerator]). + */ + fun digest(): LongArray + } +} \ No newline at end of file diff --git a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt index 978037e21..8b3831984 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt @@ -1,7 +1,9 @@ package io.unthrottled.doki.hax import com.intellij.ui.svg.setSelectionColorPatcherProvider -import com.intellij.util.SVGLoader +import io.unthrottled.doki.hax.SVGLoader +//import com.intellij.ui.svg.setSelectionColorPatcherProvider +//import com.intellij.util.SVGLoader import io.unthrottled.doki.icon.ColorPatcher import io.unthrottled.doki.service.PluginService import io.unthrottled.doki.themes.DokiTheme @@ -45,3 +47,5 @@ object SvgLoaderHacker { otherPatcher } } + + diff --git a/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt b/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt index 022ae717e..40c787e5c 100644 --- a/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt +++ b/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt @@ -48,7 +48,7 @@ object ColorPatcher : PatcherProvider { .filter { it is UIThemeLookAndFeelInfoImpl } .map { it as UIThemeLookAndFeelInfoImpl } .ifPresent { - this.uiColorPatcherProvider = it.theme.colorPatcher ?: noOptPatcherProvider + this.uiColorPatcherProvider = (it.theme.colorPatcher ?: noOptPatcherProvider) as PatcherProvider } clearCaches() } From d8dd367dc43a59c5c990745b2d4f89cf2b8efe4c Mon Sep 17 00:00:00 2001 From: Alex Simons Date: Sun, 7 Jul 2024 17:22:16 -0500 Subject: [PATCH 07/13] More hax, still in progress --- .../io/unthrottled/doki/hax/HackComponent.kt | 30 +++++++++++++++++++ .../unthrottled/doki/hax/SvgLoaderHacker.kt | 4 +-- .../unthrottled/doki/hax/{ => svg}/MoreHax.kt | 2 +- .../doki/hax/{ => svg}/SvgLoader.kt | 2 +- 4 files changed, 34 insertions(+), 4 deletions(-) rename src/main/kotlin/io/unthrottled/doki/hax/{ => svg}/MoreHax.kt (76%) rename src/main/kotlin/io/unthrottled/doki/hax/{ => svg}/SvgLoader.kt (98%) diff --git a/src/main/kotlin/io/unthrottled/doki/hax/HackComponent.kt b/src/main/kotlin/io/unthrottled/doki/hax/HackComponent.kt index 2f3ae25bb..4ce24f3bf 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/HackComponent.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/HackComponent.kt @@ -38,6 +38,7 @@ object HackComponent : Disposable { enableBackgroundConsistency() enableSelectionConsistency() enableHintConsistency() + enableMarketplaceCompatability() } fun init() { @@ -47,6 +48,10 @@ object HackComponent : Disposable { hackReformatHintInfoForeground() } + private fun enableMarketplaceCompatability() { + hackSVGLoader() + } + private fun hackReformatHintInfoForeground() { runSafely({ val cp = ClassPool(true) @@ -129,6 +134,31 @@ object HackComponent : Disposable { } } + private fun hackSVGLoader() { + runSafely({ + val cp = ClassPool(true) + cp.insertClassPath( + ClassClassPath( + Class.forName("io.unthrottled.doki.hax.FieldHacker"), + ), + ) + val ctClass = cp.get("io.unthrottled.doki.hax.SvgLoaderHacker") + ctClass.replaceClassName( + "io.unthrottled.doki.hax.svg.setSelectionColorPatcherProvider", + "com.intellij.ui.svg.setSelectionColorPatcherProvider", + + ) + ctClass.replaceClassName( + "io.unthrottled.doki.hax.svg.SVGLoader", + "com.intellij.util.SVGLoader", + + ) + ctClass.toClass() + }) { + log.warn("Unable to hackSVGLoader for reasons.") + } + } + private fun hackParameterInfoBackground() { runSafely({ val cp = ClassPool(true) diff --git a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt index 8b3831984..dce744571 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt @@ -1,7 +1,7 @@ package io.unthrottled.doki.hax -import com.intellij.ui.svg.setSelectionColorPatcherProvider -import io.unthrottled.doki.hax.SVGLoader +import io.unthrottled.doki.hax.svg.setSelectionColorPatcherProvider +import io.unthrottled.doki.hax.svg.SVGLoader //import com.intellij.ui.svg.setSelectionColorPatcherProvider //import com.intellij.util.SVGLoader import io.unthrottled.doki.icon.ColorPatcher diff --git a/src/main/kotlin/io/unthrottled/doki/hax/MoreHax.kt b/src/main/kotlin/io/unthrottled/doki/hax/svg/MoreHax.kt similarity index 76% rename from src/main/kotlin/io/unthrottled/doki/hax/MoreHax.kt rename to src/main/kotlin/io/unthrottled/doki/hax/svg/MoreHax.kt index 3b4dbab6d..669c240c4 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/MoreHax.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/svg/MoreHax.kt @@ -1,3 +1,3 @@ -package io.unthrottled.doki.hax +package io.unthrottled.doki.hax.svg public fun setSelectionColorPatcherProvider(colorPatcher: SVGLoader.SvgElementColorPatcherProvider?): kotlin.Unit {} \ No newline at end of file diff --git a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoader.kt b/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgLoader.kt similarity index 98% rename from src/main/kotlin/io/unthrottled/doki/hax/SvgLoader.kt rename to src/main/kotlin/io/unthrottled/doki/hax/svg/SvgLoader.kt index e4dea77e5..fa8ae3a30 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoader.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgLoader.kt @@ -1,4 +1,4 @@ -package io.unthrottled.doki.hax; +package io.unthrottled.doki.hax.svg; import com.intellij.openapi.util.IconLoader import com.intellij.ui.svg.* From 55687bef7b9f6550419b912e46f0d8a42bc481b4 Mon Sep 17 00:00:00 2001 From: Alex Simons Date: Mon, 8 Jul 2024 18:29:50 -0500 Subject: [PATCH 08/13] It works now. --- .../io/unthrottled/doki/hax/HackComponent.kt | 30 ----------- .../unthrottled/doki/hax/SvgLoaderHacker.kt | 51 +++++++++++++++---- .../io/unthrottled/doki/hax/svg/MoreHax.kt | 3 -- .../hax/svg/SvgElementColorPatcherProvider.kt | 15 ++++++ .../io/unthrottled/doki/hax/svg/SvgLoader.kt | 12 +---- .../io/unthrottled/doki/icon/ColorPatcher.kt | 15 +++--- 6 files changed, 65 insertions(+), 61 deletions(-) delete mode 100644 src/main/kotlin/io/unthrottled/doki/hax/svg/MoreHax.kt create mode 100644 src/main/kotlin/io/unthrottled/doki/hax/svg/SvgElementColorPatcherProvider.kt diff --git a/src/main/kotlin/io/unthrottled/doki/hax/HackComponent.kt b/src/main/kotlin/io/unthrottled/doki/hax/HackComponent.kt index 4ce24f3bf..2f3ae25bb 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/HackComponent.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/HackComponent.kt @@ -38,7 +38,6 @@ object HackComponent : Disposable { enableBackgroundConsistency() enableSelectionConsistency() enableHintConsistency() - enableMarketplaceCompatability() } fun init() { @@ -48,10 +47,6 @@ object HackComponent : Disposable { hackReformatHintInfoForeground() } - private fun enableMarketplaceCompatability() { - hackSVGLoader() - } - private fun hackReformatHintInfoForeground() { runSafely({ val cp = ClassPool(true) @@ -134,31 +129,6 @@ object HackComponent : Disposable { } } - private fun hackSVGLoader() { - runSafely({ - val cp = ClassPool(true) - cp.insertClassPath( - ClassClassPath( - Class.forName("io.unthrottled.doki.hax.FieldHacker"), - ), - ) - val ctClass = cp.get("io.unthrottled.doki.hax.SvgLoaderHacker") - ctClass.replaceClassName( - "io.unthrottled.doki.hax.svg.setSelectionColorPatcherProvider", - "com.intellij.ui.svg.setSelectionColorPatcherProvider", - - ) - ctClass.replaceClassName( - "io.unthrottled.doki.hax.svg.SVGLoader", - "com.intellij.util.SVGLoader", - - ) - ctClass.toClass() - }) { - log.warn("Unable to hackSVGLoader for reasons.") - } - } - private fun hackParameterInfoBackground() { runSafely({ val cp = ClassPool(true) diff --git a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt index dce744571..a8b5cf579 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt @@ -1,15 +1,16 @@ package io.unthrottled.doki.hax -import io.unthrottled.doki.hax.svg.setSelectionColorPatcherProvider import io.unthrottled.doki.hax.svg.SVGLoader -//import com.intellij.ui.svg.setSelectionColorPatcherProvider -//import com.intellij.util.SVGLoader +import io.unthrottled.doki.hax.svg.SvgElementColorPatcherProvider import io.unthrottled.doki.icon.ColorPatcher import io.unthrottled.doki.service.PluginService import io.unthrottled.doki.themes.DokiTheme -import java.util.Optional +import io.unthrottled.doki.util.runSafely +import java.lang.reflect.InvocationHandler +import java.lang.reflect.Method +import java.lang.reflect.Proxy +import java.util.* -typealias PatcherProvider = SVGLoader.SvgElementColorPatcherProvider object SvgLoaderHacker { /** @@ -27,11 +28,41 @@ object SvgLoaderHacker { ColorPatcher.setDokiTheme(dokiTheme) - SVGLoader.colorPatcherProvider = ColorPatcher - setSelectionColorPatcherProvider(ColorPatcher) + runSafely({ + setHackedPatcher() + }) { + println(it) + } + } + + private fun setHackedPatcher() { + val handler = object : InvocationHandler { + val methods = ColorPatcher.javaClass.methods.map { it.name to it }.toMap() + override fun invoke(proxy: Any?, method: Method?, args: Array?): Any? { + if (method == null) return null + val firstOrNull = methods[method.name] + val args2 = args ?: emptyArray() + return firstOrNull?.invoke( + ColorPatcher, *args2 + ) + } + } + val forName = Class.forName("com.intellij.util.SVGLoader\$SvgElementColorPatcherProvider") + val proxyClass = Proxy.newProxyInstance( + forName.classLoader, + arrayOf(forName), + handler + ) + val svgLoader = Class.forName("com.intellij.util.SVGLoader") + val setPatcher = svgLoader.declaredMethods.firstOrNull { it.name == "setColorPatcherProvider" } + setPatcher?.invoke(null, proxyClass) + + val clazz = Class.forName("com.intellij.ui.svg.SvgKt") + val setPatcherProvdier = clazz.declaredMethods.firstOrNull { it.name == "setSelectionColorPatcherProvider" } + setPatcherProvdier?.invoke(null, proxyClass) } - private fun collectOtherPatcher(): Optional = + private fun collectOtherPatcher(): Optional = Optional.ofNullable( SVGLoader::class.java.declaredFields .firstOrNull { it.name == "colorPatcherProvider" }, @@ -40,10 +71,10 @@ object SvgLoaderHacker { ourColorPatcherField.isAccessible = true ourColorPatcherField.get(null) } - .filter { it is PatcherProvider } + .filter { it is SvgElementColorPatcherProvider } .filter { it !is ColorPatcher } .map { - val otherPatcher = it as PatcherProvider + val otherPatcher = it as SvgElementColorPatcherProvider otherPatcher } } diff --git a/src/main/kotlin/io/unthrottled/doki/hax/svg/MoreHax.kt b/src/main/kotlin/io/unthrottled/doki/hax/svg/MoreHax.kt deleted file mode 100644 index 669c240c4..000000000 --- a/src/main/kotlin/io/unthrottled/doki/hax/svg/MoreHax.kt +++ /dev/null @@ -1,3 +0,0 @@ -package io.unthrottled.doki.hax.svg - -public fun setSelectionColorPatcherProvider(colorPatcher: SVGLoader.SvgElementColorPatcherProvider?): kotlin.Unit {} \ No newline at end of file diff --git a/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgElementColorPatcherProvider.kt b/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgElementColorPatcherProvider.kt new file mode 100644 index 000000000..0c9ee4ccc --- /dev/null +++ b/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgElementColorPatcherProvider.kt @@ -0,0 +1,15 @@ +package io.unthrottled.doki.hax.svg + +import com.intellij.ui.svg.SvgAttributePatcher + +interface SvgElementColorPatcherProvider { + fun attributeForPath(path: String): SvgAttributePatcher? = null + + /** + * Returns a digest of the current SVG color patcher. + * + * Consider using a two-element array, where the first element is a hash of the input data for the patcher, + * and the second is an ID of the patcher (see [com.intellij.ui.icons.ColorPatcherIdGenerator]). + */ + fun digest(): LongArray +} \ No newline at end of file diff --git a/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgLoader.kt b/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgLoader.kt index fa8ae3a30..34ab28fe1 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgLoader.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgLoader.kt @@ -63,15 +63,5 @@ object SVGLoader { fun digest(): ByteArray? } - interface SvgElementColorPatcherProvider { - fun attributeForPath(path: String): SvgAttributePatcher? = null +} - /** - * Returns a digest of the current SVG color patcher. - * - * Consider using a two-element array, where the first element is a hash of the input data for the patcher, - * and the second is an ID of the patcher (see [com.intellij.ui.icons.ColorPatcherIdGenerator]). - */ - fun digest(): LongArray - } -} \ No newline at end of file diff --git a/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt b/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt index 40c787e5c..f0190b314 100644 --- a/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt +++ b/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt @@ -1,5 +1,6 @@ package io.unthrottled.doki.icon +import io.unthrottled.doki.hax.svg.SvgElementColorPatcherProvider import com.google.common.cache.Cache import com.google.common.cache.CacheBuilder import com.intellij.ide.ui.LafManager @@ -9,7 +10,6 @@ import com.intellij.ui.JBColor import com.intellij.ui.JBColor.namedColor import com.intellij.ui.svg.SvgAttributePatcher import com.intellij.util.io.DigestUtil -import io.unthrottled.doki.hax.PatcherProvider import io.unthrottled.doki.themes.DokiTheme import io.unthrottled.doki.themes.ThemeManager import io.unthrottled.doki.util.runSafely @@ -19,13 +19,14 @@ import io.unthrottled.doki.util.toOptional import java.awt.Color import java.time.Duration + object NoOptPatcher : SvgAttributePatcher { override fun patchColors(attributes: MutableMap) { } } val noOptPatcherProvider = - object : PatcherProvider { + object : SvgElementColorPatcherProvider { val longArray = longArrayOf(0) override fun digest(): LongArray { @@ -34,9 +35,9 @@ val noOptPatcherProvider = } @Suppress("TooManyFunctions") -object ColorPatcher : PatcherProvider { - private var otherColorPatcherProvider: PatcherProvider = noOptPatcherProvider - private var uiColorPatcherProvider: PatcherProvider = noOptPatcherProvider +object ColorPatcher : SvgElementColorPatcherProvider { + private var otherColorPatcherProvider: SvgElementColorPatcherProvider = noOptPatcherProvider + private var uiColorPatcherProvider: SvgElementColorPatcherProvider = noOptPatcherProvider private lateinit var dokiTheme: DokiTheme private val patcherProviderCache = HashSet() @@ -48,12 +49,12 @@ object ColorPatcher : PatcherProvider { .filter { it is UIThemeLookAndFeelInfoImpl } .map { it as UIThemeLookAndFeelInfoImpl } .ifPresent { - this.uiColorPatcherProvider = (it.theme.colorPatcher ?: noOptPatcherProvider) as PatcherProvider +// this.uiColorPatcherProvider = it.theme.colorPatcher ?: noOptPatcherProvider) } clearCaches() } - fun setOtherPatcher(otherPatcher: PatcherProvider) { + fun setOtherPatcher(otherPatcher: SvgElementColorPatcherProvider) { this.otherColorPatcherProvider = otherPatcher clearCaches() } From b46f422b158077ead20102f337d2133e4e8888f0 Mon Sep 17 00:00:00 2001 From: Alex Simons Date: Mon, 8 Jul 2024 20:30:15 -0500 Subject: [PATCH 09/13] =?UTF-8?q?The=20hax=CB=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gradle.properties | 4 +- .../io/unthrottled/doki/TheDokiTheme.kt | 3 +- .../unthrottled/doki/hax/SvgLoaderHacker.kt | 26 ------- .../io/unthrottled/doki/hax/svg/SvgLoader.kt | 67 ------------------- .../io/unthrottled/doki/icon/ColorPatcher.kt | 36 +++++++--- .../doki/themes/impl/ThemeManagerImpl.kt | 1 - 6 files changed, 30 insertions(+), 107 deletions(-) delete mode 100644 src/main/kotlin/io/unthrottled/doki/hax/svg/SvgLoader.kt diff --git a/gradle.properties b/gradle.properties index 8fb1af60a..2ea7cc08e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,12 +3,12 @@ pluginGroup=io.unthrottled pluginVersion=88.5-1.14.0 -pluginSinceBuild=233.8264.8 +pluginSinceBuild=241 pluginUntilBuild=242.* # Plugin Verifier integration -> https://github.com/JetBrains/gradle-intellij-plugin#plugin-verifier-dsl # See https://jb.gg/intellij-platform-builds-list for available build versions. -pluginVerifierIdeVersions = 2023.3.2, 2024.2 +pluginVerifierIdeVersions = 2024.1, 2024.2 platformType = IU platformVersion = LATEST-EAP-SNAPSHOT diff --git a/src/main/kotlin/io/unthrottled/doki/TheDokiTheme.kt b/src/main/kotlin/io/unthrottled/doki/TheDokiTheme.kt index e6e304213..e214dce6f 100644 --- a/src/main/kotlin/io/unthrottled/doki/TheDokiTheme.kt +++ b/src/main/kotlin/io/unthrottled/doki/TheDokiTheme.kt @@ -29,7 +29,8 @@ import io.unthrottled.doki.stickers.StickerPaneService import io.unthrottled.doki.themes.ThemeManager import io.unthrottled.doki.util.doOrElse import io.unthrottled.doki.util.toOptional -import java.util.* +import java.util.Optional +import java.util.UUID class TheDokiTheme : Disposable { companion object { diff --git a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt index a8b5cf579..1d089d115 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt @@ -1,7 +1,5 @@ package io.unthrottled.doki.hax -import io.unthrottled.doki.hax.svg.SVGLoader -import io.unthrottled.doki.hax.svg.SvgElementColorPatcherProvider import io.unthrottled.doki.icon.ColorPatcher import io.unthrottled.doki.service.PluginService import io.unthrottled.doki.themes.DokiTheme @@ -9,7 +7,6 @@ import io.unthrottled.doki.util.runSafely import java.lang.reflect.InvocationHandler import java.lang.reflect.Method import java.lang.reflect.Proxy -import java.util.* object SvgLoaderHacker { @@ -21,11 +18,6 @@ object SvgLoaderHacker { return } - collectOtherPatcher() - .ifPresent { otherPatcher -> - ColorPatcher.setOtherPatcher(otherPatcher) - } - ColorPatcher.setDokiTheme(dokiTheme) runSafely({ @@ -61,22 +53,4 @@ object SvgLoaderHacker { val setPatcherProvdier = clazz.declaredMethods.firstOrNull { it.name == "setSelectionColorPatcherProvider" } setPatcherProvdier?.invoke(null, proxyClass) } - - private fun collectOtherPatcher(): Optional = - Optional.ofNullable( - SVGLoader::class.java.declaredFields - .firstOrNull { it.name == "colorPatcherProvider" }, - ) - .map { ourColorPatcherField -> - ourColorPatcherField.isAccessible = true - ourColorPatcherField.get(null) - } - .filter { it is SvgElementColorPatcherProvider } - .filter { it !is ColorPatcher } - .map { - val otherPatcher = it as SvgElementColorPatcherProvider - otherPatcher - } } - - diff --git a/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgLoader.kt b/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgLoader.kt deleted file mode 100644 index 34ab28fe1..000000000 --- a/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgLoader.kt +++ /dev/null @@ -1,67 +0,0 @@ -package io.unthrottled.doki.hax.svg; - -import com.intellij.openapi.util.IconLoader -import com.intellij.ui.svg.* -import org.w3c.dom.Element -import java.awt.* -import java.awt.image.BufferedImage -import java.io.IOException -import java.io.InputStream -import java.net.URL -import kotlin.math.max - -private val iconMaxSize: Float by lazy { - var maxSize = Integer.MAX_VALUE.toFloat() - if (!GraphicsEnvironment.isHeadless()) { - val device = GraphicsEnvironment.getLocalGraphicsEnvironment().defaultScreenDevice - val bounds = device.defaultConfiguration.bounds - val tx = device.defaultConfiguration.defaultTransform - maxSize = max(bounds.width * tx.scaleX, bounds.height * tx.scaleY).toInt().toFloat() - } - maxSize -} - -/** - * Plugins should use [ImageLoader.loadFromResource]. - */ -object SVGLoader { - const val ICON_DEFAULT_SIZE: Int = 16 - - @Throws(IOException::class) - @JvmStatic - fun load(url: URL, scale: Float): Image { - return loadSvg(path = url.path, stream = url.openStream(), scale = scale, colorPatcherProvider = null) - } - - @Throws(IOException::class) - @JvmStatic - fun load(stream: InputStream, scale: Float): Image { - return loadSvg(path = null, stream = stream, scale = scale, colorPatcherProvider = null) - } - - @Throws(IOException::class) - fun load(url: URL?, stream: InputStream, scale: Float): BufferedImage { - return loadSvg(path = url?.path, stream = stream, scale = scale, colorPatcherProvider = null) - } - - @JvmStatic - var colorPatcherProvider: SvgElementColorPatcherProvider? = null - set(colorPatcher) { - field = colorPatcher - IconLoader.clearCache() - } - - @Deprecated("Please use SvgAttributePatcher") - @Suppress("unused") - interface SvgElementColorPatcher { - fun patchColors(svg: Element) { - } - - /** - * @return hash code of the current SVG color patcher or null to disable rendered SVG images caching - */ - fun digest(): ByteArray? - } - -} - diff --git a/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt b/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt index f0190b314..f13e8e047 100644 --- a/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt +++ b/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt @@ -1,15 +1,15 @@ package io.unthrottled.doki.icon -import io.unthrottled.doki.hax.svg.SvgElementColorPatcherProvider import com.google.common.cache.Cache import com.google.common.cache.CacheBuilder import com.intellij.ide.ui.LafManager -import com.intellij.ide.ui.laf.UIThemeLookAndFeelInfoImpl +import com.intellij.ide.ui.UITheme import com.intellij.ui.ColorUtil import com.intellij.ui.JBColor import com.intellij.ui.JBColor.namedColor import com.intellij.ui.svg.SvgAttributePatcher import com.intellij.util.io.DigestUtil +import io.unthrottled.doki.hax.svg.SvgElementColorPatcherProvider import io.unthrottled.doki.themes.DokiTheme import io.unthrottled.doki.themes.ThemeManager import io.unthrottled.doki.util.runSafely @@ -46,16 +46,32 @@ object ColorPatcher : SvgElementColorPatcherProvider { calculateAndSetNewDigest() LafManager.getInstance() ?.currentUIThemeLookAndFeel.toOptional() - .filter { it is UIThemeLookAndFeelInfoImpl } - .map { it as UIThemeLookAndFeelInfoImpl } - .ifPresent { -// this.uiColorPatcherProvider = it.theme.colorPatcher ?: noOptPatcherProvider) + .map { + it to it.javaClass.methods.firstOrNull { method -> method.name == "getTheme" } } - clearCaches() - } + .filter { it.second != null } + .ifPresent { + val themePatcher = ((it.second?.invoke(it.first)) as UITheme) + val javaClass = UITheme::class.java + val attr = javaClass.methods.firstOrNull { method -> method.name == "attributeForPath" } + val digest = javaClass.methods.firstOrNull { method -> method.name == "digest" } + this.uiColorPatcherProvider = object : SvgElementColorPatcherProvider { + override fun attributeForPath(path: String): SvgAttributePatcher? { + val invoke = attr?.invoke(digest, path) + return object : SvgAttributePatcher { + override fun patchColors(attributes: MutableMap) { + invoke?.javaClass + ?.methods?.firstOrNull { method -> method.name == "patchColors" } + ?.invoke(invoke, attributes) + } + } + } - fun setOtherPatcher(otherPatcher: SvgElementColorPatcherProvider) { - this.otherColorPatcherProvider = otherPatcher + override fun digest(): LongArray { + return digest?.invoke(themePatcher) as LongArray + } + } + } clearCaches() } diff --git a/src/main/kotlin/io/unthrottled/doki/themes/impl/ThemeManagerImpl.kt b/src/main/kotlin/io/unthrottled/doki/themes/impl/ThemeManagerImpl.kt index 351a4587f..b23fe1630 100644 --- a/src/main/kotlin/io/unthrottled/doki/themes/impl/ThemeManagerImpl.kt +++ b/src/main/kotlin/io/unthrottled/doki/themes/impl/ThemeManagerImpl.kt @@ -4,7 +4,6 @@ import com.google.gson.Gson import com.intellij.ide.ui.LafManager import com.intellij.ide.ui.laf.UIThemeLookAndFeelInfo import com.intellij.ide.ui.laf.UIThemeLookAndFeelInfoImpl -import com.intellij.util.io.inputStream import io.unthrottled.doki.TheDokiTheme import io.unthrottled.doki.themes.DokiTheme import io.unthrottled.doki.themes.JetBrainsThemeDefinition From 85bd8f7c77c26d5fe129d5a4633d785aad69f21d Mon Sep 17 00:00:00 2001 From: Alex Simons Date: Mon, 8 Jul 2024 20:33:37 -0500 Subject: [PATCH 10/13] Lazy get instance. --- src/main/kotlin/io/unthrottled/doki/stickers/MarginService.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/io/unthrottled/doki/stickers/MarginService.kt b/src/main/kotlin/io/unthrottled/doki/stickers/MarginService.kt index c7658708d..087b5dea4 100644 --- a/src/main/kotlin/io/unthrottled/doki/stickers/MarginService.kt +++ b/src/main/kotlin/io/unthrottled/doki/stickers/MarginService.kt @@ -16,8 +16,8 @@ class MarginService : Logging { private const val STICKER_Y_OFFSET = 0.05 private const val STICKER_X_OFFSET = 0.03 - val instance: MarginService = - ApplicationManager.getApplication().getService(MarginService::class.java) + val instance: MarginService + get() = ApplicationManager.getApplication().getService(MarginService::class.java) } private val gson = From b00abd66b6908e2efbf4fd5f8e22b8d46679ee28 Mon Sep 17 00:00:00 2001 From: Alex Simons Date: Tue, 9 Jul 2024 17:29:46 -0500 Subject: [PATCH 11/13] Safer code. --- .../unthrottled/doki/hax/SvgLoaderHacker.kt | 61 ++++++++++++------- .../hax/svg/SvgElementColorPatcherProvider.kt | 2 +- .../io/unthrottled/doki/icon/ColorPatcher.kt | 53 ++++++++++------ .../unthrottled/doki/service/PluginService.kt | 6 +- 4 files changed, 78 insertions(+), 44 deletions(-) diff --git a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt index 1d089d115..62e2df815 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt @@ -3,13 +3,15 @@ package io.unthrottled.doki.hax import io.unthrottled.doki.icon.ColorPatcher import io.unthrottled.doki.service.PluginService import io.unthrottled.doki.themes.DokiTheme +import io.unthrottled.doki.util.Logging +import io.unthrottled.doki.util.logger import io.unthrottled.doki.util.runSafely +import io.unthrottled.doki.util.runSafelyWithResult import java.lang.reflect.InvocationHandler import java.lang.reflect.Method import java.lang.reflect.Proxy - -object SvgLoaderHacker { +object SvgLoaderHacker : Logging { /** * Enables the ability to have more than one color patcher. */ @@ -23,34 +25,47 @@ object SvgLoaderHacker { runSafely({ setHackedPatcher() }) { - println(it) + logger().warn("Unable to set hacked patcher", it) } } private fun setHackedPatcher() { - val handler = object : InvocationHandler { - val methods = ColorPatcher.javaClass.methods.map { it.name to it }.toMap() - override fun invoke(proxy: Any?, method: Method?, args: Array?): Any? { - if (method == null) return null - val firstOrNull = methods[method.name] - val args2 = args ?: emptyArray() - return firstOrNull?.invoke( - ColorPatcher, *args2 - ) + val patcherProxyHandler = + object : InvocationHandler, Logging { + val associatedMethods = ColorPatcher.javaClass.methods.associateBy { it.name } + + override fun invoke( + proxy: Any?, + method: Method?, + arguments: Array?, + ): Any? { + if (method == null) return null + return runSafelyWithResult({ + val methodToInvoke = associatedMethods[method.name] + val usableArguments = arguments ?: emptyArray() + methodToInvoke?.invoke( + ColorPatcher, + *usableArguments, + ) + }) { + logger().warn("unable to invoke proxy handler method", it) + null + } + } } - } - val forName = Class.forName("com.intellij.util.SVGLoader\$SvgElementColorPatcherProvider") - val proxyClass = Proxy.newProxyInstance( - forName.classLoader, - arrayOf(forName), - handler - ) - val svgLoader = Class.forName("com.intellij.util.SVGLoader") - val setPatcher = svgLoader.declaredMethods.firstOrNull { it.name == "setColorPatcherProvider" } - setPatcher?.invoke(null, proxyClass) + val patcherProviderClass = Class.forName("com.intellij.util.SVGLoader\$SvgElementColorPatcherProvider") + val proxiedSVGElementColorProvider = + Proxy.newProxyInstance( + patcherProviderClass.classLoader, + arrayOf(patcherProviderClass), + patcherProxyHandler, + ) + val svgLoaderClass = Class.forName("com.intellij.util.SVGLoader") + val setPatcher = svgLoaderClass.declaredMethods.firstOrNull { it.name == "setColorPatcherProvider" } + setPatcher?.invoke(null, proxiedSVGElementColorProvider) val clazz = Class.forName("com.intellij.ui.svg.SvgKt") val setPatcherProvdier = clazz.declaredMethods.firstOrNull { it.name == "setSelectionColorPatcherProvider" } - setPatcherProvdier?.invoke(null, proxyClass) + setPatcherProvdier?.invoke(null, proxiedSVGElementColorProvider) } } diff --git a/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgElementColorPatcherProvider.kt b/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgElementColorPatcherProvider.kt index 0c9ee4ccc..e765d3b8a 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgElementColorPatcherProvider.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/svg/SvgElementColorPatcherProvider.kt @@ -12,4 +12,4 @@ interface SvgElementColorPatcherProvider { * and the second is an ID of the patcher (see [com.intellij.ui.icons.ColorPatcherIdGenerator]). */ fun digest(): LongArray -} \ No newline at end of file +} diff --git a/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt b/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt index f13e8e047..9343104ca 100644 --- a/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt +++ b/src/main/kotlin/io/unthrottled/doki/icon/ColorPatcher.kt @@ -12,6 +12,8 @@ import com.intellij.util.io.DigestUtil import io.unthrottled.doki.hax.svg.SvgElementColorPatcherProvider import io.unthrottled.doki.themes.DokiTheme import io.unthrottled.doki.themes.ThemeManager +import io.unthrottled.doki.util.Logging +import io.unthrottled.doki.util.logger import io.unthrottled.doki.util.runSafely import io.unthrottled.doki.util.runSafelyWithResult import io.unthrottled.doki.util.toHexString @@ -19,7 +21,6 @@ import io.unthrottled.doki.util.toOptional import java.awt.Color import java.time.Duration - object NoOptPatcher : SvgAttributePatcher { override fun patchColors(attributes: MutableMap) { } @@ -51,26 +52,44 @@ object ColorPatcher : SvgElementColorPatcherProvider { } .filter { it.second != null } .ifPresent { - val themePatcher = ((it.second?.invoke(it.first)) as UITheme) - val javaClass = UITheme::class.java - val attr = javaClass.methods.firstOrNull { method -> method.name == "attributeForPath" } - val digest = javaClass.methods.firstOrNull { method -> method.name == "digest" } - this.uiColorPatcherProvider = object : SvgElementColorPatcherProvider { - override fun attributeForPath(path: String): SvgAttributePatcher? { - val invoke = attr?.invoke(digest, path) - return object : SvgAttributePatcher { - override fun patchColors(attributes: MutableMap) { - invoke?.javaClass - ?.methods?.firstOrNull { method -> method.name == "patchColors" } - ?.invoke(invoke, attributes) + val theme = ((it.second?.invoke(it.first)) as UITheme) + val themeClass = UITheme::class.java + val themeClassMethods = themeClass.methods + val attr = themeClassMethods.firstOrNull { method -> method.name == "attributeForPath" } + val digest = themeClassMethods.firstOrNull { method -> method.name == "digest" } + this.uiColorPatcherProvider = + object : SvgElementColorPatcherProvider, Logging { + override fun attributeForPath(path: String): SvgAttributePatcher? { + return runSafelyWithResult({ + val patcherForPath = attr?.invoke(digest, path) + val patchColorsMethod = + patcherForPath?.javaClass + ?.methods?.firstOrNull { method -> method.name == "patchColors" } + object : SvgAttributePatcher { + override fun patchColors(attributes: MutableMap) { + runSafelyWithResult({ + patchColorsMethod + ?.invoke(patcherForPath, attributes) + }) { patchingError -> + logger().warn("unable to patch colors", patchingError) + } + } + } + }) { + logger().warn("Unable to patch path for raisins", it) + null } } - } - override fun digest(): LongArray { - return digest?.invoke(themePatcher) as LongArray + override fun digest(): LongArray { + return runSafelyWithResult({ + digest?.invoke(theme) as LongArray + }) { digestError -> + logger().warn("Unable to get digest", digestError) + longArrayOf() + } + } } - } } clearCaches() } diff --git a/src/main/kotlin/io/unthrottled/doki/service/PluginService.kt b/src/main/kotlin/io/unthrottled/doki/service/PluginService.kt index 8e68fea4b..5033ffde4 100644 --- a/src/main/kotlin/io/unthrottled/doki/service/PluginService.kt +++ b/src/main/kotlin/io/unthrottled/doki/service/PluginService.kt @@ -15,7 +15,7 @@ import io.unthrottled.doki.util.Logging import io.unthrottled.doki.util.logger import io.unthrottled.doki.util.runSafelyWithResult import io.unthrottled.doki.util.toOptional -import java.util.* +import java.util.Collections import java.util.concurrent.Callable const val MOTIVATOR_PLUGIN_ID = "zd.zero.waifu-motivator-plugin" @@ -89,8 +89,8 @@ object PluginService : Logging { CompatibleUpdateRequest( ApplicationInfo.getInstance() .build.asString(), - ids.map { it.idString } - ) + ids.map { it.idString }, + ), ) HttpRequests .post(Urls.newFromEncoded(COMPATIBLE_UPDATE_URL).toExternalForm(), HttpRequests.JSON_CONTENT_TYPE) From 8fdb935884a68066549df056e07a350708ed8cc0 Mon Sep 17 00:00:00 2001 From: Alex Simons Date: Tue, 9 Jul 2024 17:31:36 -0500 Subject: [PATCH 12/13] Moar lint. --- src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt index 62e2df815..06486a6cc 100644 --- a/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt +++ b/src/main/kotlin/io/unthrottled/doki/hax/SvgLoaderHacker.kt @@ -65,7 +65,7 @@ object SvgLoaderHacker : Logging { setPatcher?.invoke(null, proxiedSVGElementColorProvider) val clazz = Class.forName("com.intellij.ui.svg.SvgKt") - val setPatcherProvdier = clazz.declaredMethods.firstOrNull { it.name == "setSelectionColorPatcherProvider" } - setPatcherProvdier?.invoke(null, proxiedSVGElementColorProvider) + val setPatcherProvider = clazz.declaredMethods.firstOrNull { it.name == "setSelectionColorPatcherProvider" } + setPatcherProvider?.invoke(null, proxiedSVGElementColorProvider) } } From 1e7984dffbaf8fde441ac66d0560a296f9c7bcca Mon Sep 17 00:00:00 2001 From: Alex Simons Date: Tue, 9 Jul 2024 17:34:10 -0500 Subject: [PATCH 13/13] Bump version & changelog. --- changelog/CHANGELOG.md | 5 +++++ changelog/RELEASE-NOTES.md | 3 ++- gradle.properties | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/changelog/CHANGELOG.md b/changelog/CHANGELOG.md index 0d7b2226e..a5e33517f 100644 --- a/changelog/CHANGELOG.md +++ b/changelog/CHANGELOG.md @@ -1,5 +1,10 @@ Changelog --- +# 88.5-1.14.0 [Marketplace Support] + +- Added initial 2024.2 build support +- Should be able to be published to marketplace now. + # 88.5-1.13.0 [2024.1 Build Support] - Added initial 2024.1 build support diff --git a/changelog/RELEASE-NOTES.md b/changelog/RELEASE-NOTES.md index cd237f380..0114ea5ec 100644 --- a/changelog/RELEASE-NOTES.md +++ b/changelog/RELEASE-NOTES.md @@ -1 +1,2 @@ -- Added initial 2024.1 build support +- Added initial 2024.2 build support +- Should be able to be published to marketplace now. diff --git a/gradle.properties b/gradle.properties index 2ea7cc08e..5ea9548c6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,7 +11,7 @@ pluginUntilBuild=242.* pluginVerifierIdeVersions = 2024.1, 2024.2 platformType = IU -platformVersion = LATEST-EAP-SNAPSHOT +platformVersion = 2023.3.2 platformDownloadSources = true # Plugin Dependencies -> https://www.jetbrains.org/intellij/sdk/docs/basics/plugin_structure/plugin_dependencies.html # Example: platformPlugins = com.intellij.java,com.jetbrains.php:203.4449.22