feat: utilize Disposer to free memory

This commit is contained in:
Johannes Frohnmeyer 2024-07-22 12:16:21 +02:00
parent f674d44f96
commit bdf576602b
Signed by: Johannes
GPG Key ID: E76429612C2929F4
4 changed files with 45 additions and 18 deletions

View File

@ -13,7 +13,7 @@ struct WLFrame {
struct org_kde_kwin_appmenu_manager *org_kde_kwin_appmenu_manager = NULL; struct org_kde_kwin_appmenu_manager *org_kde_kwin_appmenu_manager = NULL;
static void registry_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { static void registry_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) {
if (strcmp(interface, "org_kde_kwin_appmenu_manager") == 0) { if (strcmp(interface, org_kde_kwin_appmenu_manager_interface.name) == 0) {
org_kde_kwin_appmenu_manager = wl_registry_bind(registry, name, &org_kde_kwin_appmenu_manager_interface, 1); org_kde_kwin_appmenu_manager = wl_registry_bind(registry, name, &org_kde_kwin_appmenu_manager_interface, 1);
} }
} }
@ -42,7 +42,7 @@ JNIEXPORT void JNICALL Java_io_gitlab_jfronny_globalmenu_Native_init(JNIEnv *env
} }
} }
JNIEXPORT jlong JNICALL Java_io_gitlab_jfronny_globalmenu_Native_create(JNIEnv *env, jobject obj, jlong ptr) { JNIEXPORT jlong JNICALL Java_io_gitlab_jfronny_globalmenu_Native_createMenu(JNIEnv *env, jobject obj, jlong ptr) {
if (org_kde_kwin_appmenu_manager == NULL) { if (org_kde_kwin_appmenu_manager == NULL) {
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/RuntimeException"), "Appmenu manager not initialized"); (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/RuntimeException"), "Appmenu manager not initialized");
return 0; return 0;
@ -51,13 +51,13 @@ JNIEXPORT jlong JNICALL Java_io_gitlab_jfronny_globalmenu_Native_create(JNIEnv *
return (jlong) (intptr_t) org_kde_kwin_appmenu_manager_create(org_kde_kwin_appmenu_manager, frame->wl_surface); return (jlong) (intptr_t) org_kde_kwin_appmenu_manager_create(org_kde_kwin_appmenu_manager, frame->wl_surface);
} }
JNIEXPORT void JNICALL Java_io_gitlab_jfronny_globalmenu_Native_destroy(JNIEnv *env, jobject obj, jlong ptr) { JNIEXPORT void JNICALL Java_io_gitlab_jfronny_globalmenu_Native_destroyMenu(JNIEnv *env, jobject obj, jlong ptr) {
struct org_kde_kwin_appmenu *frame = (struct org_kde_kwin_appmenu *) ptr; struct org_kde_kwin_appmenu *frame = (struct org_kde_kwin_appmenu *) ptr;
org_kde_kwin_appmenu_release(frame); org_kde_kwin_appmenu_release(frame);
org_kde_kwin_appmenu_destroy(frame); org_kde_kwin_appmenu_destroy(frame);
} }
JNIEXPORT void JNICALL Java_io_gitlab_jfronny_globalmenu_Native_setAddress(JNIEnv *env, jobject obj, jlong ptr, jstring serviceName, jstring objectPath) { JNIEXPORT void JNICALL Java_io_gitlab_jfronny_globalmenu_Native_setMenuAddress(JNIEnv *env, jobject obj, jlong ptr, jstring serviceName, jstring objectPath) {
struct org_kde_kwin_appmenu *frame = (struct org_kde_kwin_appmenu *) ptr; struct org_kde_kwin_appmenu *frame = (struct org_kde_kwin_appmenu *) ptr;
char *service_name = (*env)->GetStringUTFChars(env, serviceName, NULL); char *service_name = (*env)->GetStringUTFChars(env, serviceName, NULL);
char *object_path = (*env)->GetStringUTFChars(env, objectPath, NULL); char *object_path = (*env)->GetStringUTFChars(env, objectPath, NULL);

View File

@ -7,9 +7,14 @@ import java.util.Optional;
public class Native { public class Native {
public native void init(long displayPtr); public native void init(long displayPtr);
public native long create(long ptr);
public native void destroy(long ptr); public native long createMenu(long ptr);
public native void setAddress(long ptr, String serviceName, String objectPath); public native void destroyMenu(long ptr);
public native void setMenuAddress(long ptr, String serviceName, String objectPath);
public native long createDecoration(long ptr);
public native void destroyDecoration(long ptr);
public native void setDecoration(long ptr, int mode); // 0 = no preference, 1 = client side, 2 = server side
private static final String problem; private static final String problem;
static { static {
@ -17,6 +22,8 @@ public class Native {
problem = "Not running on Linux"; problem = "Not running on Linux";
} else if (!System.getProperty("os.arch").equals("amd64")) { } else if (!System.getProperty("os.arch").equals("amd64")) {
problem = "Not running on amd64"; problem = "Not running on amd64";
} else if (System.getProperty("io.gitlab.jfronny.globalmenu.disable") != null) {
problem = "Explicitly disabled";
} else { } else {
try (InputStream is = Native.class.getResourceAsStream("/libnative.so")) { try (InputStream is = Native.class.getResourceAsStream("/libnative.so")) {
Path path = Files.createTempFile("libnative", ".so"); Path path = Files.createTempFile("libnative", ".so");

View File

@ -22,11 +22,23 @@ class GlobalMenuService(private val app: Application) : ApplicationActivationLis
override fun applicationActivated(ideFrame: IdeFrame) { override fun applicationActivated(ideFrame: IdeFrame) {
super.applicationActivated(ideFrame) super.applicationActivated(ideFrame)
if (!GlobalMenu.Native.isSupported) return if (!GlobalMenu.Native.isSupported) return
if (!GMSettings.getInstance().state.menu) return val peer: Peer
if (ideFrame is ProjectFrameHelper) { val menuBar: JMenuBar
visualize(ideFrame.rootPane.jMenuBar, ideFrame.rootPane.peer) when (ideFrame) {
} else if (ideFrame is IdeFrameImpl) { is ProjectFrameHelper -> {
visualize(ideFrame.jMenuBar, ideFrame.peer) peer = ideFrame.rootPane.peer
menuBar = ideFrame.rootPane.jMenuBar
}
is IdeFrameImpl -> {
peer = ideFrame.peer
menuBar = ideFrame.jMenuBar
}
else -> return
}
if (GMSettings.getInstance().state.menu) addGlobalMenu(menuBar, peer)
else connection?.unExportObject(DbusmenuImpl.getMenuPath(peer.nativePtr))
if (GMSettings.getInstance().state.decorations) {
} }
} }
@ -37,7 +49,7 @@ class GlobalMenuService(private val app: Application) : ApplicationActivationLis
private var lastMenu: Disposable? = null private var lastMenu: Disposable? = null
private var connection: DBusConnection? = null private var connection: DBusConnection? = null
fun visualize(menu: JMenuBar, peer: Peer) = app.invokeLater { private fun addGlobalMenu(menu: JMenuBar, peer: Peer) = app.invokeLater {
lastMenu?.let { Disposer.dispose(it) } lastMenu?.let { Disposer.dispose(it) }
lastMenu = Disposer.newDisposable() lastMenu = Disposer.newDisposable()
@ -51,6 +63,7 @@ class GlobalMenuService(private val app: Application) : ApplicationActivationLis
} }
// menu.updateMenuActions(true) // menu.updateMenuActions(true)
} }
//TODO handle keybindings
// IdeEventQueue.getInstance().addDispatcher({ e -> // IdeEventQueue.getInstance().addDispatcher({ e ->
// if (e !is KeyEvent) false // if (e !is KeyEvent) false
// else if (!e.isAltDown) false // else if (!e.isAltDown) false
@ -66,17 +79,20 @@ class GlobalMenuService(private val app: Application) : ApplicationActivationLis
val windowPtr = peer.nativePtr val windowPtr = peer.nativePtr
val menu = DbusmenuImpl(windowPtr, menuHolder) val menu = DbusmenuImpl(windowPtr, menuHolder)
conn.unExportObject(menu.objectPath) val objectPath = menu.objectPath
conn.exportObject(menu) conn.exportObject(menu)
Disposer.register(lastMenu!!) { conn.unExportObject(objectPath) }
if (peer is WLPeer) { if (peer is WLPeer) {
peer.performLocked { peer.performLocked {
val ptr = GlobalMenu.Native.create(windowPtr) val ptr = GlobalMenu.Native.createMenu(windowPtr)
GlobalMenu.Native.setAddress(ptr, conn.uniqueName, menu.objectPath) Disposer.register(lastMenu!!) { GlobalMenu.Native.destroyMenu(ptr) }
GlobalMenu.Native.setMenuAddress(ptr, conn.uniqueName, objectPath)
} }
} else { } else {
val registrar = conn.getRemoteObject("org.canonical.AppMenu.Registrar", "/com/canonical/AppMenu/Registrar", Registrar::class.java) val registrar = conn.getRemoteObject("org.canonical.AppMenu.Registrar", "/com/canonical/AppMenu/Registrar", Registrar::class.java)
registrar.RegisterWindow(UInt32(windowPtr), DBusPath(menu.objectPath)) registrar.RegisterWindow(UInt32(windowPtr), DBusPath(objectPath))
Disposer.register(lastMenu!!) { registrar.UnregisterWindow(UInt32(windowPtr)) }
} }
} }
} }

View File

@ -7,7 +7,7 @@ import org.freedesktop.dbus.types.UInt32
import org.freedesktop.dbus.types.Variant import org.freedesktop.dbus.types.Variant
class DbusmenuImpl(windowId: Long, private val menuHolder: MenuHolder) : Dbusmenu { class DbusmenuImpl(windowId: Long, private val menuHolder: MenuHolder) : Dbusmenu {
private val menuPath: String = "/com/canonical/menu0x${windowId.toString(16)}" private val menuPath: String = getMenuPath(windowId)
override fun getObjectPath(): String = menuPath override fun getObjectPath(): String = menuPath
// override fun getVersion(): UInt32 = UInt32(3) // override fun getVersion(): UInt32 = UInt32(3)
// override fun getTextDirection(): String = "none" // override fun getTextDirection(): String = "none"
@ -97,4 +97,8 @@ class DbusmenuImpl(windowId: Long, private val menuHolder: MenuHolder) : Dbusmen
} }
override fun AboutToShowGroup(ids: MutableList<Int>?): DPair<MutableList<Int>, MutableList<Int>>? = null // not needed? override fun AboutToShowGroup(ids: MutableList<Int>?): DPair<MutableList<Int>, MutableList<Int>>? = null // not needed?
companion object {
fun getMenuPath(windowId: Long): String = "/com/canonical/menu0x${windowId.toString(16)}"
}
} }