feat: mess about with X
This commit is contained in:
parent
cce25ca383
commit
184ca19652
@ -1,10 +1,16 @@
|
|||||||
package io.gitlab.jfronny.globalmenu
|
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.Application
|
||||||
import com.intellij.openapi.application.ApplicationActivationListener
|
import com.intellij.openapi.application.ApplicationActivationListener
|
||||||
import com.intellij.openapi.wm.IdeFrame
|
import com.intellij.openapi.wm.IdeFrame
|
||||||
import com.intellij.openapi.wm.impl.IdeFrameImpl
|
import com.intellij.openapi.wm.impl.IdeFrameImpl
|
||||||
import com.intellij.openapi.wm.impl.ProjectFrameHelper
|
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
|
import javax.swing.JMenuBar
|
||||||
|
|
||||||
class GlobalMenuService(private val app: Application) : ApplicationActivationListener {
|
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}")
|
GlobalMenu.Log.warn("${submenu.text}.${component?.text}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
peer.performLocked {
|
val conn = DBusConnectionBuilder.forSessionBus().build()
|
||||||
val ptr = GlobalMenu.Native.create(peer.nativePtr)
|
|
||||||
// peer.registerCleaner {
|
val menu: Dbusmenu = DbusmenuImpl()
|
||||||
// GlobalMenu.Native.destroy(ptr)
|
// 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))
|
val Component.peer: Peer get() = Peer(peerField.get(this))
|
||||||
|
|
||||||
private val componentPeerClass = Class.forName("sun.awt.wl.WLComponentPeer")
|
sealed interface Peer {
|
||||||
private val performLockedMethod = Reflect.instanceProcedure(componentPeerClass, "performLocked", Runnable::class.java).unchecked1
|
val nativePtr: Long
|
||||||
private val nativePtrField = componentPeerClass.getDeclaredField("nativePtr").apply { setAccessible(this) }
|
}
|
||||||
|
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) {
|
companion object {
|
||||||
val nativePtr: Long get() = nativePtrField.getLong(inner)
|
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) {
|
fun performLocked(runnable: Runnable) {
|
||||||
performLockedMethod(inner, runnable)
|
performLockedMethod(inner, runnable)
|
||||||
}
|
}
|
||||||
fun registerCleaner(runnable: Runnable) {
|
fun registerCleaner(runnable: Runnable) {
|
||||||
GlobalMenu.Cleaner.register(this, 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")
|
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