feat: implement SSD support
This commit is contained in:
parent
97f47569fd
commit
4ab1cc9a6b
@ -15,7 +15,6 @@ struct WLFrame {
|
|||||||
void *pad5;
|
void *pad5;
|
||||||
void *pad6;
|
void *pad6;
|
||||||
void *pad7;
|
void *pad7;
|
||||||
void *pad8;
|
|
||||||
jboolean toplevel;
|
jboolean toplevel;
|
||||||
union {
|
union {
|
||||||
struct xdg_toplevel *xdg_toplevel;
|
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");
|
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/RuntimeException"), "Not a toplevel");
|
||||||
return 0;
|
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);
|
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.Disposable
|
||||||
import com.intellij.openapi.application.Application
|
import com.intellij.openapi.application.Application
|
||||||
import com.intellij.openapi.application.ApplicationActivationListener
|
import com.intellij.openapi.application.ApplicationActivationListener
|
||||||
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.openapi.util.Disposer
|
import com.intellij.openapi.util.Disposer
|
||||||
import com.intellij.openapi.wm.IdeFrame
|
import com.intellij.openapi.wm.IdeFrame
|
||||||
import com.intellij.openapi.wm.impl.IdeFrameImpl
|
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.DBusConnection
|
||||||
import org.freedesktop.dbus.connections.impl.DBusConnectionBuilder
|
import org.freedesktop.dbus.connections.impl.DBusConnectionBuilder
|
||||||
import org.freedesktop.dbus.types.UInt32
|
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
|
import javax.swing.JMenuBar
|
||||||
|
|
||||||
class GlobalMenuService(private val app: Application) : ApplicationActivationListener {
|
class GlobalMenuService(private val app: Application) : ApplicationActivationListener {
|
||||||
@ -23,22 +28,44 @@ class GlobalMenuService(private val app: Application) : ApplicationActivationLis
|
|||||||
super.applicationActivated(ideFrame)
|
super.applicationActivated(ideFrame)
|
||||||
if (!GlobalMenu.Native.isSupported) return
|
if (!GlobalMenu.Native.isSupported) return
|
||||||
val peer: Peer
|
val peer: Peer
|
||||||
val menuBar: JMenuBar
|
val menuBar: JMenuBar?
|
||||||
|
val frame: JFrame
|
||||||
|
GlobalMenu.Log.warn(ideFrame.toString())
|
||||||
when (ideFrame) {
|
when (ideFrame) {
|
||||||
is ProjectFrameHelper -> {
|
is ProjectFrameHelper -> {
|
||||||
peer = ideFrame.rootPane.peer
|
peer = ideFrame.rootPane.peer
|
||||||
menuBar = ideFrame.rootPane.jMenuBar
|
menuBar = ideFrame.rootPane.jMenuBar
|
||||||
|
frame = ideFrame.frame
|
||||||
}
|
}
|
||||||
is IdeFrameImpl -> {
|
is IdeFrameImpl -> {
|
||||||
peer = ideFrame.peer
|
peer = ideFrame.peer
|
||||||
menuBar = ideFrame.jMenuBar
|
menuBar = ideFrame.jMenuBar
|
||||||
|
frame = ideFrame
|
||||||
}
|
}
|
||||||
else -> return
|
else -> return
|
||||||
}
|
}
|
||||||
if (GlobalMenu.Native.isMenuSupported && GMSettings.getInstance().state.menu) addGlobalMenu(menuBar, peer)
|
onActivate(peer, frame, menuBar)
|
||||||
else connection?.unExportObject(DbusmenuImpl.getMenuPath(peer.nativePtr))
|
}
|
||||||
if (GlobalMenu.Native.isDecorationSupported && GMSettings.getInstance().state.decorations) {
|
|
||||||
|
|
||||||
|
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
|
package io.gitlab.jfronny.globalmenu
|
||||||
|
|
||||||
import java.util.function.BiConsumer
|
import java.util.function.*
|
||||||
import java.util.function.BiFunction
|
|
||||||
import java.util.function.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, 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) }
|
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 Runnable.invoke() = run()
|
||||||
operator fun <T> Supplier<T>.invoke() = get()
|
operator fun <T> Supplier<T>.invoke() = get()
|
||||||
operator fun <T, R> Function<T, R>.invoke(t: T): R = apply(t)
|
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, 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.Reflect
|
||||||
import io.gitlab.jfronny.commons.unsafe.reflect.impl.CoreReflect
|
import io.gitlab.jfronny.commons.unsafe.reflect.impl.CoreReflect
|
||||||
import java.awt.Component
|
import java.awt.Component
|
||||||
|
import java.awt.Insets
|
||||||
import java.lang.reflect.AccessibleObject
|
import java.lang.reflect.AccessibleObject
|
||||||
import java.lang.reflect.Field
|
import java.lang.reflect.Field
|
||||||
|
|
||||||
@ -42,14 +43,25 @@ class WLPeer(private val inner: Any) : Peer {
|
|||||||
fun performLocked(runnable: Runnable) {
|
fun performLocked(runnable: Runnable) {
|
||||||
performLockedMethod(inner, runnable)
|
performLockedMethod(inner, runnable)
|
||||||
}
|
}
|
||||||
fun registerCleaner(runnable: Runnable) {
|
var decorated: Boolean
|
||||||
GlobalMenu.Cleaner.register(this, runnable)
|
get() = containerPeerClass.isInstance(inner) && getInsetsMethod(inner).top > 0
|
||||||
|
set(value) {
|
||||||
|
val decoration = decorationField.get(inner)
|
||||||
|
isUndecoratedField.setBoolean(decoration, !value)
|
||||||
|
markRepaintNeededMethod(decoration)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val componentPeerClass = Class.forName("sun.awt.wl.WLComponentPeer")
|
val componentPeerClass = Class.forName("sun.awt.wl.WLComponentPeer")
|
||||||
private val performLockedMethod = Reflect.instanceProcedure(componentPeerClass, "performLocked", Runnable::class.java).unchecked1
|
private val performLockedMethod = Reflect.instanceProcedure(componentPeerClass, "performLocked", Runnable::class.java).unchecked1
|
||||||
private val nativePtrField = componentPeerClass.getDeclaredField("nativePtr").apply { setAccessible(this) }
|
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