aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--resources/languages/resources.properties11
-rw-r--r--src/net/java/sip/communicator/impl/gui/UIServiceImpl.java39
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/MainFrame.java57
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java40
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/systemtray/SystemTray.java72
-rw-r--r--src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicatorTray.java24
-rw-r--r--src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java82
-rw-r--r--src/net/java/sip/communicator/service/gui/UIService.java26
-rw-r--r--src/net/java/sip/communicator/service/systray/SystrayService.java20
-rw-r--r--src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java6
10 files changed, 268 insertions, 109 deletions
diff --git a/resources/languages/resources.properties b/resources/languages/resources.properties
index deea410..156c911 100644
--- a/resources/languages/resources.properties
+++ b/resources/languages/resources.properties
@@ -840,6 +840,15 @@ service.gui.security.encryption.required=Encryption required!
service.protocol.ICE_FAILED=Could not establish connection (ICE failed and no relay found)
+service.systray.MODE=Tray implementation
+service.systray.mode.NATIVE=Default
+service.systray.mode.DISABLED=Disabled
+service.systray.mode.APPINDICATOR=AppIndicator (Unity, KDE, not plain Gnome 3; may crash on Debian)
+service.systray.mode.APPINDICATOR_STATIC=AppIndicator Static (no account status menus)
+service.systray.CLI_NOTE=If your choice does not work, you can start {0} with the "--notray" option. \
+ This forces the mode to "Disabled" and shows the GUI. \
+ Changing the tray implementation requires a restart.
+
# impl.protocol.ssh
#Contact Details Seperator(must not be part of contact data stored as persistent
# data)
@@ -1089,7 +1098,7 @@ plugin.generalconfig.SILK_ALWAYS_ASSUME_PACKET_LOSS=Always assume packet loss:
plugin.generalconfig.SILK_SAT=Speech activity threshold (0-1):
plugin.generalconfig.SILK_ADVERTISE_FEC=Advertise FEC support in SDP:
plugin.generalconfig.RESTORE=Restore defaults
-plugin.generalconfig.MINIMIZE_NOT_HIDE=Minimize the main window instead of hiding it
+plugin.generalconfig.MINIMIZE_NOT_HIDE=Minimize the main window instead of closing or hiding it
# gibberish accregwizz
plugin.gibberishaccregwizz.PROTOCOL_NAME=Gibberish
diff --git a/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java b/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java
index b7e1d9c..db2eac9 100644
--- a/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java
+++ b/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java
@@ -200,6 +200,7 @@ public class UIServiceImpl
}
if(ConfigurationUtils.isApplicationVisible()
+ || Boolean.getBoolean("disable-tray")
|| ConfigurationUtils.isMinimizeInsteadOfHide())
{
mainFrame.setFrameVisible(true);
@@ -433,38 +434,16 @@ public class UIServiceImpl
}
/**
- * Implements {@link UIService#setExitOnMainWindowClose}. Sets the boolean
- * property which indicates whether the application should be exited when
- * the main application window is closed.
- *
- * @param exitOnMainWindowClose <tt>true</tt> if closing the main
- * application window should also be exiting the application; otherwise,
- * <tt>false</tt>
- */
- public void setExitOnMainWindowClose(boolean exitOnMainWindowClose)
- {
- mainFrame.setDefaultCloseOperation(
- exitOnMainWindowClose
- ? JFrame.DISPOSE_ON_CLOSE
- : ConfigurationUtils.isMinimizeInsteadOfHide()
- ? JFrame.DO_NOTHING_ON_CLOSE
- : JFrame.HIDE_ON_CLOSE);
- }
-
- /**
- * Implements {@link UIService#getExitOnMainWindowClose()}. Gets the boolean
- * property which indicates whether the application should be exited when
- * the main application window is closed.
- *
- * @return determines whether the UI impl would exit the application when
- * the main application window is closed.
+ * Called from the systray service when a tray has been initialized and
+ * hiding (instead of minimizing or exiting) is possible). If hiding is
+ * possible and the option to minimize is not selected, the application
+ * gets hidden on clicking 'X'.
+ *
+ * @param true if a tray icon was loaded.
*/
- public boolean getExitOnMainWindowClose()
+ public void setMainWindowCanHide(boolean canHide)
{
- return
- (mainFrame != null)
- && (mainFrame.getDefaultCloseOperation()
- == JFrame.DISPOSE_ON_CLOSE);
+ mainFrame.updateCloseAction(canHide);
}
/**
diff --git a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
index 4762df8..b450efe 100644
--- a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
+++ b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
@@ -334,13 +334,9 @@ public class MainFrame
*/
private void init()
{
- setDefaultCloseOperation(
- GuiActivator.getUIService().getExitOnMainWindowClose()
- ? JFrame.DISPOSE_ON_CLOSE
- : JFrame.HIDE_ON_CLOSE);
-
+ // at startup, we cannot hide yet
+ updateCloseAction(false);
registerKeyActions();
-
JComponent northPanel = createTopComponent();
this.setJMenuBar(menu);
@@ -394,6 +390,30 @@ public class MainFrame
}
}
+ /**
+ * If hiding is possible and the option to minimize is not selected, the
+ * application gets hidden on clicking 'X'.
+ *
+ * @param true if hiding is possible, i.e. a tray icon is loaded
+ */
+ public void updateCloseAction(boolean canHide)
+ {
+ if (ConfigurationUtils.isMinimizeInsteadOfHide())
+ {
+ logger.info("Updating close action: DO_NOTHING_ON_CLOSE");
+ setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+ }
+ else
+ {
+ logger.info("Updating close action: " + (canHide
+ ? "HIDE_ON_CLOSE"
+ : "DISPOSE_ON_CLOSE"));
+ setDefaultCloseOperation(canHide
+ ? JFrame.HIDE_ON_CLOSE
+ : JFrame.DISPOSE_ON_CLOSE);
+ }
+ }
+
private Component createButtonPanel()
{
boolean isCallButtonEnabled = false;
@@ -1885,7 +1905,8 @@ public class MainFrame
*/
protected void windowClosed(WindowEvent event)
{
- if(GuiActivator.getUIService().getExitOnMainWindowClose())
+ if(getDefaultCloseOperation() == JFrame.EXIT_ON_CLOSE ||
+ getDefaultCloseOperation() == JFrame.DISPOSE_ON_CLOSE)
{
try
{
@@ -1919,10 +1940,17 @@ public class MainFrame
// On Mac systems the application is not quited on window close, so we
// don't need to warn the user.
- if (!GuiActivator.getUIService().getExitOnMainWindowClose()
- && !OSUtils.IS_MAC
- && GuiActivator.getSystrayService().checkInitialized())
+ if (OSUtils.IS_MAC)
{
+ return;
+ }
+
+ switch (getDefaultCloseOperation())
+ {
+ case JFrame.EXIT_ON_CLOSE:
+ case JFrame.DISPOSE_ON_CLOSE:
+ return;
+ case JFrame.HIDE_ON_CLOSE:
SwingUtilities.invokeLater(new Runnable()
{
public void run()
@@ -1941,12 +1969,11 @@ public class MainFrame
}
}
});
-
ConfigurationUtils.setApplicationVisible(false);
- if (ConfigurationUtils.isMinimizeInsteadOfHide())
- {
- this.minimize();
- }
+ break;
+ case JFrame.DO_NOTHING_ON_CLOSE:
+ this.minimize();
+ break;
}
}
diff --git a/src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java b/src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java
index fd9d43e..0b40798 100644
--- a/src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java
+++ b/src/net/java/sip/communicator/impl/osdependent/jdic/SystrayServiceJdicImpl.java
@@ -21,6 +21,8 @@ import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.net.*;
+import java.util.HashMap;
+import java.util.Map;
import javax.swing.*;
import javax.swing.event.*;
@@ -54,7 +56,6 @@ import com.apple.eawt.*;
public class SystrayServiceJdicImpl
extends AbstractSystrayService
{
-
/**
* The systray.
*/
@@ -130,7 +131,6 @@ public class SystrayServiceJdicImpl
super(OsDependentActivator.bundleContext);
SystemTray systray;
-
try
{
systray = SystemTray.getSystemTray();
@@ -146,10 +146,39 @@ public class SystrayServiceJdicImpl
logger.error("Failed to create a systray!", t);
}
}
- this.systray = systray;
+ this.systray = systray;
if (this.systray != null)
+ {
initSystray();
+ }
+ }
+
+ @Override
+ public Map<String, String> getSystrayModes()
+ {
+ return new HashMap<String, String>()
+ {{
+ put("disabled", "service.systray.mode.DISABLED");
+ if (java.awt.SystemTray.isSupported())
+ {
+ put("native", "service.systray.mode.NATIVE");
+ }
+
+ if (!OSUtils.IS_MAC && !OSUtils.IS_WINDOWS)
+ {
+ put("appindicator",
+ "service.systray.mode.APPINDICATOR");
+ put("appindicator_static",
+ "service.systray.mode.APPINDICATOR_STATIC");
+ }
+ }};
+ }
+
+ @Override
+ public String getActiveSystrayMode()
+ {
+ return SystemTray.getSystemTrayMode();
}
/**
@@ -323,8 +352,7 @@ public class SystrayServiceJdicImpl
});
initialized = true;
-
- uiService.setExitOnMainWindowClose(false);
+ uiService.setMainWindowCanHide(true);
}
/**
@@ -432,8 +460,6 @@ public class SystrayServiceJdicImpl
@Override
public boolean checkInitialized()
{
- if (!initialized)
- logger.error("Systray not init");
return initialized;
}
diff --git a/src/net/java/sip/communicator/impl/osdependent/systemtray/SystemTray.java b/src/net/java/sip/communicator/impl/osdependent/systemtray/SystemTray.java
index 74baa16..818d1e7 100644
--- a/src/net/java/sip/communicator/impl/osdependent/systemtray/SystemTray.java
+++ b/src/net/java/sip/communicator/impl/osdependent/systemtray/SystemTray.java
@@ -26,6 +26,7 @@ import org.jitsi.util.*;
import net.java.sip.communicator.impl.osdependent.*;
import net.java.sip.communicator.impl.osdependent.systemtray.appindicator.*;
import net.java.sip.communicator.impl.osdependent.systemtray.awt.*;
+import net.java.sip.communicator.service.systray.*;
import net.java.sip.communicator.util.Logger;
/**
@@ -33,11 +34,9 @@ import net.java.sip.communicator.util.Logger;
*/
public abstract class SystemTray
{
- private static final String PNMAE_DISABLE_TRY =
- "net.java.sip.communicator.osdependent.systemtray.DISABLE";
-
private static final Logger logger = Logger.getLogger(SystemTray.class);
private static SystemTray systemTray;
+ private static final String DISABLED_TRAY_MODE = "disabled";
/**
* Gets or creates the supported <tt>SystemTray</tt> implementations.
@@ -45,37 +44,78 @@ public abstract class SystemTray
*/
public final static SystemTray getSystemTray()
{
- boolean disable = OsDependentActivator.getConfigurationService()
- .getBoolean(PNMAE_DISABLE_TRY, false);
- if (disable || GraphicsEnvironment.isHeadless())
- {
- return null;
- }
-
if (systemTray == null)
{
- if (OSUtils.IS_LINUX)
+ String mode = getSystemTrayMode();
+ logger.info("Tray for " + mode + " requested");
+ switch (mode)
{
+ case DISABLED_TRAY_MODE:
+ return null;
+ case "native":
+ if (java.awt.SystemTray.isSupported())
+ {
+ systemTray = new AWTSystemTray();
+ }
+
+ break;
+ case "appindicator":
+ try
+ {
+ systemTray = new AppIndicatorTray(true);
+ }
+ catch(Exception ex)
+ {
+ logger.error("AppIndicator tray not available", ex);
+ }
+ break;
+ case "appindicator_static":
try
{
- systemTray = new AppIndicatorTray();
- return systemTray;
+ systemTray = new AppIndicatorTray(false);
}
catch(Exception ex)
{
- logger.info(ex.getMessage());
+ logger.error("AppIndicator tray not available", ex);
}
+
+ break;
}
- if (java.awt.SystemTray.isSupported())
+ if (systemTray == null)
{
- systemTray = new AWTSystemTray();
+ OsDependentActivator.getConfigurationService()
+ .setProperty(SystrayService.PNMAE_TRAY_MODE, "disabled");
}
}
return systemTray;
}
+ public static String getSystemTrayMode()
+ {
+ String defaultTrayMode = DISABLED_TRAY_MODE;
+ if (GraphicsEnvironment.isHeadless())
+ {
+ return DISABLED_TRAY_MODE;
+ }
+
+ // setting from cmd-line: request to disable tray in case it failed
+ if (Boolean.getBoolean("disable-tray"))
+ {
+ OsDependentActivator.getConfigurationService().setProperty(
+ SystrayService.PNMAE_TRAY_MODE, DISABLED_TRAY_MODE);
+ }
+
+ if (OSUtils.IS_WINDOWS || OSUtils.IS_MAC)
+ {
+ defaultTrayMode = "native";
+ }
+
+ return OsDependentActivator.getConfigurationService()
+ .getString(SystrayService.PNMAE_TRAY_MODE, defaultTrayMode);
+ }
+
/**
* Adds a <tt>TrayIcon</tt> to this system tray implementation.
*
diff --git a/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicatorTray.java b/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicatorTray.java
index 3f4e267..90c949a 100644
--- a/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicatorTray.java
+++ b/src/net/java/sip/communicator/impl/osdependent/systemtray/appindicator/AppIndicatorTray.java
@@ -32,25 +32,11 @@ import net.java.sip.communicator.util.*;
*/
public class AppIndicatorTray extends SystemTray
{
- private static final String PNMAE_APPINDICATOR_DISABLED =
- "net.java.sip.communicator.osdependent.systemtray.appindicator.DISABLED";
- private static final String PNMAE_APPINDICATOR_DYNAMIC_MENU =
- "net.java.sip.communicator.osdependent.systemtray.appindicator.DYNAMIC_MENU";
+ private boolean dynamicMenu;
- public AppIndicatorTray() throws Exception
+ public AppIndicatorTray(boolean dynamicMenu) throws Exception
{
- boolean disable = OsDependentActivator.getConfigurationService()
- .getBoolean(PNMAE_APPINDICATOR_DISABLED, false);
- if (disable)
- {
- throw new Exception("AppIndicator is disabled");
- }
-
- if (!OSUtils.IS_LINUX)
- {
- throw new Exception("Not running Linux, AppIndicator1 is not available");
- }
-
+ this.dynamicMenu = dynamicMenu;
try
{
// pre-initialize the JNA libraries before attempting to use them
@@ -74,7 +60,6 @@ public class AppIndicatorTray extends SystemTray
@Override
public TrayIcon createTrayIcon(ImageIcon icon, String tooltip, Object popup)
{
-
return new AppIndicatorTrayIcon(icon, tooltip, (JPopupMenu) popup);
}
@@ -88,7 +73,6 @@ public class AppIndicatorTray extends SystemTray
@Override
public boolean supportsDynamicMenu()
{
- return OsDependentActivator.getConfigurationService()
- .getBoolean(PNMAE_APPINDICATOR_DYNAMIC_MENU, true);
+ return dynamicMenu;
}
}
diff --git a/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java b/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java
index 6319455..04d55a5 100644
--- a/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java
+++ b/src/net/java/sip/communicator/plugin/generalconfig/GeneralConfigurationPanel.java
@@ -98,6 +98,13 @@ public class GeneralConfigurationPanel
=
"net.java.sip.communicator.plugin.generalconfig.localeconfig.DISABLED";
+ /**
+ * Indicates if the systray config panel should be disabled, i.e. not
+ * visible to the user.
+ */
+ private static final String SYSTRAY_CONFIG_DISABLED_PROP =
+ "net.java.sip.communicator.plugin.generalconfig.systrayconfig.DISABLED";
+
/**
* Indicates if the Call configuration panel should be disabled, i.e.
* not visible to the user.
@@ -169,6 +176,13 @@ public class GeneralConfigurationPanel
}
if(!GeneralConfigPluginActivator.getConfigurationService()
+ .getBoolean(SYSTRAY_CONFIG_DISABLED_PROP, false))
+ {
+ mainPanel.add(createSystrayeConfigPanel());
+ mainPanel.add(Box.createVerticalStrut(10));
+ }
+
+ if(!GeneralConfigPluginActivator.getConfigurationService()
.getBoolean(CALL_CONFIG_DISABLED_PROP, false))
{
mainPanel.add(createCallConfigPanel());
@@ -251,7 +265,7 @@ public class GeneralConfigurationPanel
{
boolean value = ((JCheckBox) e.getSource()).isSelected();
ConfigurationUtils.setIsMinimizeInsteadOfHide(value);
- UtilActivator.getUIService().setExitOnMainWindowClose(
+ UtilActivator.getUIService().setMainWindowCanHide(
!UtilActivator.getSystrayService().checkInitialized());
}
});
@@ -856,6 +870,72 @@ public class GeneralConfigurationPanel
return localeConfigPanel;
}
+ private static class Item
+ {
+ public String key;
+ public String value;
+
+ public Item(String key, String value)
+ {
+ this.key = key;
+ this.value = value;
+ }
+
+ @Override
+ public String toString()
+ {
+ return GeneralConfigPluginActivator.getResources()
+ .getI18NString(value);
+ }
+ }
+
+ /**
+ * Initializes the systray configuration panel.
+ * @return the created component
+ */
+ private Component createSystrayeConfigPanel()
+ {
+ JPanel panel = GeneralConfigPluginActivator.
+ createConfigSectionComponent(
+ Resources.getString("service.systray.MODE"));
+
+ final JComboBox<Item> systrayModes = new JComboBox<>();
+ SystrayService ss = GeneralConfigPluginActivator.getSystrayService();
+ for (Map.Entry<String, String> mode : ss.getSystrayModes().entrySet())
+ {
+ Item i = new Item(mode.getKey(), mode.getValue());
+ systrayModes.addItem(i);
+ if (mode.getKey().equals(ss.getActiveSystrayMode()))
+ {
+ systrayModes.setSelectedItem(i);
+ }
+ }
+
+ systrayModes.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ GeneralConfigPluginActivator.getConfigurationService()
+ .setProperty(SystrayService.PNMAE_TRAY_MODE,
+ ((Item) systrayModes.getSelectedItem()).key);
+ }
+ });
+
+ panel.add(systrayModes);
+ String label = "<html><body style='width:350px'>* " +
+ Resources.getString("service.systray.CLI_NOTE", new String[]{
+ Resources.getSettingsString("service.gui.APPLICATION_NAME")
+ }) + "</body></html>";
+ JLabel warnLabel = new JLabel(label);
+ warnLabel.setToolTipText(label);
+ warnLabel.setForeground(Color.GRAY);
+ warnLabel.setFont(warnLabel.getFont().deriveFont(8));
+ warnLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 8, 0));
+ panel.add(warnLabel);
+ return panel;
+ }
+
/**
* Creates the call configuration panel.
*
diff --git a/src/net/java/sip/communicator/service/gui/UIService.java b/src/net/java/sip/communicator/service/gui/UIService.java
index 33219d8..48994d4 100644
--- a/src/net/java/sip/communicator/service/gui/UIService.java
+++ b/src/net/java/sip/communicator/service/gui/UIService.java
@@ -157,26 +157,14 @@ public interface UIService
public void bringToFront();
/**
- * Sets the exitOnClose property. When TRUE, the user could exit the
- * application by simply closing the main application window (by clicking
- * the X button or pressing Alt-F4). When set to FALSE the main application
- * window will be only hidden.
- *
- * @param exitOnClose When TRUE, the user could exit the application by
- * simply closing the main application window (by clicking the X
- * button or pressing Alt-F4). When set to FALSE the main
- * application window will be only hidden.
- */
- public void setExitOnMainWindowClose(boolean exitOnClose);
-
- /**
- * Returns TRUE if the application could be exited by closing the main
- * application window, otherwise returns FALSE.
- *
- * @return Returns TRUE if the application could be exited by closing the
- * main application window, otherwise returns FALSE
+ * Called from the systray service when a tray has been initialized and
+ * hiding (instead of minimizing or exiting) is possible). If hiding is
+ * possible and the option to minimize is not selected, the application
+ * gets hidden on clicking 'X'.
+ *
+ * @param true if a tray icon was loaded.
*/
- public boolean getExitOnMainWindowClose();
+ public void setMainWindowCanHide(boolean exitOnClose);
/**
* Returns an exported window given by the <tt>WindowID</tt>. This could be
diff --git a/src/net/java/sip/communicator/service/systray/SystrayService.java b/src/net/java/sip/communicator/service/systray/SystrayService.java
index bcde841..9d88852 100644
--- a/src/net/java/sip/communicator/service/systray/SystrayService.java
+++ b/src/net/java/sip/communicator/service/systray/SystrayService.java
@@ -17,6 +17,8 @@
*/
package net.java.sip.communicator.service.systray;
+import java.util.*;
+
import net.java.sip.communicator.service.systray.event.*;
/**
@@ -27,6 +29,9 @@ import net.java.sip.communicator.service.systray.event.*;
*/
public interface SystrayService
{
+ public static final String PNMAE_TRAY_MODE =
+ "net.java.sip.communicator.osdependent.systemtray.MODE";
+
/**
* Message type corresponding to an error message.
*/
@@ -136,4 +141,19 @@ public interface SystrayService
* @param count The number of pending notifications.
*/
public void setNotificationCount(int count);
+
+ /**
+ * Gets a map of systray modes and resource-keys that describe them.
+ * @return key: mode for config property, value: resource key
+ */
+ public Map<String, String> getSystrayModes();
+
+ /**
+ * Gets the systray mode that was chosen at startup, either by default or as
+ * an override selected by the user.
+ *
+ * @return The selected mode or {@code disabled} if the user selected mode
+ * is not available.
+ */
+ public String getActiveSystrayMode();
}
diff --git a/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java b/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java
index 90041fc..d5cbf14 100644
--- a/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java
+++ b/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java
@@ -299,6 +299,11 @@ public class LaunchArgHandler
// do nothing already handled by startup script/binary
continue;
}
+ else if (args[i].startsWith("--notray"))
+ {
+ System.setProperty("disable-tray", "true");
+ continue;
+ }
//if this is the last arg and it's not an option then it's probably
//an URI
else if ( i == args.length - 1
@@ -521,6 +526,7 @@ public class LaunchArgHandler
System.out.println(" -6, --ipv6 prefer IPv6 addresses where possible only");
System.out.println(" -4, --ipv4 forces use of IPv4 only");
System.out.println(" -v, --version display the current version and exit");
+ System.out.println(" -n, --notray disable the tray icon and show the GUI");
}
/**