Skip to content

Instantly share code, notes, and snippets.

@adrientetar
Created March 19, 2025 02:12
Show Gist options
  • Save adrientetar/b039998a0752261d2ee7db9ade3e7c15 to your computer and use it in GitHub Desktop.
Save adrientetar/b039998a0752261d2ee7db9ade3e7c15 to your computer and use it in GitHub Desktop.
Custom title bar in Compose Multiplatform with JBR runtime. Updated for the new WindowDecorations API. known JBR 17 old version: b1207.30 new version: b1367.22
import sun.misc.Unsafe
import java.awt.Frame
import java.lang.reflect.AccessibleObject
import java.lang.reflect.Method
/**
* Access custom window decoration functions in the JetBrains Runtime.
*
* Original code: <https://github.com/ButterCam/compose-jetbrains-theme/blob/main/expui/src/main/kotlin/io/kanro/compose/jetbrains/expui/util/CustomWindowDecorationAccessing.kt>
* Updated for new WindowDecorations JBR API: <https://android.googlesource.com/platform/external/jetbrains/JetBrainsRuntime/+/a8a5398a738fab3daa559874e779faad9c85e746%5E%21/#F24>
*/
object WindowDecorations {
init {
UnsafeAccess.assignAccessibility(
UnsafeAccess.desktopModule,
listOf("java.awt")
)
}
private val windowDecorationsInstance: Any? = try {
val windowDecorations = Class.forName(windowDecorationsClassName)
val constructor = windowDecorations.declaredConstructors.first()
constructor.isAccessible = true
constructor.newInstance()
} catch (e: Exception) {
null
}
private val createCustomTitleBarMethod: Method? =
getMethod("createCustomTitleBar")
private val setHeightMethod: Method? =
getCustomTitleBarMethod("setHeight", Float::class.java)
private fun getMethod(name: String, vararg params: Class<*>): Method? {
return try {
val clazz = Class.forName(windowDecorationsClassName)
val method = clazz.getDeclaredMethod(name, *params)
method.isAccessible = true
method
} catch (e: Exception) {
null
}
}
private fun getCustomTitleBarMethod(name: String, vararg params: Class<*>): Method? {
return try {
val clazz = Class.forName(customTitleBarClassName)
val method = clazz.getDeclaredMethod(name, *params)
method.isAccessible = true
method
} catch (e: Exception) {
null
}
}
/**
* Disable the system title bar for the provided [frame] - only retain the window controls,
* centered around the provided [height].
*
* @return `true` if the custom title bar was set successfully, `false` otherwise.
*/
fun setCustomTitleBar(frame: Frame, height: Float): Boolean {
val windowDecorations = windowDecorationsInstance ?: return false
// Create custom title bar
val customTitleBar = run {
val method = createCustomTitleBarMethod ?: return false
method.invoke(windowDecorations) ?: return false
}
// Set the height
val setHeightMethod = setHeightMethod ?: return false
setHeightMethod.invoke(customTitleBar, height)
// Set custom title bar
val setCustomTitleBarMethod = getMethod(
"setCustomTitleBar", Frame::class.java, customTitleBar::class.java
) ?: return false
setCustomTitleBarMethod.invoke(windowDecorations, frame, customTitleBar)
return true
}
}
private const val windowDecorationsClassName = "java.awt.Window\$WindowDecorations"
private const val customTitleBarClassName = "java.awt.Window\$CustomTitleBar"
private object UnsafeAccess {
private val unsafe: Any? by lazy {
try {
val theUnsafe = Unsafe::class.java.getDeclaredField("theUnsafe")
theUnsafe.isAccessible = true
theUnsafe.get(null) as Unsafe
} catch (e: Throwable) {
null
}
}
val desktopModule by lazy {
ModuleLayer.boot().findModule("java.desktop").get()
}
val ownerModule by lazy {
this.javaClass.module
}
private val isAccessibleFieldOffset: Long? by lazy {
try {
(unsafe as? Unsafe)?.objectFieldOffset(Parent::class.java.getDeclaredField("first"))
} catch (e: Throwable) {
null
}
}
private val implAddOpens by lazy {
try {
Module::class.java.getDeclaredMethod(
"implAddOpens", String::class.java, Module::class.java
).accessible()
} catch (e: Throwable) {
null
}
}
fun assignAccessibility(obj: AccessibleObject) {
try {
val theUnsafe = unsafe as? Unsafe ?: return
val offset = isAccessibleFieldOffset ?: return
theUnsafe.putBooleanVolatile(obj, offset, true)
} catch (e: Throwable) {
// ignore
}
}
fun assignAccessibility(module: Module, packages: List<String>) {
try {
packages.forEach {
implAddOpens?.invoke(module, it, ownerModule)
}
} catch (e: Throwable) {
// ignore
}
}
private class Parent {
var first = false
@Volatile
var second: Any? = null
}
}
private fun <T : AccessibleObject> T.accessible(): T {
return apply {
UnsafeAccess.assignAccessibility(this)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment