feat: implement SSD support
This commit is contained in:
parent
97f47569fd
commit
4ab1cc9a6b
@ -15,7 +15,6 @@ struct WLFrame {
|
||||
void *pad5;
|
||||
void *pad6;
|
||||
void *pad7;
|
||||
void *pad8;
|
||||
jboolean toplevel;
|
||||
union {
|
||||
struct xdg_toplevel *xdg_toplevel;
|
||||
@ -101,6 +100,10 @@ JNIEXPORT jlong JNICALL Java_io_gitlab_jfronny_globalmenu_Native_createDecoratio
|
||||
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/RuntimeException"), "Not a toplevel");
|
||||
return 0;
|
||||
}
|
||||
if (frame->xdg_toplevel == NULL) {
|
||||
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/RuntimeException"), "No xdg_toplevel extracted");
|
||||
return 0;
|
||||
}
|
||||
return (jlong) (intptr_t) zxdg_decoration_manager_v1_get_toplevel_decoration(zxdg_decoration_manager_v1, frame->xdg_toplevel);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import com.canonical.appmenu.Registrar
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.Application
|
||||
import com.intellij.openapi.application.ApplicationActivationListener
|
||||
import com.intellij.openapi.application.ApplicationManager
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.openapi.wm.IdeFrame
|
||||
import com.intellij.openapi.wm.impl.IdeFrameImpl
|
||||
@ -16,6 +17,10 @@ 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.Dimension
|
||||
import java.awt.Window
|
||||
import javax.swing.FocusManager
|
||||
import javax.swing.JFrame
|
||||
import javax.swing.JMenuBar
|
||||
|
||||
class GlobalMenuService(private val app: Application) : ApplicationActivationListener {
|
||||
@ -23,22 +28,44 @@ class GlobalMenuService(private val app: Application) : ApplicationActivationLis
|
||||
super.applicationActivated(ideFrame)
|
||||
if (!GlobalMenu.Native.isSupported) return
|
||||
val peer: Peer
|
||||
val menuBar: JMenuBar
|
||||
val menuBar: JMenuBar?
|
||||
val frame: JFrame
|
||||
GlobalMenu.Log.warn(ideFrame.toString())
|
||||
when (ideFrame) {
|
||||
is ProjectFrameHelper -> {
|
||||
peer = ideFrame.rootPane.peer
|
||||
menuBar = ideFrame.rootPane.jMenuBar
|
||||
frame = ideFrame.frame
|
||||
}
|
||||
is IdeFrameImpl -> {
|
||||
peer = ideFrame.peer
|
||||
menuBar = ideFrame.jMenuBar
|
||||
frame = ideFrame
|
||||
}
|
||||
else -> return
|
||||
}
|
||||
if (GlobalMenu.Native.isMenuSupported && GMSettings.getInstance().state.menu) addGlobalMenu(menuBar, peer)
|
||||
else connection?.unExportObject(DbusmenuImpl.getMenuPath(peer.nativePtr))
|
||||
if (GlobalMenu.Native.isDecorationSupported && GMSettings.getInstance().state.decorations) {
|
||||
onActivate(peer, frame, menuBar)
|
||||
}
|
||||
|
||||
private fun onActivate(peer: Peer, frame: Window, menuBar: JMenuBar?) {
|
||||
if (GlobalMenu.Native.isMenuSupported && GMSettings.getInstance().state.menu && menuBar != null) addGlobalMenu(menuBar, peer)
|
||||
else connection?.unExportObject(DbusmenuImpl.getMenuPath(peer.nativePtr))
|
||||
if (GlobalMenu.Native.isDecorationSupported && GMSettings.getInstance().state.decorations && peer is WLPeer) {
|
||||
if (peer.decorated) {
|
||||
// Disable client-side decorations and enable server-side decorations
|
||||
peer.decorated = false
|
||||
frame.size = Dimension(frame.width, frame.height + 1)
|
||||
val decoration = GlobalMenu.Native.createDecoration(peer.nativePtr)
|
||||
// Disposer.register(lastMenu!!) { GlobalMenu.Native.destroyDecoration(decoration)
|
||||
GlobalMenu.Native.setDecoration(decoration, 2)
|
||||
}
|
||||
}
|
||||
ApplicationManager.getApplication().invokeLater {
|
||||
val frame1 = FocusManager.getCurrentManager().focusedWindow
|
||||
if (frame != frame1) onActivate(frame1.peer, frame1, when (frame1) {
|
||||
is JFrame -> frame1.jMenuBar
|
||||
else -> null
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
package io.gitlab.jfronny.globalmenu
|
||||
|
||||
import java.util.function.BiConsumer
|
||||
import java.util.function.BiFunction
|
||||
import java.util.function.*
|
||||
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 <T> Consumer<T>.unchecked: Consumer<Any> get() = Consumer { accept(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)
|
||||
operator fun <T1, T2> BiConsumer<T1, T2>.invoke(t1: T1, t2: T2) = accept(t1, t2)
|
||||
operator fun <T> Consumer<T>.invoke(t: T) = accept(t)
|
@ -3,6 +3,7 @@ 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.awt.Insets
|
||||
import java.lang.reflect.AccessibleObject
|
||||
import java.lang.reflect.Field
|
||||
|
||||
@ -42,14 +43,25 @@ class WLPeer(private val inner: Any) : Peer {
|
||||
fun performLocked(runnable: Runnable) {
|
||||
performLockedMethod(inner, runnable)
|
||||
}
|
||||
fun registerCleaner(runnable: Runnable) {
|
||||
GlobalMenu.Cleaner.register(this, runnable)
|
||||
}
|
||||
var decorated: Boolean
|
||||
get() = containerPeerClass.isInstance(inner) && getInsetsMethod(inner).top > 0
|
||||
set(value) {
|
||||
val decoration = decorationField.get(inner)
|
||||
isUndecoratedField.setBoolean(decoration, !value)
|
||||
markRepaintNeededMethod(decoration)
|
||||
}
|
||||
|
||||
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 containerPeerClass = Class.forName("java.awt.peer.ContainerPeer")
|
||||
private val getInsetsMethod = Reflect.instanceFunction(containerPeerClass, "getInsets", Insets::class.java).unchecked
|
||||
private val decoratedPeerClass = Class.forName("sun.awt.wl.WLDecoratedPeer")
|
||||
private val decorationField = decoratedPeerClass.getDeclaredField("decoration").apply { setAccessible(this) }
|
||||
private val frameDecorationClass = Class.forName("sun.awt.wl.WLFrameDecoration")
|
||||
private val markRepaintNeededMethod = Reflect.instanceProcedure(frameDecorationClass, "markRepaintNeeded").unchecked
|
||||
private val isUndecoratedField = frameDecorationClass.getDeclaredField("isUndecorated").apply { setAccessible(this) }
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user