forked from dorkbox/SystemTray
Added 'hasImage()' to menu-entry. Fixed text entry alignment issues
for GTK menus
This commit is contained in:
parent
27fa213fc1
commit
34588de6b7
@ -66,9 +66,13 @@ interface MenuEntry {
|
||||
*
|
||||
* @param imageStream the InputStream of the image to use
|
||||
*/
|
||||
@Deprecated
|
||||
void setImage(InputStream imageStream);
|
||||
|
||||
/**
|
||||
* @return true if this menu entry has an image assigned to it, or is just text.
|
||||
*/
|
||||
boolean hasImage();
|
||||
|
||||
/**
|
||||
* Sets a callback for a menu entry. This is the action that occurs when one clicks the menu entry
|
||||
*
|
||||
|
@ -45,6 +45,10 @@ class GtkMenuEntry implements MenuEntry, GCallback {
|
||||
private volatile SystemTrayMenuAction callback;
|
||||
private volatile Pointer image;
|
||||
|
||||
// these are necessary BECAUSE GTK menus look funky as hell when there are some menu entries WITH icons and some WITHOUT
|
||||
private volatile boolean hasLegitIcon = true;
|
||||
private static File transparentIcon = null;
|
||||
|
||||
/**
|
||||
* called from inside dispatch thread. ONLY creates the menu item, but DOES NOT attach it!
|
||||
* this is a FLOATING reference. See: https://developer.gnome.org/gobject/stable/gobject-The-Base-Object-Type.html#floating-ref
|
||||
@ -56,13 +60,19 @@ class GtkMenuEntry implements MenuEntry, GCallback {
|
||||
|
||||
menuItem = Gtk.gtk_image_menu_item_new_with_label(label);
|
||||
|
||||
if (imagePath != null) {
|
||||
if (transparentIcon == null) {
|
||||
transparentIcon = ImageUtils.getTransparentImage(ImageUtils.ENTRY_SIZE);
|
||||
}
|
||||
|
||||
hasLegitIcon = imagePath != null;
|
||||
if (hasLegitIcon) {
|
||||
// NOTE: XFCE used to use appindicator3, which DOES NOT support images in the menu. This change was reverted.
|
||||
// see: https://ask.fedoraproject.org/en/question/23116/how-to-fix-missing-icons-in-program-menus-and-context-menus/
|
||||
// see: https://git.gnome.org/browse/gtk+/commit/?id=627a03683f5f41efbfc86cc0f10e1b7c11e9bb25
|
||||
image = Gtk.gtk_image_new_from_file(imagePath.getAbsolutePath());
|
||||
|
||||
Gtk.gtk_image_menu_item_set_image(menuItem, image);
|
||||
|
||||
// must always re-set always-show after setting the image
|
||||
Gtk.gtk_image_menu_item_set_always_show_image(menuItem, Gtk.TRUE);
|
||||
}
|
||||
@ -70,6 +80,34 @@ class GtkMenuEntry implements MenuEntry, GCallback {
|
||||
nativeLong = Gobject.g_signal_connect_object(menuItem, "activate", this, null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* the menu entry looks FUNKY when there are a mis-match of entries WITH and WITHOUT images
|
||||
*
|
||||
* called on the DISPATCH thread
|
||||
*/
|
||||
void setSpacerImage(final boolean everyoneElseHasImages) {
|
||||
if (hasLegitIcon) {
|
||||
// we have a legit icon, so there is nothing else we can do.
|
||||
return;
|
||||
}
|
||||
|
||||
if (image != null) {
|
||||
Gtk.gtk_widget_destroy(image);
|
||||
image = null;
|
||||
Gtk.gtk_widget_show_all(menuItem);
|
||||
}
|
||||
|
||||
if (everyoneElseHasImages) {
|
||||
image = Gtk.gtk_image_new_from_file(transparentIcon.getAbsolutePath());
|
||||
|
||||
Gtk.gtk_image_menu_item_set_image(menuItem, image);
|
||||
|
||||
// must always re-set always-show after setting the image
|
||||
Gtk.gtk_image_menu_item_set_always_show_image(menuItem, Gtk.TRUE);
|
||||
}
|
||||
|
||||
Gtk.gtk_widget_show_all(menuItem);
|
||||
}
|
||||
|
||||
// called by native code
|
||||
@Override
|
||||
@ -105,7 +143,9 @@ class GtkMenuEntry implements MenuEntry, GCallback {
|
||||
}
|
||||
|
||||
private
|
||||
void setImage_(final File imagePath) {
|
||||
void setImage_(final File imageFile) {
|
||||
hasLegitIcon = imageFile != null;
|
||||
|
||||
Gtk.dispatch(new Runnable() {
|
||||
@Override
|
||||
public
|
||||
@ -113,12 +153,11 @@ class GtkMenuEntry implements MenuEntry, GCallback {
|
||||
if (image != null) {
|
||||
Gtk.gtk_widget_destroy(image);
|
||||
image = null;
|
||||
Gtk.gtk_widget_show_all(menuItem);
|
||||
}
|
||||
|
||||
Gtk.gtk_widget_show_all(menuItem);
|
||||
|
||||
if (imagePath != null) {
|
||||
image = Gtk.gtk_image_new_from_file(imagePath.getAbsolutePath());
|
||||
if (hasLegitIcon) {
|
||||
image = Gtk.gtk_image_new_from_file(imageFile.getAbsolutePath());
|
||||
Gtk.gtk_image_menu_item_set_image(menuItem, image);
|
||||
Gobject.g_object_ref_sink(image);
|
||||
|
||||
@ -165,7 +204,6 @@ class GtkMenuEntry implements MenuEntry, GCallback {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public
|
||||
void setImage(final InputStream imageStream) {
|
||||
if (imageStream == null) {
|
||||
@ -176,6 +214,12 @@ class GtkMenuEntry implements MenuEntry, GCallback {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
boolean hasImage() {
|
||||
return hasLegitIcon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
void setCallback(final SystemTrayMenuAction callback) {
|
||||
|
@ -163,11 +163,22 @@ class GtkTypeSystemTray extends SystemTray {
|
||||
Gobject.g_object_ref_sink(connectionStatusItem);
|
||||
}
|
||||
|
||||
boolean hasImages = false;
|
||||
|
||||
// now add back other menu entries
|
||||
synchronized (menuEntries) {
|
||||
for (int i = 0; i < menuEntries.size(); i++) {
|
||||
GtkMenuEntry menuEntry__ = (GtkMenuEntry) menuEntries.get(i);
|
||||
|
||||
hasImages |= menuEntry__.hasImage();
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i < menuEntries.size(); i++) {
|
||||
GtkMenuEntry menuEntry__ = (GtkMenuEntry) menuEntries.get(i);
|
||||
// the menu entry looks FUNKY when there are a mis-match of entries WITH and WITHOUT images
|
||||
menuEntry__.setSpacerImage(hasImages);
|
||||
|
||||
// will also get: gsignal.c:2516: signal 'child-added' is invalid for instance '0x7f1df8244080' of type 'GtkMenu'
|
||||
Gtk.gtk_menu_shell_append(this.menu, menuEntry__.menuItem);
|
||||
Gobject.g_object_ref_sink(menuEntry__.menuItem);
|
||||
@ -264,8 +275,7 @@ class GtkTypeSystemTray extends SystemTray {
|
||||
addMenuEntry_(menuText, null, callback);
|
||||
}
|
||||
else {
|
||||
// addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageUrl), callback);
|
||||
addMenuEntry_(menuText, ImageUtils.getTransparentImage(ImageUtils.ENTRY_SIZE), callback);
|
||||
addMenuEntry_(menuText, ImageUtils.resizeAndCache(ImageUtils.ENTRY_SIZE, imageUrl), callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,6 +37,7 @@ class SwingMenuEntry implements MenuEntry {
|
||||
private final JMenuItem menuItem;
|
||||
private final ActionListener swingCallback;
|
||||
|
||||
private volatile boolean hasLegitIcon = false;
|
||||
private volatile String text;
|
||||
private volatile SystemTrayMenuAction callback;
|
||||
|
||||
@ -61,6 +62,7 @@ class SwingMenuEntry implements MenuEntry {
|
||||
menuItem.addActionListener(swingCallback);
|
||||
|
||||
if (imagePath != null) {
|
||||
hasLegitIcon = true;
|
||||
setImageIcon(imagePath);
|
||||
}
|
||||
|
||||
@ -110,10 +112,12 @@ class SwingMenuEntry implements MenuEntry {
|
||||
private
|
||||
void setImageIcon(final File imagePath) {
|
||||
if (imagePath != null) {
|
||||
hasLegitIcon = true;
|
||||
ImageIcon origIcon = new ImageIcon(imagePath.getAbsolutePath());
|
||||
menuItem.setIcon(origIcon);
|
||||
}
|
||||
else {
|
||||
hasLegitIcon = false;
|
||||
menuItem.setIcon(null);
|
||||
}
|
||||
}
|
||||
@ -152,7 +156,6 @@ class SwingMenuEntry implements MenuEntry {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public
|
||||
void setImage(final InputStream imageStream) {
|
||||
if (imageStream == null) {
|
||||
@ -163,6 +166,12 @@ class SwingMenuEntry implements MenuEntry {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
boolean hasImage() {
|
||||
return hasLegitIcon;
|
||||
}
|
||||
|
||||
@Override
|
||||
public
|
||||
void setCallback(final SystemTrayMenuAction callback) {
|
||||
|
Loading…
Reference in New Issue
Block a user