Skip to content

Instantly share code, notes, and snippets.

@RChehowski
Created March 5, 2019 08:11
Show Gist options
  • Save RChehowski/6361e3c5d594e8c81399dfc971b88a5d to your computer and use it in GitHub Desktop.
Save RChehowski/6361e3c5d594e8c81399dfc971b88a5d to your computer and use it in GitHub Desktop.
package com.vizor.unreal.platform.mac;
import com.vizor.log.LogManager;
import com.vizor.log.Logger;
import com.vizor.unreal.platform.FrameDecorator;
import javax.swing.ImageIcon;
import java.awt.Image;
import java.lang.invoke.MethodHandle;
import java.net.URL;
import static java.lang.invoke.MethodHandles.lookup;
import static java.lang.invoke.MethodType.methodType;
public class MacFrameDecorator extends FrameDecorator
{
private static final Logger log = LogManager.getLogger(MacFrameDecorator.class);
// Methods:
private MethodHandle requestForeground;
private MethodHandle requestUserAttention;
private MethodHandle setDockIconImage;
private static MethodHandle setDockIconBadge;
private static final String REQUEST_FOREGROUND_NAME = "requestForeground";
private static final String REQUEST_USER_ATTENTION_NAME = "requestUserAttention";
private static final String SET_DOCK_ICON_IMAGE = "setDockIconImage";
private static final String SET_DOCK_ICON_BADGE = "setDockIconBadge";
public MacFrameDecorator()
{
super(new MacTaskBar());
try {
// Root application class. Note that all AppKit classes are non-portable.
final Class<?> applicationClass = Class.forName("com.apple.eawt.Application");
Object application = applicationClass.getMethod("getApplication").invoke(null);
requestForeground = lookup().findVirtual(applicationClass, REQUEST_FOREGROUND_NAME,
methodType(void.class, boolean.class)).bindTo(application);
requestUserAttention = lookup().findVirtual(applicationClass, REQUEST_USER_ATTENTION_NAME,
methodType(void.class, boolean.class)).bindTo(application);
setDockIconImage = lookup().findVirtual(applicationClass, SET_DOCK_ICON_IMAGE,
methodType(void.class, Image.class)).bindTo(application);
setDockIconBadge = lookup().findVirtual(applicationClass, SET_DOCK_ICON_BADGE,
methodType(void.class, String.class)).bindTo(application);
}
catch (Throwable t) {
throw new RuntimeException(t);
}
}
// Implementation
@Override
protected final native void showNotificationImpl(String title, String body, Runnable runnable);
@Override
protected final void requestForegroundImpl()
{
try {
if (requestForeground != null)
requestForeground.invoke(true);
else
log.error("Unable to call {}: no such method", REQUEST_FOREGROUND_NAME);
}
catch (Throwable t) {
log.error("Unable to call {}: {}", REQUEST_FOREGROUND_NAME, t.toString());
}
}
@Override
protected final void requestUserAttentionImpl(boolean enable)
{
try {
if (requestUserAttention != null)
requestUserAttention.invoke(enable);
else
log.error("Unable to call {}: no such method", REQUEST_USER_ATTENTION_NAME);
}
catch (Throwable t) {
log.error("Unable to call {}: {}", REQUEST_USER_ATTENTION_NAME, t.toString());
}
}
@Override
protected final void setApplicationIconImpl(URL iconUrl)
{
try {
if (setDockIconImage != null)
{
final Image image = new ImageIcon(iconUrl).getImage();
setDockIconImage.invoke(image);
}
else
{
log.error("Unable to call {}: no such method", SET_DOCK_ICON_IMAGE);
}
}
catch (Throwable t) {
log.error("Unable to call {}: {}", SET_DOCK_ICON_IMAGE, t.toString());
}
}
/**
* Called from {@link MacTaskBar}
* @param text Text do display or null
*/
static void setBadgeText(final String text)
{
try {
if (setDockIconBadge != null)
setDockIconBadge.invoke(text);
else
log.error("Unable to call {}: no such method", SET_DOCK_ICON_BADGE);
}
catch (Throwable t) {
log.error("Unable to call {}: {}", SET_DOCK_ICON_BADGE, t.toString());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment