feat: initial experimentation
This commit is contained in:
commit
9c7ca4aaa1
40
.gitignore
vendored
Normal file
40
.gitignore
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
.gradle
|
||||
build/
|
||||
!gradle/wrapper/gradle-wrapper.jar
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
out/
|
||||
!**/src/main/**/out/
|
||||
!**/src/test/**/out/
|
||||
.intellijPlatform
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
bin/
|
||||
!**/src/main/**/bin/
|
||||
!**/src/test/**/bin/
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
24
.run/Run IDE with Plugin.run.xml
Normal file
24
.run/Run IDE with Plugin.run.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Run Plugin" type="GradleRunConfiguration" factoryName="Gradle">
|
||||
<log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log"/>
|
||||
<ExternalSystemSettings>
|
||||
<option name="executionName"/>
|
||||
<option name="externalProjectPath" value="$PROJECT_DIR$"/>
|
||||
<option name="externalSystemIdString" value="GRADLE"/>
|
||||
<option name="scriptParameters" value=""/>
|
||||
<option name="taskDescriptions">
|
||||
<list/>
|
||||
</option>
|
||||
<option name="taskNames">
|
||||
<list>
|
||||
<option value="runIde"/>
|
||||
</list>
|
||||
</option>
|
||||
<option name="vmOptions" value=""/>
|
||||
</ExternalSystemSettings>
|
||||
<ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
|
||||
<ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
|
||||
<DebugAllEnabled>false</DebugAllEnabled>
|
||||
<method v="2"/>
|
||||
</configuration>
|
||||
</component>
|
3
README.md
Normal file
3
README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# References
|
||||
- [the removal commit](https://github.com/JetBrains/intellij-community/commit/336265215c1ae9bf9fd7f9c23ebfabc8fc810743)
|
||||
- [a swing menu library](https://github.com/Vitaliy-Yakovchuk/dbusmenu-swing)
|
76
build.gradle.kts
Normal file
76
build.gradle.kts
Normal file
@ -0,0 +1,76 @@
|
||||
plugins {
|
||||
java
|
||||
kotlin("jvm") version "1.9.24"
|
||||
id("org.jetbrains.intellij.platform") version "2.0.0-beta9"
|
||||
}
|
||||
|
||||
group = "io.gitlab.jfronny"
|
||||
version = "1.0-SNAPSHOT"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://maven.frohnmeyer-wds.de/artifacts")
|
||||
|
||||
intellijPlatform {
|
||||
defaultRepositories()
|
||||
}
|
||||
}
|
||||
|
||||
val extraResources by configurations.creating
|
||||
|
||||
dependencies {
|
||||
intellijPlatform {
|
||||
intellijIdeaCommunity("242.20224.91")
|
||||
instrumentationTools()
|
||||
}
|
||||
implementation("io.gitlab.jfronny:commons-unsafe:2.0.0-SNAPSHOT")
|
||||
extraResources(project(mapOf("path" to ":native", "configuration" to "results")))
|
||||
}
|
||||
|
||||
val copyExtraResources by tasks.creating(Copy::class) {
|
||||
from(extraResources)
|
||||
into(layout.buildDirectory.dir("extraResources"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
resources {
|
||||
this.srcDir(copyExtraResources)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class RunToolTask : AbstractExecTask<RunToolTask>(RunToolTask::class.java) {
|
||||
@get:InputFile abstract val inputFile: RegularFileProperty
|
||||
@get:OutputFile abstract val outputFile: RegularFileProperty
|
||||
}
|
||||
|
||||
tasks {
|
||||
// Set the JVM compatibility versions
|
||||
withType<JavaCompile> {
|
||||
sourceCompatibility = "21"
|
||||
targetCompatibility = "21"
|
||||
}
|
||||
withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
||||
kotlinOptions.jvmTarget = "21"
|
||||
}
|
||||
|
||||
patchPluginXml {
|
||||
sinceBuild.set("242")
|
||||
untilBuild.set("243.*")
|
||||
}
|
||||
|
||||
signPlugin {
|
||||
certificateChain.set(System.getenv("CERTIFICATE_CHAIN"))
|
||||
privateKey.set(System.getenv("PRIVATE_KEY"))
|
||||
password.set(System.getenv("PRIVATE_KEY_PASSWORD"))
|
||||
}
|
||||
|
||||
publishPlugin {
|
||||
token.set(System.getenv("PUBLISH_TOKEN"))
|
||||
}
|
||||
|
||||
runIde {
|
||||
this.jvmArgs("-Dawt.toolkit.name=WLToolkit")
|
||||
}
|
||||
}
|
6
gradle.properties
Normal file
6
gradle.properties
Normal file
@ -0,0 +1,6 @@
|
||||
# Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib
|
||||
kotlin.stdlib.default.dependency=false
|
||||
# Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html
|
||||
org.gradle.configuration-cache=false
|
||||
# Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html
|
||||
org.gradle.caching=true
|
78
native/build.gradle.kts
Normal file
78
native/build.gradle.kts
Normal file
@ -0,0 +1,78 @@
|
||||
import org.gradle.internal.jvm.Jvm
|
||||
|
||||
plugins {
|
||||
`cpp-library`
|
||||
}
|
||||
|
||||
group = rootProject.group
|
||||
version = rootProject.version
|
||||
|
||||
abstract class RunToolTask : AbstractExecTask<RunToolTask>(RunToolTask::class.java) {
|
||||
@get:InputFile abstract val inputFile: RegularFileProperty
|
||||
@get:OutputFile abstract val outputFile: RegularFileProperty
|
||||
}
|
||||
|
||||
library {
|
||||
binaries.configureEach {
|
||||
val compileTask = compileTask.get()
|
||||
val dir = "${Jvm.current().javaHome}/include"
|
||||
compileTask.includes.from(dir)
|
||||
|
||||
val osFamily = targetPlatform.targetMachine.operatingSystemFamily
|
||||
if (osFamily.isMacOs) compileTask.includes.from("$dir/darwin")
|
||||
else if (osFamily.isLinux) compileTask.includes.from("$dir/linux")
|
||||
else if (osFamily.isWindows) compileTask.includes.from("$dir/win32")
|
||||
|
||||
compileTask.source.from(fileTree(mapOf("dir" to "src/main/c", "include" to "**/*.c")))
|
||||
compileTask.source.from(fileTree(mapOf("dir" to layout.buildDirectory.dir("generated"), "include" to "**/*.c")))
|
||||
compileTask.includes.from(layout.buildDirectory.dir("generated"))
|
||||
|
||||
if (toolChain is VisualCpp) {
|
||||
compileTask.compilerArgs.addAll("/TC")
|
||||
} else if (toolChain is GccCompatibleToolChain) {
|
||||
compileTask.compilerArgs.addAll("-x", "c", "-std=c11")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val results by configurations.creating {
|
||||
isCanBeConsumed = true
|
||||
isCanBeResolved = false
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
// val jar by tasks.creating(Jar::class) {
|
||||
// destinationDirectory = layout.buildDirectory
|
||||
// archiveClassifier.set("native")
|
||||
// dependsOn()
|
||||
// from()
|
||||
// }
|
||||
artifacts {
|
||||
add("results", layout.buildDirectory.file("lib/main/release/libnative.so")) {
|
||||
builtBy(tasks.named("assembleRelease"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
val generateAppmenuHeader by registering(RunToolTask::class) {
|
||||
group = "custom"
|
||||
inputFile = file("src/main/protocols/appmenu.xml")
|
||||
outputFile = layout.buildDirectory.file("generated/appmenu.h")
|
||||
commandLine("wayland-scanner", "client-header", inputFile.asFile.get().absolutePath, outputFile.asFile.get().absolutePath)
|
||||
}
|
||||
val generateAppmenuGlue by registering(RunToolTask::class) {
|
||||
group = "custom"
|
||||
inputFile = file("src/main/protocols/appmenu.xml")
|
||||
outputFile = layout.buildDirectory.file("generated/appmenu.c")
|
||||
commandLine("wayland-scanner", "private-code", inputFile.asFile.get().absolutePath, outputFile.asFile.get().absolutePath)
|
||||
}
|
||||
afterEvaluate {
|
||||
named("compileDebugCpp") {
|
||||
dependsOn(generateAppmenuHeader, generateAppmenuGlue)
|
||||
}
|
||||
named("compileReleaseCpp") {
|
||||
dependsOn(generateAppmenuHeader, generateAppmenuGlue)
|
||||
}
|
||||
}
|
||||
}
|
67
native/src/main/c/native.c
Normal file
67
native/src/main/c/native.c
Normal file
@ -0,0 +1,67 @@
|
||||
#include <jni.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "wayland-client-protocol.h"
|
||||
#include "appmenu.h"
|
||||
|
||||
struct WLFrame {
|
||||
jobject pad1;
|
||||
struct wl_surface *wl_surface;
|
||||
// more stuff follows, but we don't care about it
|
||||
};
|
||||
|
||||
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) {
|
||||
if (strcmp(interface, "org_kde_kwin_appmenu_manager") == 0) {
|
||||
org_kde_kwin_appmenu_manager = wl_registry_bind(registry, name, &org_kde_kwin_appmenu_manager_interface, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void registry_global_remove(void *data, struct wl_registry *registry, uint32_t name) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
static const struct wl_registry_listener wl_registry_listener = {
|
||||
.global = registry_global,
|
||||
.global_remove = registry_global_remove,
|
||||
};
|
||||
|
||||
JNIEXPORT void JNICALL Java_io_gitlab_jfronny_globalmenu_Native_init(JNIEnv *env, jobject obj, jlong ptr) {
|
||||
struct wl_display *wl_display = (struct wl_display *) ptr;
|
||||
struct wl_registry *wl_registry = wl_display_get_registry(wl_display);
|
||||
if (wl_registry == NULL) {
|
||||
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/RuntimeException"), "Failed to get registry");
|
||||
return;
|
||||
}
|
||||
|
||||
wl_registry_add_listener(wl_registry, &wl_registry_listener, NULL);
|
||||
if (wl_display_roundtrip(wl_display) < 0) {
|
||||
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/RuntimeException"), "Failed to roundtrip");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_io_gitlab_jfronny_globalmenu_Native_create(JNIEnv *env, jobject obj, jlong ptr) {
|
||||
if (org_kde_kwin_appmenu_manager == NULL) {
|
||||
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/RuntimeException"), "Appmenu manager not initialized");
|
||||
return 0;
|
||||
}
|
||||
struct WLFrame *frame = (struct WLFrame *) ptr;
|
||||
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) {
|
||||
struct org_kde_kwin_appmenu *frame = (struct org_kde_kwin_appmenu *) ptr;
|
||||
org_kde_kwin_appmenu_release(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) {
|
||||
struct org_kde_kwin_appmenu *frame = (struct org_kde_kwin_appmenu *) ptr;
|
||||
char *service_name = (*env)->GetStringUTFChars(env, serviceName, NULL);
|
||||
char *object_path = (*env)->GetStringUTFChars(env, objectPath, NULL);
|
||||
org_kde_kwin_appmenu_set_address(frame, service_name, object_path);
|
||||
(*env)->ReleaseStringUTFChars(env, serviceName, service_name);
|
||||
(*env)->ReleaseStringUTFChars(env, objectPath, object_path);
|
||||
}
|
35
native/src/main/protocols/appmenu.xml
Normal file
35
native/src/main/protocols/appmenu.xml
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<protocol name="appmenu">
|
||||
<copyright><![CDATA[
|
||||
SPDX-FileCopyrightText: 2017 David Edmundson
|
||||
SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
]]></copyright>
|
||||
<interface name="org_kde_kwin_appmenu_manager" version="1">
|
||||
<description summary="appmenu dbus address interface">
|
||||
This interface allows a client to link a window (or wl_surface) to an com.canonical.dbusmenu
|
||||
interface registered on DBus.
|
||||
</description>
|
||||
<request name="create">
|
||||
<arg name="id" type="new_id" interface="org_kde_kwin_appmenu"/>
|
||||
<arg name="surface" type="object" interface="wl_surface"/>
|
||||
</request>
|
||||
</interface>
|
||||
<interface name="org_kde_kwin_appmenu" version="1">
|
||||
<description summary="appmenu dbus address interface">
|
||||
The DBus service name and object path where the appmenu interface is present
|
||||
The object should be registered on the session bus before sending this request.
|
||||
If not applicable, clients should remove this object.
|
||||
</description>
|
||||
<request name="set_address">
|
||||
<description summary="initialise or update the location of the AppMenu interface">
|
||||
Set or update the service name and object path.
|
||||
Strings should be formatted in Latin-1 matching the relevant DBus specifications.
|
||||
</description>
|
||||
<arg name="service_name" type="string" />
|
||||
<arg name="object_path" type="string" />
|
||||
</request>
|
||||
<request name="release" type="destructor">
|
||||
<description summary="release the appmenu object"/>
|
||||
</request>
|
||||
</interface>
|
||||
</protocol>
|
10
settings.gradle.kts
Normal file
10
settings.gradle.kts
Normal file
@ -0,0 +1,10 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "globalmenu"
|
||||
|
||||
include("native")
|
26
src/main/java/io/gitlab/jfronny/globalmenu/Native.java
Normal file
26
src/main/java/io/gitlab/jfronny/globalmenu/Native.java
Normal file
@ -0,0 +1,26 @@
|
||||
package io.gitlab.jfronny.globalmenu;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class Native {
|
||||
public native void init(long displayPtr);
|
||||
public native long create(long ptr);
|
||||
public native void destroy(long ptr);
|
||||
public native void setAddress(long ptr, String serviceName, String objectPath);
|
||||
|
||||
static {
|
||||
if (System.getProperty("os.name").toLowerCase().contains("linux")) {
|
||||
try (InputStream is = Native.class.getResourceAsStream("/libnative.so")) {
|
||||
Path path = Files.createTempFile("libnative", ".so");
|
||||
Files.copy(is, path, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
|
||||
System.load(path.toString());
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("Linux is required for the global menu plugin");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package io.gitlab.jfronny.globalmenu
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
|
||||
object GlobalMenu {
|
||||
val Log: Logger = Logger.getInstance(GlobalMenu::class.java)
|
||||
val Native = Native()
|
||||
val Cleaner = java.lang.ref.Cleaner.create()
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package io.gitlab.jfronny.globalmenu
|
||||
|
||||
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 javax.swing.JMenuBar
|
||||
|
||||
class GlobalMenuService(private val app: Application) : ApplicationActivationListener {
|
||||
override fun applicationActivated(ideFrame: IdeFrame) {
|
||||
super.applicationActivated(ideFrame)
|
||||
ideFrame.project?.let { project ->
|
||||
println(ideFrame.javaClass)
|
||||
if (ideFrame is ProjectFrameHelper) {
|
||||
// ideFrame.frame.jMenuBar = JMenuBar()
|
||||
// ideFrame.rootPane.jMenuBar
|
||||
visualize(ideFrame.rootPane.jMenuBar, ideFrame.rootPane.peer)
|
||||
} else if (ideFrame is IdeFrameImpl) {
|
||||
visualize(ideFrame.jMenuBar, ideFrame.peer)
|
||||
}
|
||||
GlobalMenu.Log.warn("Activated: ${project.name}")
|
||||
}
|
||||
}
|
||||
|
||||
fun visualize(menu: JMenuBar, peer: Peer) {
|
||||
GlobalMenu.Log.warn("Using peer: $peer")
|
||||
//TODO send to compositor
|
||||
for (i in 0 until menu.menuCount) {
|
||||
val submenu = menu.getMenu(i)
|
||||
for (j in 0 until submenu.itemCount) {
|
||||
val component = submenu.getItem(j)
|
||||
GlobalMenu.Log.warn("${submenu.text}.${component?.text}")
|
||||
}
|
||||
}
|
||||
peer.performLocked {
|
||||
val ptr = GlobalMenu.Native.create(peer.nativePtr)
|
||||
// peer.registerCleaner {
|
||||
// GlobalMenu.Native.destroy(ptr)
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package io.gitlab.jfronny.globalmenu
|
||||
|
||||
import com.intellij.ide.AppLifecycleListener
|
||||
|
||||
class InitializationComponent : AppLifecycleListener {
|
||||
override fun appFrameCreated(commandLineArgs: MutableList<String>) {
|
||||
GlobalMenu.Native.init(getDisplayPtr())
|
||||
}
|
||||
}
|
14
src/main/kotlin/io/gitlab/jfronny/globalmenu/Lambda.kt
Normal file
14
src/main/kotlin/io/gitlab/jfronny/globalmenu/Lambda.kt
Normal file
@ -0,0 +1,14 @@
|
||||
package io.gitlab.jfronny.globalmenu
|
||||
|
||||
import java.util.function.BiConsumer
|
||||
import java.util.function.BiFunction
|
||||
import java.util.function.Function
|
||||
import java.util.function.Supplier
|
||||
|
||||
val <T, R> Function<T, R>.unchecked: Function<Any, R> get() = Function { it: Any -> apply(it as T) }
|
||||
val <T1, T2> BiConsumer<T1, T2>.unchecked1: BiConsumer<Any, T2> get() = BiConsumer { t1: Any, t2: T2 -> accept(t1 as T1, t2) }
|
||||
operator fun Runnable.invoke() = run()
|
||||
operator fun <T> Supplier<T>.invoke() = get()
|
||||
operator fun <T, R> Function<T, R>.invoke(t: T): R = apply(t)
|
||||
operator fun <T1, T2, R> BiFunction<T1, T2, R>.invoke(t1: T1, t2: T2): R = apply(t1, t2)
|
||||
operator fun <T1, T2> BiConsumer<T1, T2>.invoke(t1: T1, t2: T2) = accept(t1, t2)
|
38
src/main/kotlin/io/gitlab/jfronny/globalmenu/Reflect.kt
Normal file
38
src/main/kotlin/io/gitlab/jfronny/globalmenu/Reflect.kt
Normal file
@ -0,0 +1,38 @@
|
||||
package io.gitlab.jfronny.globalmenu
|
||||
|
||||
import io.gitlab.jfronny.commons.unsafe.reflect.Reflect
|
||||
import io.gitlab.jfronny.commons.unsafe.reflect.impl.CoreReflect
|
||||
import java.awt.Component
|
||||
import java.lang.reflect.AccessibleObject
|
||||
import java.lang.reflect.Field
|
||||
|
||||
private val accessibleSetter = CoreReflect.lookup(AccessibleObject::class.java).findSetter(AccessibleObject::class.java, "override", Boolean::class.java)
|
||||
private fun setAccessible(field: Field) {
|
||||
accessibleSetter.invoke(field, true)
|
||||
}
|
||||
|
||||
private val peerField = Component::class.java.getDeclaredField("peer").apply { isAccessible = true }
|
||||
|
||||
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) }
|
||||
|
||||
class Peer(private val inner: Any) {
|
||||
val nativePtr: Long get() = nativePtrField.getLong(inner)
|
||||
fun performLocked(runnable: Runnable) {
|
||||
performLockedMethod(inner, runnable)
|
||||
}
|
||||
fun registerCleaner(runnable: Runnable) {
|
||||
GlobalMenu.Cleaner.register(this, runnable)
|
||||
}
|
||||
}
|
||||
|
||||
private val wlDisplayClass = Class.forName("sun.awt.wl.WLDisplay")
|
||||
private val getInstanceMethod = Reflect.staticFunction(wlDisplayClass, "getInstance", wlDisplayClass)
|
||||
private val getDisplayPtrMethod = Reflect.instanceFunction(wlDisplayClass, "getDisplayPtr", Long::class.java).unchecked
|
||||
fun getDisplayPtr(): Long {
|
||||
val display = getInstanceMethod()
|
||||
return getDisplayPtrMethod(display) as Long
|
||||
}
|
32
src/main/resources/META-INF/plugin.xml
Normal file
32
src/main/resources/META-INF/plugin.xml
Normal file
@ -0,0 +1,32 @@
|
||||
<!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
|
||||
<idea-plugin>
|
||||
<!-- Unique identifier of the plugin. It should be FQN. It cannot be changed between the plugin versions. -->
|
||||
<id>io.gitlab.jfronny.globalmenu</id>
|
||||
|
||||
<!-- Public plugin name should be written in Title Case.
|
||||
Guidelines: https://plugins.jetbrains.com/docs/marketplace/plugin-overview-page.html#plugin-name -->
|
||||
<name>Global Menu</name>
|
||||
|
||||
<!-- A displayed Vendor name or Organization ID displayed on the Plugins Page. -->
|
||||
<vendor email="projects.contact@frohnmeyer-wds.de" url="https://jfronny.gitlab.io">JFronny</vendor>
|
||||
|
||||
<!-- Description of the plugin displayed on the Plugin Page and IDE Plugin Manager.
|
||||
Simple HTML elements (text formatting, paragraphs, and lists) can be added inside of <![CDATA[ ]]> tag.
|
||||
Guidelines: https://plugins.jetbrains.com/docs/marketplace/plugin-overview-page.html#plugin-description -->
|
||||
<description><![CDATA[
|
||||
Reenables the global menu on Linux systems.
|
||||
]]></description>
|
||||
|
||||
<!-- Product and plugin compatibility requirements.
|
||||
Read more: https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html -->
|
||||
<depends>com.intellij.modules.platform</depends>
|
||||
|
||||
<!-- Extension points defined by the plugin.
|
||||
Read more: https://plugins.jetbrains.com/docs/intellij/plugin-extension-points.html -->
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
</extensions>
|
||||
<applicationListeners>
|
||||
<listener class="io.gitlab.jfronny.globalmenu.GlobalMenuService" topic="com.intellij.openapi.application.ApplicationActivationListener"/>
|
||||
<listener class="io.gitlab.jfronny.globalmenu.InitializationComponent" topic="com.intellij.ide.AppLifecycleListener"/>
|
||||
</applicationListeners>
|
||||
</idea-plugin>
|
12
src/main/resources/META-INF/pluginIcon.svg
Normal file
12
src/main/resources/META-INF/pluginIcon.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M32.0845 7.94025V4H24.0203V7.9896H16.029V4H7.91553V7.94025H4V36H16.0044V32.0045C16.0058 30.9457 16.4274 29.9308 17.1766 29.1826C17.9258 28.4345 18.9412 28.0143 20 28.0143C21.0588 28.0143 22.0743 28.4345 22.8234 29.1826C23.5726 29.9308 23.9942 30.9457 23.9956 32.0045V36H36V7.94025H32.0845Z"
|
||||
fill="url(#paint0_linear)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear" x1="2.94192" y1="4.89955" x2="37.7772" y2="39.7345"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0.15937" stop-color="#3BEA62"/>
|
||||
<stop offset="0.5404" stop-color="#3C99CC"/>
|
||||
<stop offset="0.93739" stop-color="#6B57FF"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 818 B |
Loading…
Reference in New Issue
Block a user