feat: mess about with X
This commit is contained in:
parent
cce25ca383
commit
184ca19652
@ -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}")
|
||||
}
|
||||
}
|
||||
peer.performLocked {
|
||||
val ptr = GlobalMenu.Native.create(peer.nativePtr)
|
||||
// peer.registerCleaner {
|
||||
// GlobalMenu.Native.destroy(ptr)
|
||||
// }
|
||||
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)
|
||||
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))
|
||||
}
|
||||
}
|
||||
}
|
@ -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")
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user