diff --git a/src/main/kotlin/io/gitlab/jfronny/globalmenu/GlobalMenuService.kt b/src/main/kotlin/io/gitlab/jfronny/globalmenu/GlobalMenuService.kt
index 7b799b6..7825c02 100644
--- a/src/main/kotlin/io/gitlab/jfronny/globalmenu/GlobalMenuService.kt
+++ b/src/main/kotlin/io/gitlab/jfronny/globalmenu/GlobalMenuService.kt
@@ -1,38 +1,77 @@
package io.gitlab.jfronny.globalmenu
import com.canonical.appmenu.Registrar
+import com.intellij.ide.IdeEventQueue
+import com.intellij.openapi.Disposable
+import com.intellij.openapi.actionSystem.impl.ActionMenu
import com.intellij.openapi.application.Application
import com.intellij.openapi.application.ApplicationActivationListener
+import com.intellij.openapi.progress.runBlockingCancellable
+import com.intellij.openapi.util.Disposer
import com.intellij.openapi.wm.IdeFrame
import com.intellij.openapi.wm.impl.IdeFrameImpl
import com.intellij.openapi.wm.impl.ProjectFrameHelper
+import com.intellij.platform.ide.menu.IdeJMenuBar
import io.gitlab.jfronny.globalmenu.proxy.DbusmenuImpl
import io.gitlab.jfronny.globalmenu.proxy.SwingMenuHolder
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.runBlocking
import org.freedesktop.dbus.DBusPath
+import org.freedesktop.dbus.connections.impl.DBusConnection
import org.freedesktop.dbus.connections.impl.DBusConnectionBuilder
import org.freedesktop.dbus.types.UInt32
+import java.awt.Window
+import java.awt.event.KeyEvent
import javax.swing.JMenuBar
+import javax.swing.SwingUtilities
class GlobalMenuService(private val app: Application) : ApplicationActivationListener {
override fun applicationActivated(ideFrame: IdeFrame) {
super.applicationActivated(ideFrame)
if (!GlobalMenu.Native.isSupported) return
- ideFrame.project?.let { project ->
- println(ideFrame.javaClass)
- if (ideFrame is ProjectFrameHelper) {
- visualize(ideFrame.rootPane.jMenuBar, ideFrame.rootPane.peer)
- } else if (ideFrame is IdeFrameImpl) {
- visualize(ideFrame.jMenuBar, ideFrame.peer)
- }
- GlobalMenu.Log.warn("Activated: ${project.name}")
+ if (ideFrame is ProjectFrameHelper) {
+ visualize(ideFrame.rootPane.jMenuBar, ideFrame.rootPane.peer)
+ } else if (ideFrame is IdeFrameImpl) {
+ visualize(ideFrame.jMenuBar, ideFrame.peer)
}
}
- fun visualize(menu: JMenuBar, peer: Peer) {
- val conn = DBusConnectionBuilder.forSessionBus().build()
+ override fun applicationDeactivated(ideFrame: IdeFrame) {
+ lastMenu?.let { Disposer.dispose(it) }
+ }
+
+ private var lastMenu: Disposable? = null
+ private var connection: DBusConnection? = null
+
+ fun visualize(menu: JMenuBar, peer: Peer) = app.invokeLater {
+ lastMenu?.let { Disposer.dispose(it) }
+ lastMenu = Disposer.newDisposable()
+
+ val conn = connection ?: DBusConnectionBuilder.forSessionBus().build()
+ connection = conn
+
+ val menuHolder = SwingMenuHolder(menu, "DBusMenuRoot")
+ if (menu is IdeJMenuBar) {
+ menu.addUpdateGlobalMenuRootsListener {
+ menuHolder.update(menu.rootMenuItems)
+ }
+ menu.updateMenuActions(true)
+ }
+// IdeEventQueue.getInstance().addDispatcher({ e ->
+// if (e !is KeyEvent) false
+// else if (!e.isAltDown) false
+// else {
+// val src = e.component
+// val wndParent = if (src is Window) src else SwingUtilities.windowForComponent(src)
+// val eventChar = e.keyChar.uppercaseChar()
+//
+//
+// true
+// }
+// }, lastMenu!!)
val windowPtr = peer.nativePtr
- val menu = DbusmenuImpl(windowPtr, SwingMenuHolder(menu, "DBusMenuRoot"))
+ val menu = DbusmenuImpl(windowPtr, menuHolder)
conn.unExportObject(menu.objectPath)
conn.exportObject(menu)
diff --git a/src/main/kotlin/io/gitlab/jfronny/globalmenu/proxy/DbusmenuImpl.kt b/src/main/kotlin/io/gitlab/jfronny/globalmenu/proxy/DbusmenuImpl.kt
index 6b58ce7..91c8c73 100644
--- a/src/main/kotlin/io/gitlab/jfronny/globalmenu/proxy/DbusmenuImpl.kt
+++ b/src/main/kotlin/io/gitlab/jfronny/globalmenu/proxy/DbusmenuImpl.kt
@@ -2,6 +2,7 @@ package io.gitlab.jfronny.globalmenu.proxy
import com.canonical.*
import io.gitlab.jfronny.globalmenu.DPair
+import io.gitlab.jfronny.globalmenu.GlobalMenu
import org.freedesktop.dbus.types.UInt32
import org.freedesktop.dbus.types.Variant
@@ -65,9 +66,16 @@ class DbusmenuImpl(windowId: Long, private val menuHolder: MenuHolder) : Dbusmen
return properties
}
- override fun Event(id: Int, eventId: String?, data: Variant<*>?, timestamp: UInt32?) {
- if ("clicked".endsWith(eventId!!)) { //TODO this seems off
- menuHolder.find(id)?.onEvent()
+ override fun Event(id: Int, eventId: String, data: Variant<*>?, timestamp: UInt32?) {
+ GlobalMenu.Log.warn("Event $eventId for menu $id (${menuHolder.find(id)})")
+ try {
+ when (eventId) {
+ "clicked" -> menuHolder.find(id)?.onEvent()
+ "opened" -> menuHolder.find(id)?.update()
+ }
+ } catch (e: Exception) {
+ GlobalMenu.Log.error("Failed to handle event $eventId for menu $id", e)
+ throw e
}
}
diff --git a/src/main/kotlin/io/gitlab/jfronny/globalmenu/proxy/Menu.kt b/src/main/kotlin/io/gitlab/jfronny/globalmenu/proxy/Menu.kt
index f5ebb91..f9ce387 100644
--- a/src/main/kotlin/io/gitlab/jfronny/globalmenu/proxy/Menu.kt
+++ b/src/main/kotlin/io/gitlab/jfronny/globalmenu/proxy/Menu.kt
@@ -12,4 +12,5 @@ interface Menu {
val toggleState: Int
val children: List