Menu icon indicating copy to clipboard operation
Menu copied to clipboard

Make global menu work for JetBrains (Java) applications

Open probonopd opened this issue 5 years ago • 21 comments

Make global menu work for JetBrains (Java) applications: bring the contents of (1) into (2). This will also make the commands searchable via the search field in the global menu and the system-wide ⌘+Space, which large IDEs like the ones from JetBrains would benefit from.

image

How?

image

probonopd avatar Dec 30 '20 10:12 probonopd

https://youtrack.jetbrains.com/issue/IDEA-169904

IntelliJ 2020.1.4 is last version global menu supported

rilian commented on 2020-11-15 10:23

Jetbrains apps does not need jayatana. They support appmenus natively.

Possibly helpful

  • https://issuetracker.google.com/iassues/121304907
  • https://aur.archlinux.org/packages/vala-panel-appmenu-jayatana-git/

probonopd avatar Dec 30 '20 10:12 probonopd

Maybe it is a good idea to check that issue https://youtrack.jetbrains.com/issue/IDEA-169904

alexandreliberato avatar Dec 31 '20 00:12 alexandreliberato

Installing libdbusmenu pkg did not seem to make any difference.

LD_DEBUG=libs truss /usr/local/bin/pycharm-ce 2>&1 | grep menu

outputs nothing, indicating that no files/libraries with "menu" in their name are even attempted to be opened...

probonopd avatar Dec 31 '20 10:12 probonopd

Also see https://github.com/rilian-la-te/vala-panel-appmenu#experimental-features

JAyatana allows for displaying global menus in Java Swing applications. Because Vala-Panel-Appmenu uses the unity-gtk-module backend, this should theoretically work with JAyatana, although applications such as Netbeans and the JetBrains suite of IDEs require some configuration, which you can figure out with a cursory internet search.

probonopd avatar Dec 31 '20 11:12 probonopd

JetBrains IntelliJ code refers to Global Menu in this commit. So can it be enabled in JetBrains IDEs? How?

probonopd avatar Nov 03 '21 17:11 probonopd

Watching the output of dbus-monitor, I can't see jetBrains PyCharm to send any menu information via D-Bus. Maybe it is checking for some condition which helloSystem does not meet (yet) and hence doesn't even attempt to send menu information via D-Bus?

Yet somewhere deep inside there is AppMenu related code:

FreeBSD% grep -r AppMenu /usr/local/share/pycharm-ce/ 
Binary file /usr/local/share/pycharm-ce/lib/platform-impl.jar matches

FreeBSD% grep -r GlobalMenu /usr/local/share/pycharm-ce/                      
Binary file /usr/local/share/pycharm-ce/lib/platform-impl.jar matches
Binary file /usr/local/share/pycharm-ce/lib/resources.jar matches

FreeBSD% strings /usr/local/share/pycharm-ce/lib/platform-impl.jar | grep AppMenu
5Closed dbus-service 'com.canonical.AppMenu.Registrar'
7Appeared dbus-service 'com.canonical.AppMenu.Registrar'
$AppMenu-service can't register xid 
doBindAppMenuOfParent
installAppMenuIfNeeded
doInstallAppMenuIfNeeded
com/intellij/openapi/wm/impl/LinuxIdeMenuBar$Companion$doBindAppMenuOfParent$1.class
Ncom/intellij/openapi/wm/impl/LinuxIdeMenuBar$Companion$doBindAppMenuOfParent$1
doBindAppMenuOfParent
PLcom/intellij/openapi/wm/impl/LinuxIdeMenuBar$Companion$doBindAppMenuOfParent$1;
doBindAppMenuOfParent
Ncom/intellij/openapi/wm/impl/LinuxIdeMenuBar$Companion$doBindAppMenuOfParent$1
doInstallAppMenuIfNeeded
doBindAppMenuOfParent
installAppMenuIfNeeded
installAppMenuIfNeeded
installAppMenuIfNeeded
com/intellij/openapi/wm/impl/LinuxIdeMenuBar$Companion$doBindAppMenuOfParent$1.classPK

This code seems to be related: https://github.com/JetBrains/intellij-community/search?q=GlobalMenuLinux

And especially: https://github.com/JetBrains/intellij-community/blob/584913b212d4e92347d9b925f2f417fcc0dee439/platform/platform-impl/src/com/intellij/openapi/wm/impl/GlobalMenuLinux.java#L790

    if (!SystemInfo.isLinux ||

Can it really be that they hardcoded the global menu not to show if the platform is not Linux, effectively disabling the global menu on BSD, even though all prerequisites are met?

Is this something that could be changed by e.g., using LD_PRELOAD?

probonopd avatar Nov 23 '21 09:11 probonopd

This should be fixed upstream. Can we do something in the meantime?

Assuming we could get com/intellij/openapi/wm/impl/GlobalMenuLinux.class inside /usr/local/share/pycharm-ce/lib/platform-impl.jar patched so that it doesn't check for Linux by the virtues of something like https://jdec.app/, is there a way to get it loaded instead of the one in the jar?

https://www.py4u.net/discuss/632477 says:

Write your own class in the same package as the original one, make sure your classes are before the 3-rd party jar on the java classpath. This way you will override the original version, class loader will load your class.

mkdir -p /tmp/com/intellij/openapi/wm/impl/patch/
cp GlobalMenuLinux.class /tmp/patch/com/intellij/openapi/wm/impl/patch/
FreeBSD% /usr/local/openjdk12//bin/java -classpath /tmp/:/usr/local/share/pycharm-ce/lib/bootstrap.jar:/usr/local/share/pycharm-ce/lib/util.jar:/usr/local/share/pycharm-ce/lib/jdom.jar:/usr/local/share/pycharm-ce/lib/log4j.jar:/usr/local/share/pycharm-ce/lib/jna.jar -Xms128m -Xmx1258m -XX:ReservedCodeCacheSize=240m -XX:+UseConcMarkSweepGC -XX:SoftRefLRUPolicyMSPerMB=50 -ea -XX:CICompilerCount=2 -Dsun.io.useCanonPrefixCache=false -Djdk.http.auth.tunneling.disabledSchemes="" -XX:+HeapDumpOnOutOfMemoryError -XX:-OmitStackTraceInFastThrow -Djdk.attach.allowAttachSelf=true -Dkotlinx.coroutines.debug=off -Djdk.module.illegalAccess.silent=true -Dawt.useSystemAAFontSettings=lcd -Dsun.java2d.renderer=sun.java2d.marlin.MarlinRenderingEngine -Dsun.tools.attach.tmp.only=true -XX:ErrorFile=/home/user/java_error_in_pycharm_%p.log -XX:HeapDumpPath=/home/user/java_error_in_pycharm_.hprof -Didea.vendor.name=JetBrains -Didea.paths.selector=PyCharmCE2021.1 -Djb.vmOptionsFile=/home/user/.config/JetBrains/PyCharmCE2021.1/pycharm64.vmoptions -Didea.platform.prefix=PyCharmCore com.intellij.idea.Main

We are up to something? @jsm222 what do you think?

probonopd avatar Nov 23 '21 10:11 probonopd

Upstream ticket opened: https://youtrack.jetbrains.com/issue/PY-51727

probonopd avatar Nov 23 '21 10:11 probonopd

Upstream doesn't want to make this change "without any testing". Even though I am sure FreeBSD users would be happy to test.

If we knew what syscall is used by SystemInfo.isLinux, we could possibly overwrite it using LD_PRELOAD...

probonopd avatar Aug 06 '23 13:08 probonopd

They are definitely running uname, but the following does not do the trick - there may be more to it. I was hoping that by changing the output of uname we could trick SystemInfo.isLinux, but it is not entirely clear whether this succeeded. We need to see whether we can get global menus to work with any Java application that uses the same GUI toolkit as Jetbrains.

sudo mv /usr/bin/uname /usr/bin/uname.original

Then create and make executable the following script as /usr/bin/uname:

#!/bin/bash

echo ""
echo "Script name: $0" >> /tmp/info
echo "Number of arguments: $#" >> /tmp/info
echo "Arguments: $@" >> /tmp/info

/usr/bin/uname.disabled "$@" | sed  -e 's|FreeBSD|Linux|g'

By looking at /tmp/info after running a JetBrains IDE we see the accesses.

probonopd avatar Aug 06 '23 15:08 probonopd

I remember using Xubuntu with xfce4-appmenu-plugin a couple of years ago and the JetBrains IDE (PHPStorm) was working with a global menu.

osbre avatar Sep 05 '23 12:09 osbre

They hardcoded the global menu not to show if the platform is not Linux, effectively disabling the global menu on BSD, even though all prerequisites are met.

probonopd avatar Sep 06 '23 18:09 probonopd

Trying to understand their reasoning for doing that. Would it mean that once removed it could break their macOS and Windows versions?

Perhaps in this case they have to invert it from : !SystemInfo.isLinux to: (pseudocode) !(SystemInfo.isWindows || SystemInfo.isDarwin)

And also, they have the word "Linux" all over the place in that implementation. Out of curiosity, what the proper name would be? (for example, GlobalMenuDbus instead of GlobalMenuLinux?)

osbre avatar Sep 06 '23 18:09 osbre

Out of curiosity, what the proper name would be?

Great question.

This stuff is under-documented and under-specified. https://github.com/unity8-team/libdbusmenu-qt calls it the "DBusMenu protocol".

The specification used to be at https://people.canonical.com/~agateau/dbusmenu/spec/index.html but the link is dead as of 2020. On https://agateau.com/2009/statusnotifieritem-and-dbusmenu/ it is described as: "The goal of DBusMenu is to make it possible for applications using the StatusNotifierItem spec to send their menus over DBus, so that the workspace can display them in a consistent way, regardless of whether the application is written using Qt, GTK or another toolkit."

Here is a collection of what information I could gather so far: https://hellosystem.github.io/docs/developer/menu

probonopd avatar Sep 06 '23 18:09 probonopd

Trying to understand their reasoning for doing that. Would it mean that once removed it could break their macOS and Windows versions?

I also think we will be missing this linux blob https://github.com/JetBrains/intellij-community/blob/584913b212d4e92347d9b925f2f417fcc0dee439/bin/linux/libdbm64.so UPDATE perhaps not Update Update they do not ship a FreeBSD version of that lib.. But It might be portable from intellij-community-202.7660/native/LinuxGlobalMenu

jsm222 avatar Sep 06 '23 20:09 jsm222

IntelliJ 2020.1.4 is last version global menu supported

I tested on Linux with helloSystem's Menu, and 2023.2 intellij-ce gets global menus.. Now I only have left to hack and build the source..

jsm222 avatar Sep 07 '23 15:09 jsm222

Okay after a lot of stack tracing and building jna and intelij froms source and sqlite and libdb.so and jetbrains fork of libdbusmenu... ideangmenu

I will share the details later...

jsm222 avatar Sep 10 '23 00:09 jsm222

WOW, this is awesome!

probonopd avatar Sep 10 '23 06:09 probonopd

I will share the details later...

Some of them are here https://youtrack.jetbrains.com/issue/IDEA-283161

jsm222 avatar Sep 10 '23 14:09 jsm222

@jsm222 Very cool. Is it possible to submit that git-diff as a PR and they would accept it?

osbre avatar Sep 10 '23 15:09 osbre

@jsm222 Very cool. Is it possible to submit that git-diff as a PR and they would accept it?

https://github.com/JetBrains/intellij-community/pull/2571

I will share the details later...

Here are the rest of the details https://github.com/jsm222/LinuxGlobalMenu

jsm222 avatar Sep 10 '23 23:09 jsm222