feat: mess about with X

This commit is contained in:
Johannes Frohnmeyer 2024-07-20 10:52:49 +02:00
parent cce25ca383
commit 184ca19652
Signed by: Johannes
GPG Key ID: E76429612C2929F4
3 changed files with 101 additions and 10 deletions

View File

@ -1,10 +1,16 @@
package io.gitlab.jfronny.globalmenu
import com.canonical.Dbusmenu
import com.canonical.appmenu.Registrar
import com.intellij.openapi.application.Application
import com.intellij.openapi.application.ApplicationActivationListener
import com.intellij.openapi.wm.IdeFrame
import com.intellij.openapi.wm.impl.IdeFrameImpl
import com.intellij.openapi.wm.impl.ProjectFrameHelper
import io.gitlab.jfronny.globalmenu.proxy.DbusmenuImpl
import org.freedesktop.dbus.DBusPath
import org.freedesktop.dbus.connections.impl.DBusConnectionBuilder
import org.freedesktop.dbus.types.UInt32
import javax.swing.JMenuBar
class GlobalMenuService(private val app: Application) : ApplicationActivationListener {
@ -34,11 +40,20 @@ class GlobalMenuService(private val app: Application) : ApplicationActivationLis
GlobalMenu.Log.warn("${submenu.text}.${component?.text}")
}
}
val conn = DBusConnectionBuilder.forSessionBus().build()
val menu: Dbusmenu = DbusmenuImpl()
// firefox seems to use mObjectPath(nsPrintfCString("/com/canonical/menu/%u", sID++))
conn.exportObject("/com/canonical/dbusmenu", menu)
if (peer is WLPeer) {
peer.performLocked {
val ptr = GlobalMenu.Native.create(peer.nativePtr)
// peer.registerCleaner {
// GlobalMenu.Native.destroy(ptr)
// }
GlobalMenu.Native.setAddress(ptr, conn.uniqueName, menu.objectPath)
}
} else {
val registrar = conn.getRemoteObject("org.canonical.AppMenu.Registrar", "/com/canonical/AppMenu/Registrar", Registrar::class.java)
registrar.RegisterWindow(UInt32(peer.nativePtr), DBusPath(menu.objectPath))
}
}
}

View File

@ -15,18 +15,36 @@ private val peerField = Component::class.java.getDeclaredField("peer").apply { i
val Component.peer: Peer get() = Peer(peerField.get(this))
private val componentPeerClass = Class.forName("sun.awt.wl.WLComponentPeer")
private val performLockedMethod = Reflect.instanceProcedure(componentPeerClass, "performLocked", Runnable::class.java).unchecked1
private val nativePtrField = componentPeerClass.getDeclaredField("nativePtr").apply { setAccessible(this) }
sealed interface Peer {
val nativePtr: Long
}
fun Peer(peer: Any): Peer {
if (X11Peer.componentPeerClass.isInstance(peer)) return X11Peer(peer)
if (WLPeer.componentPeerClass.isInstance(peer)) return WLPeer(peer)
throw IllegalArgumentException("Unknown peer type: ${peer.javaClass}")
}
class X11Peer(private val inner: Any) : Peer {
override val nativePtr: Long get() = getPtrMethod(inner)
class Peer(private val inner: Any) {
val nativePtr: Long get() = nativePtrField.getLong(inner)
companion object {
val componentPeerClass = Class.forName("sun.awt.X11.XComponentPeer")
private val getPtrMethod = Reflect.instanceFunction(componentPeerClass, "getWindow", Long::class.java).unchecked
}
}
class WLPeer(private val inner: Any) : Peer {
override val nativePtr: Long get() = nativePtrField.getLong(inner)
fun performLocked(runnable: Runnable) {
performLockedMethod(inner, runnable)
}
fun registerCleaner(runnable: Runnable) {
GlobalMenu.Cleaner.register(this, runnable)
}
companion object {
val componentPeerClass = Class.forName("sun.awt.wl.WLComponentPeer")
private val performLockedMethod = Reflect.instanceProcedure(componentPeerClass, "performLocked", Runnable::class.java).unchecked1
private val nativePtrField = componentPeerClass.getDeclaredField("nativePtr").apply { setAccessible(this) }
}
}
private val wlDisplayClass = Class.forName("sun.awt.wl.WLDisplay")

View File

@ -0,0 +1,58 @@
package io.gitlab.jfronny.globalmenu.proxy
import com.canonical.*
import org.freedesktop.dbus.types.UInt32
import org.freedesktop.dbus.types.Variant
class DbusmenuImpl : Dbusmenu {
override fun getObjectPath(): String {
TODO("Not yet implemented")
}
override fun getVersion(): UInt32 {
TODO("Not yet implemented")
}
override fun getTextDirection(): String {
TODO("Not yet implemented")
}
override fun getStatus(): String {
TODO("Not yet implemented")
}
override fun getIconThemePath(): Dbusmenu.PropertyIconThemePathType {
TODO("Not yet implemented")
}
override fun GetLayout(parentId: Int, recursionDepth: Int, propertyNames: MutableList<String>?): GetLayoutTuple {
TODO("Not yet implemented")
}
override fun GetGroupProperties(
ids: MutableList<Int>?,
propertyNames: MutableList<String>?
): MutableList<GetGroupPropertiesStruct> {
TODO("Not yet implemented")
}
override fun GetProperty(id: Int, name: String?): Variant<*> {
TODO("Not yet implemented")
}
override fun Event(id: Int, eventId: String?, data: Variant<*>?, timestamp: UInt32?) {
TODO("Not yet implemented")
}
override fun EventGroup(events: MutableList<EventGroupStruct>?): MutableList<Int> {
TODO("Not yet implemented")
}
override fun AboutToShow(id: Int): Boolean {
TODO("Not yet implemented")
}
override fun AboutToShowGroup(ids: MutableList<Int>?): AboutToShowGroupTuple {
TODO("Not yet implemented")
}
}