Fixed errors with GObject access on FreeBSD + Gnome3. Added text to
warning logs.
This commit is contained in:
parent
9727662aca
commit
f426e2d08d
@ -323,7 +323,7 @@ class SystemTray {
|
|||||||
FORCE_TRAY_TYPE = TrayType.AutoDetect;
|
FORCE_TRAY_TYPE = TrayType.AutoDetect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (OS.isLinux()) {
|
else if (OS.isLinux() || OS.isUnix()) {
|
||||||
// kablooie if SWT/JavaFX is not configured in a way that works with us.
|
// kablooie if SWT/JavaFX is not configured in a way that works with us.
|
||||||
if (FORCE_TRAY_TYPE != TrayType.Swing) {
|
if (FORCE_TRAY_TYPE != TrayType.Swing) {
|
||||||
if (isSwtLoaded) {
|
if (isSwtLoaded) {
|
||||||
@ -419,7 +419,7 @@ class SystemTray {
|
|||||||
// macosx doesn't respond to all buttons (but should)
|
// macosx doesn't respond to all buttons (but should)
|
||||||
SystemTrayFixes.fixMacOS();
|
SystemTrayFixes.fixMacOS();
|
||||||
}
|
}
|
||||||
else if (OS.isLinux() && FORCE_TRAY_TYPE != TrayType.Swing) {
|
else if ((OS.isLinux() || OS.isUnix()) && FORCE_TRAY_TYPE != TrayType.Swing) {
|
||||||
// see: https://askubuntu.com/questions/72549/how-to-determine-which-window-manager-is-running
|
// see: https://askubuntu.com/questions/72549/how-to-determine-which-window-manager-is-running
|
||||||
|
|
||||||
// For funsies, SyncThing did a LOT of work on compatibility (unfortunate for us) in python.
|
// For funsies, SyncThing did a LOT of work on compatibility (unfortunate for us) in python.
|
||||||
@ -446,7 +446,7 @@ class SystemTray {
|
|||||||
|
|
||||||
// BLEH. if gnome-shell is running, IT'S REALLY GNOME!
|
// BLEH. if gnome-shell is running, IT'S REALLY GNOME!
|
||||||
// we must ALWAYS do this check!!
|
// we must ALWAYS do this check!!
|
||||||
boolean isReallyGnome = OSUtil.Linux.DesktopEnv.isGnome();
|
boolean isReallyGnome = OSUtil.DesktopEnv.isGnome();
|
||||||
|
|
||||||
if (isReallyGnome) {
|
if (isReallyGnome) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
@ -536,7 +536,11 @@ class SystemTray {
|
|||||||
else if (OSUtil.Linux.isUbuntu()) {
|
else if (OSUtil.Linux.isUbuntu()) {
|
||||||
// so far, because of the interaction between gnome3 + ubuntu, the GtkStatusIcon miraculously works.
|
// so far, because of the interaction between gnome3 + ubuntu, the GtkStatusIcon miraculously works.
|
||||||
trayType = selectTypeQuietly(useNativeMenus, TrayType.GtkStatusIcon);
|
trayType = selectTypeQuietly(useNativeMenus, TrayType.GtkStatusIcon);
|
||||||
} else {
|
}
|
||||||
|
else if (OSUtil.Unix.isFreeBSD()) {
|
||||||
|
trayType = selectTypeQuietly(useNativeMenus, TrayType.GtkStatusIcon);
|
||||||
|
}
|
||||||
|
else {
|
||||||
// arch likely will have problems unless the correct/appropriate libraries are installed.
|
// arch likely will have problems unless the correct/appropriate libraries are installed.
|
||||||
trayType = selectTypeQuietly(useNativeMenus, TrayType.AppIndicator);
|
trayType = selectTypeQuietly(useNativeMenus, TrayType.AppIndicator);
|
||||||
}
|
}
|
||||||
@ -690,7 +694,7 @@ class SystemTray {
|
|||||||
CacheUtil.tempDir = "SysTray";
|
CacheUtil.tempDir = "SysTray";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (OS.isLinux()) {
|
if (OS.isLinux() || OS.isUnix()) {
|
||||||
// NOTE: appindicator1 -> GTk2, appindicator3 -> GTK3.
|
// NOTE: appindicator1 -> GTk2, appindicator3 -> GTK3.
|
||||||
// appindicator3 doesn't support menu icons via GTK2!!
|
// appindicator3 doesn't support menu icons via GTK2!!
|
||||||
if (!Gtk.isLoaded) {
|
if (!Gtk.isLoaded) {
|
||||||
@ -752,8 +756,8 @@ class SystemTray {
|
|||||||
|
|
||||||
if (!AppIndicator.isLoaded) {
|
if (!AppIndicator.isLoaded) {
|
||||||
// YIKES. Try to fallback to GtkStatusIndicator, since AppIndicator couldn't load.
|
// YIKES. Try to fallback to GtkStatusIndicator, since AppIndicator couldn't load.
|
||||||
|
logger.warn("Unable to initialize the AppIndicator correctly, falling back to GtkStatusIcon type");
|
||||||
trayType = selectTypeQuietly(useNativeMenus, TrayType.GtkStatusIcon);
|
trayType = selectTypeQuietly(useNativeMenus, TrayType.GtkStatusIcon);
|
||||||
logger.warn("Unable to initialize the AppIndicator correctly, falling back to GtkStatusIcon.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -794,7 +798,7 @@ class SystemTray {
|
|||||||
// if it's linux + native menus must not start on the EDT!
|
// if it's linux + native menus must not start on the EDT!
|
||||||
// _AwtTray must be constructed on the EDT however...
|
// _AwtTray must be constructed on the EDT however...
|
||||||
if (isJavaFxLoaded || isSwtLoaded ||
|
if (isJavaFxLoaded || isSwtLoaded ||
|
||||||
(OS.isLinux() && NativeUI.class.isAssignableFrom(trayType) && trayType != _AwtTray.class)) {
|
((OS.isLinux() || OS.isUnix()) && NativeUI.class.isAssignableFrom(trayType) && trayType != _AwtTray.class)) {
|
||||||
try {
|
try {
|
||||||
reference.set((Tray) trayType.getConstructors()[0].newInstance(systemTray));
|
reference.set((Tray) trayType.getConstructors()[0].newInstance(systemTray));
|
||||||
logger.info("Successfully Loaded: {}", trayType.getSimpleName());
|
logger.info("Successfully Loaded: {}", trayType.getSimpleName());
|
||||||
|
@ -15,8 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
package dorkbox.systemTray.jna.linux;
|
package dorkbox.systemTray.jna.linux;
|
||||||
|
|
||||||
|
import static dorkbox.systemTray.SystemTray.logger;
|
||||||
|
|
||||||
import com.sun.jna.Callback;
|
import com.sun.jna.Callback;
|
||||||
import com.sun.jna.NativeLong;
|
import com.sun.jna.NativeLibrary;
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
import com.sun.jna.ptr.PointerByReference;
|
import com.sun.jna.ptr.PointerByReference;
|
||||||
|
|
||||||
@ -31,7 +33,14 @@ public
|
|||||||
class Gobject {
|
class Gobject {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
JnaHelper.register("gobject-2.0", Gobject.class);
|
try {
|
||||||
|
NativeLibrary library = JnaHelper.register("gobject-2.0", Gobject.class);
|
||||||
|
if (library == null) {
|
||||||
|
logger.error("Error loading GObject library, it failed to load.");
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
logger.error("Error loading GObject library, it failed to load {}", e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -42,5 +51,5 @@ class Gobject {
|
|||||||
public static native void g_object_force_floating(Pointer object);
|
public static native void g_object_force_floating(Pointer object);
|
||||||
public static native void g_object_ref_sink(Pointer object);
|
public static native void g_object_ref_sink(Pointer object);
|
||||||
|
|
||||||
public static native NativeLong g_signal_connect_object(Pointer instance, String detailed_signal, Callback c_handler, Pointer object, int connect_flags);
|
public static native void g_signal_connect_object(Pointer instance, String detailed_signal, Callback c_handler, Pointer object, int connect_flags);
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ package dorkbox.systemTray.nativeUI;
|
|||||||
|
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
import com.sun.jna.NativeLong;
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
|
|
||||||
import dorkbox.systemTray.MenuItem;
|
import dorkbox.systemTray.MenuItem;
|
||||||
@ -28,9 +27,6 @@ import dorkbox.systemTray.jna.linux.Gtk;
|
|||||||
import dorkbox.systemTray.peer.MenuItemPeer;
|
import dorkbox.systemTray.peer.MenuItemPeer;
|
||||||
|
|
||||||
class GtkMenuItem extends GtkBaseMenuItem implements MenuItemPeer, GCallback {
|
class GtkMenuItem extends GtkBaseMenuItem implements MenuItemPeer, GCallback {
|
||||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
|
||||||
private final NativeLong nativeLong;
|
|
||||||
|
|
||||||
private final GtkMenu parent;
|
private final GtkMenu parent;
|
||||||
|
|
||||||
// these have to be volatile, because they can be changed from any thread
|
// these have to be volatile, because they can be changed from any thread
|
||||||
@ -50,7 +46,7 @@ class GtkMenuItem extends GtkBaseMenuItem implements MenuItemPeer, GCallback {
|
|||||||
super(Gtk.gtk_image_menu_item_new_with_mnemonic(""));
|
super(Gtk.gtk_image_menu_item_new_with_mnemonic(""));
|
||||||
|
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
nativeLong = Gobject.g_signal_connect_object(_native, "activate", this, null, 0);
|
Gobject.g_signal_connect_object(_native, "activate", this, null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ package dorkbox.systemTray.nativeUI;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
|
|
||||||
import com.sun.jna.NativeLong;
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
|
|
||||||
import dorkbox.systemTray.Checkbox;
|
import dorkbox.systemTray.Checkbox;
|
||||||
@ -30,9 +29,6 @@ import dorkbox.systemTray.peer.CheckboxPeer;
|
|||||||
|
|
||||||
// ElementaryOS shows the checkbox on the right, everyone else is on the left. With eOS, we CANNOT show the spacer image. It does not work
|
// ElementaryOS shows the checkbox on the right, everyone else is on the left. With eOS, we CANNOT show the spacer image. It does not work
|
||||||
class GtkMenuItemCheckbox extends GtkBaseMenuItem implements CheckboxPeer, GCallback {
|
class GtkMenuItemCheckbox extends GtkBaseMenuItem implements CheckboxPeer, GCallback {
|
||||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
|
||||||
private final NativeLong nativeLong;
|
|
||||||
|
|
||||||
private final GtkMenu parent;
|
private final GtkMenu parent;
|
||||||
|
|
||||||
// these have to be volatile, because they can be changed from any thread
|
// these have to be volatile, because they can be changed from any thread
|
||||||
@ -53,7 +49,7 @@ class GtkMenuItemCheckbox extends GtkBaseMenuItem implements CheckboxPeer, GCall
|
|||||||
super(Gtk.gtk_check_menu_item_new_with_mnemonic(""));
|
super(Gtk.gtk_check_menu_item_new_with_mnemonic(""));
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
|
||||||
nativeLong = Gobject.g_signal_connect_object(_native, "activate", this, null, 0);
|
Gobject.g_signal_connect_object(_native, "activate", this, null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// called by native code
|
// called by native code
|
||||||
|
@ -16,11 +16,8 @@
|
|||||||
package dorkbox.systemTray.nativeUI;
|
package dorkbox.systemTray.nativeUI;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import com.sun.jna.NativeLong;
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
|
|
||||||
import dorkbox.systemTray.MenuItem;
|
import dorkbox.systemTray.MenuItem;
|
||||||
@ -45,7 +42,8 @@ class _GtkStatusIconNativeTray extends Tray implements NativeUI {
|
|||||||
// https://github.com/djdeath/glib/blob/master/gobject/gobject.c
|
// https://github.com/djdeath/glib/blob/master/gobject/gobject.c
|
||||||
|
|
||||||
// have to save these in a field to prevent GC on the objects (since they go out-of-scope from java)
|
// have to save these in a field to prevent GC on the objects (since they go out-of-scope from java)
|
||||||
private final List<Object> gtkCallbacks = new ArrayList<Object>();
|
// see: https://github.com/java-native-access/jna/blob/master/www/CallbacksAndClosures.md
|
||||||
|
private GEventCallback gtkCallback = null;
|
||||||
|
|
||||||
// This is required if we have JavaFX or SWT shutdown hooks (to prevent us from shutting down twice...)
|
// This is required if we have JavaFX or SWT shutdown hooks (to prevent us from shutting down twice...)
|
||||||
private AtomicBoolean shuttingDown = new AtomicBoolean();
|
private AtomicBoolean shuttingDown = new AtomicBoolean();
|
||||||
@ -135,7 +133,7 @@ class _GtkStatusIconNativeTray extends Tray implements NativeUI {
|
|||||||
|
|
||||||
// mark for GC
|
// mark for GC
|
||||||
trayIcon = null;
|
trayIcon = null;
|
||||||
gtkCallbacks.clear();
|
gtkCallback = null;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -153,7 +151,7 @@ class _GtkStatusIconNativeTray extends Tray implements NativeUI {
|
|||||||
void run() {
|
void run() {
|
||||||
trayIcon = Gtk.gtk_status_icon_new();
|
trayIcon = Gtk.gtk_status_icon_new();
|
||||||
|
|
||||||
final GEventCallback gtkCallback = new GEventCallback() {
|
gtkCallback = new GEventCallback() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void callback(Pointer notUsed, final GdkEventButton event) {
|
void callback(Pointer notUsed, final GdkEventButton event) {
|
||||||
@ -165,12 +163,7 @@ class _GtkStatusIconNativeTray extends Tray implements NativeUI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
final NativeLong button_press_event = Gobject.g_signal_connect_object(trayIcon, "button_press_event",
|
Gobject.g_signal_connect_object(trayIcon, "button_press_event", gtkCallback, null, 0);
|
||||||
gtkCallback, null, 0);
|
|
||||||
|
|
||||||
// have to do this to prevent GC on these objects
|
|
||||||
gtkCallbacks.add(gtkCallback);
|
|
||||||
gtkCallbacks.add(button_press_event);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ import java.awt.Point;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import com.sun.jna.NativeLong;
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
import com.sun.jna.ptr.PointerByReference;
|
import com.sun.jna.ptr.PointerByReference;
|
||||||
|
|
||||||
@ -92,8 +91,6 @@ class _AppIndicatorTray extends Tray implements SwingUI {
|
|||||||
private AtomicBoolean shuttingDown = new AtomicBoolean();
|
private AtomicBoolean shuttingDown = new AtomicBoolean();
|
||||||
|
|
||||||
// necessary to prevent GC on these objects
|
// necessary to prevent GC on these objects
|
||||||
@SuppressWarnings({"FieldCanBeLocal", "unused"})
|
|
||||||
private NativeLong nativeLong;
|
|
||||||
@SuppressWarnings("FieldCanBeLocal")
|
@SuppressWarnings("FieldCanBeLocal")
|
||||||
private GEventCallback gtkCallback;
|
private GEventCallback gtkCallback;
|
||||||
|
|
||||||
@ -295,7 +292,7 @@ class _AppIndicatorTray extends Tray implements SwingUI {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
nativeLong = Gobject.g_signal_connect_object(rootMenuItem.getValue(), "about-to-show", gtkCallback, null, 0);
|
Gobject.g_signal_connect_object(rootMenuItem.getValue(), "about-to-show", gtkCallback, null, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -18,13 +18,10 @@ package dorkbox.systemTray.swingUI;
|
|||||||
import java.awt.MouseInfo;
|
import java.awt.MouseInfo;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import javax.swing.JPopupMenu;
|
import javax.swing.JPopupMenu;
|
||||||
|
|
||||||
import com.sun.jna.NativeLong;
|
|
||||||
import com.sun.jna.Pointer;
|
import com.sun.jna.Pointer;
|
||||||
|
|
||||||
import dorkbox.systemTray.MenuItem;
|
import dorkbox.systemTray.MenuItem;
|
||||||
@ -51,7 +48,8 @@ class _GtkStatusIconTray extends Tray implements SwingUI {
|
|||||||
private volatile Pointer trayIcon;
|
private volatile Pointer trayIcon;
|
||||||
|
|
||||||
// have to save these in a field to prevent GC on the objects (since they go out-of-scope from java)
|
// have to save these in a field to prevent GC on the objects (since they go out-of-scope from java)
|
||||||
private final List<Object> gtkCallbacks = new ArrayList<Object>();
|
// see: https://github.com/java-native-access/jna/blob/master/www/CallbacksAndClosures.md
|
||||||
|
private GEventCallback gtkCallback = null;
|
||||||
|
|
||||||
private AtomicBoolean shuttingDown = new AtomicBoolean();
|
private AtomicBoolean shuttingDown = new AtomicBoolean();
|
||||||
|
|
||||||
@ -75,7 +73,7 @@ class _GtkStatusIconTray extends Tray implements SwingUI {
|
|||||||
void run() {
|
void run() {
|
||||||
trayIcon = Gtk.gtk_status_icon_new();
|
trayIcon = Gtk.gtk_status_icon_new();
|
||||||
|
|
||||||
final GEventCallback gtkCallback = new GEventCallback() {
|
gtkCallback = new GEventCallback() {
|
||||||
@Override
|
@Override
|
||||||
public
|
public
|
||||||
void callback(Pointer notUsed, final GdkEventButton event) {
|
void callback(Pointer notUsed, final GdkEventButton event) {
|
||||||
@ -87,12 +85,7 @@ class _GtkStatusIconTray extends Tray implements SwingUI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
final NativeLong button_press_event = Gobject.g_signal_connect_object(trayIcon, "button_press_event",
|
Gobject.g_signal_connect_object(trayIcon, "button_press_event", gtkCallback, null, 0);
|
||||||
gtkCallback, null, 0);
|
|
||||||
|
|
||||||
// have to do this to prevent GC on these objects
|
|
||||||
gtkCallbacks.add(gtkCallback);
|
|
||||||
gtkCallbacks.add(button_press_event);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -209,7 +202,6 @@ class _GtkStatusIconTray extends Tray implements SwingUI {
|
|||||||
|
|
||||||
// mark for GC
|
// mark for GC
|
||||||
trayIcon = null;
|
trayIcon = null;
|
||||||
gtkCallbacks.clear();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user