Moved screen position information into it's own class. Updated/cleaned up code warnings
This commit is contained in:
parent
da2f22c18f
commit
7d2cdf5b1a
|
@ -16,6 +16,7 @@
|
||||||
package dorkbox.util.tray.linux;
|
package dorkbox.util.tray.linux;
|
||||||
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
|
import dorkbox.util.ScreenUtil;
|
||||||
import dorkbox.util.SwingUtil;
|
import dorkbox.util.SwingUtil;
|
||||||
import dorkbox.util.jna.linux.Gobject;
|
import dorkbox.util.jna.linux.Gobject;
|
||||||
import dorkbox.util.jna.linux.Gtk;
|
import dorkbox.util.jna.linux.Gtk;
|
||||||
|
@ -44,15 +45,18 @@ class GtkSystemTray extends SystemTray {
|
||||||
private static final Gobject libgobject = Gobject.INSTANCE;
|
private static final Gobject libgobject = Gobject.INSTANCE;
|
||||||
private static final Gtk libgtk = Gtk.INSTANCE;
|
private static final Gtk libgtk = Gtk.INSTANCE;
|
||||||
|
|
||||||
private final Map<String, JMenuItem> menuEntries = new HashMap<String, JMenuItem>(2);
|
final Map<String, JMenuItem> menuEntries = new HashMap<String, JMenuItem>(2);
|
||||||
|
|
||||||
private volatile SystemTrayMenuPopup jmenu;
|
volatile SystemTrayMenuPopup jmenu;
|
||||||
private volatile JMenuItem connectionStatusItem;
|
volatile JMenuItem connectionStatusItem;
|
||||||
|
|
||||||
private volatile Pointer trayIcon;
|
private volatile Pointer trayIcon;
|
||||||
|
|
||||||
// need to hang on to these to prevent gc
|
// need to hang on to these to prevent gc
|
||||||
private final List<Pointer> widgets = new ArrayList<Pointer>(4);
|
private final List<Pointer> widgets = new ArrayList<Pointer>(4);
|
||||||
|
|
||||||
|
// have to make this a field, to prevent GC on this object
|
||||||
|
@SuppressWarnings("FieldCanBeLocal")
|
||||||
private Gobject.GEventCallback gtkCallback;
|
private Gobject.GEventCallback gtkCallback;
|
||||||
|
|
||||||
public
|
public
|
||||||
|
@ -72,10 +76,11 @@ class GtkSystemTray extends SystemTray {
|
||||||
|
|
||||||
libgtk.gdk_threads_enter();
|
libgtk.gdk_threads_enter();
|
||||||
|
|
||||||
this.trayIcon = libgtk.gtk_status_icon_new();
|
final Pointer trayIcon = libgtk.gtk_status_icon_new();
|
||||||
libgtk.gtk_status_icon_set_from_file(this.trayIcon, iconPath(iconName));
|
this.trayIcon = trayIcon;
|
||||||
libgtk.gtk_status_icon_set_tooltip(this.trayIcon, this.appName);
|
libgtk.gtk_status_icon_set_from_file(trayIcon, iconPath(iconName));
|
||||||
libgtk.gtk_status_icon_set_visible(this.trayIcon, true);
|
libgtk.gtk_status_icon_set_tooltip(trayIcon, this.appName);
|
||||||
|
libgtk.gtk_status_icon_set_visible(trayIcon, true);
|
||||||
|
|
||||||
// have to make this a field, to prevent GC on this object
|
// have to make this a field, to prevent GC on this object
|
||||||
this.gtkCallback = new Gobject.GEventCallback() {
|
this.gtkCallback = new Gobject.GEventCallback() {
|
||||||
|
@ -90,17 +95,18 @@ class GtkSystemTray extends SystemTray {
|
||||||
void run() {
|
void run() {
|
||||||
// test this using cinnamon (which still uses status icon)
|
// test this using cinnamon (which still uses status icon)
|
||||||
|
|
||||||
if (GtkSystemTray.this.jmenu.isVisible()) {
|
final SystemTrayMenuPopup jmenu = GtkSystemTray.this.jmenu;
|
||||||
GtkSystemTray.this.jmenu.setVisible(false);
|
if (jmenu.isVisible()) {
|
||||||
|
jmenu.setVisible(false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Dimension size = GtkSystemTray.this.jmenu.getPreferredSize();
|
Dimension size = jmenu.getPreferredSize();
|
||||||
|
|
||||||
int x = (int) event.x_root;
|
int x = (int) event.x_root;
|
||||||
int y = (int) event.y_root;
|
int y = (int) event.y_root;
|
||||||
|
|
||||||
Point point = new Point(x, y);
|
Point point = new Point(x, y);
|
||||||
Rectangle bounds = SwingUtil.getScreenBoundsAt(point);
|
Rectangle bounds = ScreenUtil.getScreenBoundsAt(point);
|
||||||
|
|
||||||
if (y < bounds.y) {
|
if (y < bounds.y) {
|
||||||
y = bounds.y;
|
y = bounds.y;
|
||||||
|
@ -132,10 +138,10 @@ class GtkSystemTray extends SystemTray {
|
||||||
y -= distanceToEdgeOfTray + 4;
|
y -= distanceToEdgeOfTray + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkSystemTray.this.jmenu.setInvoker(GtkSystemTray.this.jmenu);
|
jmenu.setInvoker(jmenu);
|
||||||
GtkSystemTray.this.jmenu.setLocation(x, y);
|
jmenu.setLocation(x, y);
|
||||||
GtkSystemTray.this.jmenu.setVisible(true);
|
jmenu.setVisible(true);
|
||||||
GtkSystemTray.this.jmenu.requestFocus();
|
jmenu.requestFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -143,12 +149,13 @@ class GtkSystemTray extends SystemTray {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// all the clicks. This is because native menu popups are a pain to figure out, so we cheat and use some java bits to do the popup
|
// all the clicks. This is because native menu popups are a pain to figure out, so we cheat and use some java bits to do the popup
|
||||||
libgobject.g_signal_connect_data(this.trayIcon, "button_press_event", this.gtkCallback, null, null, 0);
|
libgobject.g_signal_connect_data(trayIcon, "button_press_event", this.gtkCallback, null, null, 0);
|
||||||
libgtk.gdk_threads_leave();
|
libgtk.gdk_threads_leave();
|
||||||
|
|
||||||
this.active = true;
|
this.active = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("FieldRepeatedlyAccessedInMethod")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void removeTray() {
|
void removeTray() {
|
||||||
|
@ -183,6 +190,7 @@ class GtkSystemTray extends SystemTray {
|
||||||
super.removeTray();
|
super.removeTray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("FieldRepeatedlyAccessedInMethod")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void setStatus(final String infoString, String iconName) {
|
void setStatus(final String infoString, String iconName) {
|
||||||
|
@ -191,9 +199,10 @@ class GtkSystemTray extends SystemTray {
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
if (GtkSystemTray.this.connectionStatusItem == null) {
|
if (GtkSystemTray.this.connectionStatusItem == null) {
|
||||||
GtkSystemTray.this.connectionStatusItem = new JMenuItem(infoString);
|
final JMenuItem connectionStatusItem = new JMenuItem(infoString);
|
||||||
GtkSystemTray.this.connectionStatusItem.setEnabled(false);
|
GtkSystemTray.this.connectionStatusItem = connectionStatusItem;
|
||||||
GtkSystemTray.this.jmenu.add(GtkSystemTray.this.connectionStatusItem);
|
connectionStatusItem.setEnabled(false);
|
||||||
|
GtkSystemTray.this.jmenu.add(connectionStatusItem);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GtkSystemTray.this.connectionStatusItem.setText(infoString);
|
GtkSystemTray.this.connectionStatusItem.setText(infoString);
|
||||||
|
@ -213,10 +222,11 @@ class GtkSystemTray extends SystemTray {
|
||||||
public
|
public
|
||||||
void addMenuEntry(final String menuText, final SystemTrayMenuAction callback) {
|
void addMenuEntry(final String menuText, final SystemTrayMenuAction callback) {
|
||||||
SwingUtil.invokeAndWait(new Runnable() {
|
SwingUtil.invokeAndWait(new Runnable() {
|
||||||
|
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
Map<String, JMenuItem> menuEntries2 = GtkSystemTray.this.menuEntries;
|
final Map<String, JMenuItem> menuEntries2 = GtkSystemTray.this.menuEntries;
|
||||||
|
|
||||||
synchronized (menuEntries2) {
|
synchronized (menuEntries2) {
|
||||||
JMenuItem menuEntry = menuEntries2.get(menuText);
|
JMenuItem menuEntry = menuEntries2.get(menuText);
|
||||||
|
@ -259,10 +269,11 @@ class GtkSystemTray extends SystemTray {
|
||||||
public
|
public
|
||||||
void updateMenuEntry(final String origMenuText, final String newMenuText, final SystemTrayMenuAction newCallback) {
|
void updateMenuEntry(final String origMenuText, final String newMenuText, final SystemTrayMenuAction newCallback) {
|
||||||
SwingUtil.invokeAndWait(new Runnable() {
|
SwingUtil.invokeAndWait(new Runnable() {
|
||||||
|
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
Map<String, JMenuItem> menuEntries2 = GtkSystemTray.this.menuEntries;
|
final Map<String, JMenuItem> menuEntries2 = GtkSystemTray.this.menuEntries;
|
||||||
|
|
||||||
synchronized (menuEntries2) {
|
synchronized (menuEntries2) {
|
||||||
JMenuItem menuEntry = menuEntries2.get(origMenuText);
|
JMenuItem menuEntry = menuEntries2.get(origMenuText);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package dorkbox.util.tray.swing;
|
package dorkbox.util.tray.swing;
|
||||||
|
|
||||||
|
import dorkbox.util.ScreenUtil;
|
||||||
import dorkbox.util.SwingUtil;
|
import dorkbox.util.SwingUtil;
|
||||||
import dorkbox.util.tray.SystemTrayMenuAction;
|
import dorkbox.util.tray.SystemTrayMenuAction;
|
||||||
import dorkbox.util.tray.SystemTrayMenuPopup;
|
import dorkbox.util.tray.SystemTrayMenuPopup;
|
||||||
|
@ -34,13 +35,13 @@ import java.util.Map;
|
||||||
public
|
public
|
||||||
class SwingSystemTray extends dorkbox.util.tray.SystemTray {
|
class SwingSystemTray extends dorkbox.util.tray.SystemTray {
|
||||||
|
|
||||||
private final Map<String, JMenuItem> menuEntries = new HashMap<String, JMenuItem>(2);
|
final Map<String, JMenuItem> menuEntries = new HashMap<String, JMenuItem>(2);
|
||||||
|
|
||||||
private volatile SystemTrayMenuPopup jmenu;
|
volatile SystemTrayMenuPopup jmenu;
|
||||||
private volatile JMenuItem connectionStatusItem;
|
volatile JMenuItem connectionStatusItem;
|
||||||
|
|
||||||
private volatile SystemTray tray;
|
volatile SystemTray tray;
|
||||||
private volatile TrayIcon trayIcon;
|
volatile TrayIcon trayIcon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new system tray handler class.
|
* Creates a new system tray handler class.
|
||||||
|
@ -65,6 +66,7 @@ class SwingSystemTray extends dorkbox.util.tray.SystemTray {
|
||||||
super.removeTray();
|
super.removeTray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("FieldRepeatedlyAccessedInMethod")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void createTray(final String iconName) {
|
void createTray(final String iconName) {
|
||||||
|
@ -79,18 +81,20 @@ class SwingSystemTray extends dorkbox.util.tray.SystemTray {
|
||||||
else {
|
else {
|
||||||
SwingSystemTray.this.jmenu = new SystemTrayMenuPopup();
|
SwingSystemTray.this.jmenu = new SystemTrayMenuPopup();
|
||||||
|
|
||||||
Image trayImage = newImage(iconName);
|
final Image trayImage = newImage(iconName);
|
||||||
SwingSystemTray.this.trayIcon = new TrayIcon(trayImage);
|
final TrayIcon trayIcon = new TrayIcon(trayImage);
|
||||||
SwingSystemTray.this.trayIcon.setToolTip(SwingSystemTray.this.appName);
|
SwingSystemTray.this.trayIcon = trayIcon;
|
||||||
|
trayIcon.setToolTip(SwingSystemTray.this.appName);
|
||||||
|
|
||||||
SwingSystemTray.this.trayIcon.addMouseListener(new MouseAdapter() {
|
trayIcon.addMouseListener(new MouseAdapter() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void mousePressed(MouseEvent e) {
|
void mousePressed(MouseEvent e) {
|
||||||
Dimension size = SwingSystemTray.this.jmenu.getPreferredSize();
|
final SystemTrayMenuPopup jmenu = SwingSystemTray.this.jmenu;
|
||||||
|
Dimension size = jmenu.getPreferredSize();
|
||||||
|
|
||||||
Point point = e.getPoint();
|
Point point = e.getPoint();
|
||||||
Rectangle bounds = SwingUtil.getScreenBoundsAt(point);
|
Rectangle bounds = ScreenUtil.getScreenBoundsAt(point);
|
||||||
|
|
||||||
int x = point.x;
|
int x = point.x;
|
||||||
int y = point.y;
|
int y = point.y;
|
||||||
|
@ -113,15 +117,15 @@ class SwingSystemTray extends dorkbox.util.tray.SystemTray {
|
||||||
x -= size.width; // snap to edge of mouse
|
x -= size.width; // snap to edge of mouse
|
||||||
}
|
}
|
||||||
|
|
||||||
SwingSystemTray.this.jmenu.setInvoker(SwingSystemTray.this.jmenu);
|
jmenu.setInvoker(jmenu);
|
||||||
SwingSystemTray.this.jmenu.setLocation(x, y);
|
jmenu.setLocation(x, y);
|
||||||
SwingSystemTray.this.jmenu.setVisible(true);
|
jmenu.setVisible(true);
|
||||||
SwingSystemTray.this.jmenu.requestFocus();
|
jmenu.requestFocus();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SwingSystemTray.this.tray.add(SwingSystemTray.this.trayIcon);
|
SwingSystemTray.this.tray.add(trayIcon);
|
||||||
SwingSystemTray.this.active = true;
|
SwingSystemTray.this.active = true;
|
||||||
} catch (AWTException e) {
|
} catch (AWTException e) {
|
||||||
logger.error("TrayIcon could not be added.", e);
|
logger.error("TrayIcon could not be added.", e);
|
||||||
|
@ -137,6 +141,7 @@ class SwingSystemTray extends dorkbox.util.tray.SystemTray {
|
||||||
return new ImageIcon(iconPath).getImage().getScaledInstance(TRAY_SIZE, TRAY_SIZE, Image.SCALE_SMOOTH);
|
return new ImageIcon(iconPath).getImage().getScaledInstance(TRAY_SIZE, TRAY_SIZE, Image.SCALE_SMOOTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("FieldRepeatedlyAccessedInMethod")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void setStatus(final String infoString, final String iconName) {
|
void setStatus(final String infoString, final String iconName) {
|
||||||
|
@ -145,9 +150,11 @@ class SwingSystemTray extends dorkbox.util.tray.SystemTray {
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
if (SwingSystemTray.this.connectionStatusItem == null) {
|
if (SwingSystemTray.this.connectionStatusItem == null) {
|
||||||
SwingSystemTray.this.connectionStatusItem = new JMenuItem(infoString);
|
final JMenuItem connectionStatusItem = new JMenuItem(infoString);
|
||||||
SwingSystemTray.this.connectionStatusItem.setEnabled(false);
|
connectionStatusItem.setEnabled(false);
|
||||||
SwingSystemTray.this.jmenu.add(SwingSystemTray.this.connectionStatusItem);
|
SwingSystemTray.this.jmenu.add(connectionStatusItem);
|
||||||
|
|
||||||
|
SwingSystemTray.this.connectionStatusItem = connectionStatusItem;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SwingSystemTray.this.connectionStatusItem.setText(infoString);
|
SwingSystemTray.this.connectionStatusItem.setText(infoString);
|
||||||
|
@ -166,10 +173,11 @@ class SwingSystemTray extends dorkbox.util.tray.SystemTray {
|
||||||
public
|
public
|
||||||
void addMenuEntry(final String menuText, final SystemTrayMenuAction callback) {
|
void addMenuEntry(final String menuText, final SystemTrayMenuAction callback) {
|
||||||
SwingUtil.invokeAndWait(new Runnable() {
|
SwingUtil.invokeAndWait(new Runnable() {
|
||||||
|
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
Map<String, JMenuItem> menuEntries2 = SwingSystemTray.this.menuEntries;
|
final Map<String, JMenuItem> menuEntries2 = SwingSystemTray.this.menuEntries;
|
||||||
|
|
||||||
synchronized (menuEntries2) {
|
synchronized (menuEntries2) {
|
||||||
JMenuItem menuEntry = menuEntries2.get(menuText);
|
JMenuItem menuEntry = menuEntries2.get(menuText);
|
||||||
|
@ -210,10 +218,11 @@ class SwingSystemTray extends dorkbox.util.tray.SystemTray {
|
||||||
public
|
public
|
||||||
void updateMenuEntry(final String origMenuText, final String newMenuText, final SystemTrayMenuAction newCallback) {
|
void updateMenuEntry(final String origMenuText, final String newMenuText, final SystemTrayMenuAction newCallback) {
|
||||||
SwingUtil.invokeAndWait(new Runnable() {
|
SwingUtil.invokeAndWait(new Runnable() {
|
||||||
|
@SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter")
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void run() {
|
void run() {
|
||||||
Map<String, JMenuItem> menuEntries2 = SwingSystemTray.this.menuEntries;
|
final Map<String, JMenuItem> menuEntries2 = SwingSystemTray.this.menuEntries;
|
||||||
|
|
||||||
synchronized (menuEntries2) {
|
synchronized (menuEntries2) {
|
||||||
JMenuItem menuEntry = menuEntries2.get(origMenuText);
|
JMenuItem menuEntry = menuEntries2.get(origMenuText);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user