Trying to launch a second instance of SIP Communicator now brings the first one to front

Clicking on the systray icon when SC is minimized, now restores it
    also, when SC is on another desktop the systray click now takes you to that desktop
cusax-fix
Emil Ivov 18 years ago
parent 88a0036d18
commit 046b8ff337

@ -31,7 +31,7 @@ public class ArgDelegationActivator
* A reference to the delegation peer implementation that is currently
* handling uri arguments.
*/
private UriDelegationPeerImpl delegationPeer = null;
private ArgDelegationPeerImpl delegationPeer = null;
/**
* A reference to the <tt>UIService</tt> currently in use in
@ -49,7 +49,7 @@ public class ArgDelegationActivator
public void start(BundleContext bc) throws Exception
{
bundleContext = bc;
delegationPeer = new UriDelegationPeerImpl(bc);
delegationPeer = new ArgDelegationPeerImpl(bc);
bc.addServiceListener(delegationPeer);
//register our instance of delegation peer.

@ -24,11 +24,11 @@
*
* @author Emil Ivov
*/
public class UriDelegationPeerImpl
implements UriDelegationPeer, ServiceListener
public class ArgDelegationPeerImpl
implements ArgDelegationPeer, ServiceListener
{
private static final Logger logger =
Logger.getLogger(UriDelegationPeerImpl.class);
Logger.getLogger(ArgDelegationPeerImpl.class);
/**
* The list of uriHandlers that we are currently aware of.
@ -38,12 +38,12 @@ public class UriDelegationPeerImpl
/**
* Creates an instance of this peer and scans <tt>bundleContext</tt> for all
* existing <tt>UriHandler</tt>s
* existing <tt>UriHandler</tt>
*
* @param bundleContext a reference to a currently valid instance of a
* bundle context.
*/
public UriDelegationPeerImpl(BundleContext bundleContext)
public ArgDelegationPeerImpl(BundleContext bundleContext)
{
ServiceReference[] uriHandlerRefs = null;
@ -182,5 +182,17 @@ public void handleUri(String uriArg)
}
}
/**
* This method would simply bring the application on focus as it is called
* when the user has tried to launch a second instance of SIP Communicator
* while a first one was already running. Future implementations may also
* show an error/information message to the user notifying them that a
* second instance is not to be launched.
*/
public void handleConcurrentInvocationRequest()
{
ArgDelegationActivator.getUIService().setVisible(true);
}
}

@ -1579,6 +1579,7 @@ public void run()
{
MainFrame.this.addNativePlugins();
MainFrame.super.setVisible(isVisible);
MainFrame.super.setExtendedState(MainFrame.NORMAL);
MainFrame.super.toFront();
}
else

@ -72,9 +72,9 @@ public class SystrayServiceJdicImpl
private int maxMessageNumber = 3;
private SystrayMessage aggregatedMessage;
/**
* Stores the system time, when the main window was restored the last time
* Stores the system time, when the main window was restored the last time
*/
private long setVisibleTime = 0;
@ -95,14 +95,14 @@ public class SystrayServiceJdicImpl
private ImageIcon logoIconWhite;
private ImageIcon envelopeIcon;
private ImageIcon envelopeIconWhite;
/**
* The dock Icons used only in Mac version
*/
private URL dockIconOffline;
private URL dockIconAway;
private URL dockIconFFC;
private boolean initialized = false;
/**
@ -153,7 +153,7 @@ private void initSystray()
logoIconFFC = Resources.getImage("trayIconWindowsFFC");
envelopeIcon = Resources.getImage("messageIconWindows");
}
// If we're running under MacOSX, we use a special black and
// If we're running under MacOSX, we use a special black and
// white icons without background.
else if (osName.startsWith("Mac OS X"))
{
@ -173,19 +173,19 @@ else if (osName.startsWith("Mac OS X"))
if (!osName.startsWith("Mac OS X"))
{
// default to set offline , if any protocols become
// default to set offline , if any protocols become
// online will set it to online
currentIcon = logoIconOffline;
}
else
currentIcon = logoIcon;
trayIcon = new TrayIcon(currentIcon,
Resources.getApplicationString("applicationName"),
menu);
trayIcon.setIconAutoSize(true);
if (osName.startsWith("Mac OS X"))
{
// init dock Icons
@ -208,7 +208,7 @@ public void actionPerformed(ActionEvent e)
if (isVisible) {
setVisibleTime = currentTime;
}
else if (currentTime < (setVisibleTime + doubleClickSpeed))
else if (currentTime < (setVisibleTime + doubleClickSpeed))
{
// Do nothing. the last restore is less than 2 seconds, so it is very
// likely, that the user made a double click. prevent the main window
@ -227,7 +227,7 @@ else if (currentTime < (setVisibleTime + doubleClickSpeed))
}
});
// Change the MacOSX icon with the white one when the popup
// Change the MacOSX icon with the white one when the popup
// menu appears
if (osName.startsWith("Mac OS X"))
{
@ -243,11 +243,11 @@ public void popupMenuWillBecomeVisible(PopupMenuEvent e)
else
{
trayIcon.setIcon(logoIconWhite);
currentIcon = logoIconWhite;
currentIcon = logoIconWhite;
}
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
{
if (currentIcon == envelopeIconWhite)
{
@ -260,11 +260,11 @@ public void popupMenuWillBecomeInvisible(PopupMenuEvent e)
currentIcon = logoIcon;
}
}
public void popupMenuCanceled(PopupMenuEvent e)
public void popupMenuCanceled(PopupMenuEvent e)
{
popupMenuWillBecomeInvisible(e);
}
}
});
}
@ -297,8 +297,8 @@ public void actionPerformed(ActionEvent e)
* Saves the last status for all accounts. This information is used
* on logging. Each time user logs in he's logged with the same status
* as he was the last time before closing the application.
*
* @param protocolProvider the protocol provider for which we save the
*
* @param protocolProvider the protocol provider for which we save the
* last selected status
* @param statusName the status name to save
*/
@ -359,10 +359,10 @@ public void saveStatusInformation(
* Implements the <tt>SystratService.showPopupMessage</tt> method. Shows
* a pop up message, above the Systray icon, which has the given title,
* message content and message type.
*
*
* @param title the title of the message
* @param messageContent the content text
* @param messageType the type of the message
* @param messageType the type of the message
*/
public void showPopupMessage( String title,
String messageContent,
@ -370,7 +370,7 @@ public void showPopupMessage( String title,
{
if(!checkInitialized())
return;
int trayMsgType = TrayIcon.NONE_MESSAGE_TYPE;
if (messageType == SystrayService.ERROR_MESSAGE_TYPE)
@ -391,7 +391,7 @@ else if (messageType == SystrayService.WARNING_MESSAGE_TYPE)
/**
* Implements the <tt>SystrayService.addPopupMessageListener</tt> method.
*
*
* @param listener the listener to add
*/
public void addPopupMessageListener(SystrayPopupMessageListener listener)
@ -404,7 +404,7 @@ public void addPopupMessageListener(SystrayPopupMessageListener listener)
/**
* Implements the <tt>SystrayService.removePopupMessageListener</tt> method.
*
*
* @param listener the listener to remove
*/
public void removePopupMessageListener(SystrayPopupMessageListener listener)
@ -418,7 +418,7 @@ public void removePopupMessageListener(SystrayPopupMessageListener listener)
/**
* Notifies all interested listeners that a <tt>SystrayPopupMessageEvent</tt>
* has occured.
*
*
* @param sourceObject the source of this event
*/
private void firePopupMessageEvent(Object sourceObject)
@ -445,16 +445,16 @@ private void firePopupMessageEvent(Object sourceObject)
/**
* Sets a new Systray icon.
*
*
* @param imageType the type of the image to set.
*/
public void setSystrayIcon(int imageType)
{
if(!checkInitialized())
return;
String osName = System.getProperty("os.name");
ImageIcon toChangeSystrayIcon = null;
if (imageType == SystrayService.SC_IMG_TYPE)
@ -500,13 +500,13 @@ else if (imageType == SystrayService.ENVELOPE_IMG_TYPE)
toChangeSystrayIcon = envelopeIcon;
}
}
if(toChangeSystrayIcon != null)
{
this.trayIcon.setIcon(toChangeSystrayIcon);
this.currentIcon = toChangeSystrayIcon;
}
if (osName.startsWith("Mac OS X"))
{
URL toChangeDockIcon = null;
@ -522,7 +522,7 @@ else if (imageType == SystrayService.ENVELOPE_IMG_TYPE)
case SystrayService.SC_IMG_FFC_TYPE :
toChangeDockIcon = dockIconFFC; break;
}
try
{
if(toChangeDockIcon != null)
@ -538,7 +538,7 @@ else if (imageType == SystrayService.ENVELOPE_IMG_TYPE)
}
}
}
private boolean checkInitialized()
{
if(!initialized)
@ -549,7 +549,7 @@ private boolean checkInitialized()
else
return true;
}
/**
* Shows the oldest message in the message queue and then removes it from
* the queue.
@ -616,7 +616,7 @@ private class SystrayMessage
* Creates an instance of <tt>SystrayMessage</tt> by specifying the
* message <tt>title</tt>, the content of the message and the type of
* the message.
*
*
* @param title the title of the message
* @param messageContent the content of the message
* @param messageType the type of the message
@ -635,7 +635,7 @@ public SystrayMessage( String title,
* message <tt>title</tt>, the content of the message, the type of
* the message and the number of messages that this message has
* aggregated.
*
*
* @param messageContent the content of the message
* @param aggregatedMessageNumber the number of messages that this
* message has aggregated
@ -655,7 +655,7 @@ public SystrayMessage( String messageContent,
/**
* Returns the title of the message.
*
*
* @return the title of the message
*/
public String getTitle()
@ -665,7 +665,7 @@ public String getTitle()
/**
* Returns the message content.
*
*
* @return the message content
*/
public String getMessageContent()
@ -675,7 +675,7 @@ public String getMessageContent()
/**
* Returns the message type.
*
*
* @return the message type
*/
public int getMessageType()
@ -685,7 +685,7 @@ public int getMessageType()
/**
* Returns the number of aggregated messages this message represents.
*
*
* @return the number of aggregated messages this message represents.
*/
public int getAggregatedMessageNumber()
@ -696,7 +696,7 @@ public int getAggregatedMessageNumber()
/**
* Adds the given number of messages to the number of aggregated
* messages contained in this message.
*
*
* @param messageNumber the number of messages to add to the number of
* aggregated messages contained in this message
*/

@ -81,10 +81,10 @@ else if (osName.startsWith("Windows"))
System.exit(argHandler.getErrorCode());
}
//lock our config di so that we would only have a single instance of
//lock our config dir so that we would only have a single instance of
//sip communicator, no matter how many times we start it (use mainly
//for handling sip: uris after starting the application)
if ( argHandlerRes != LaunchArgHandler.ACTION_CONTINUE_MULTIINSTANCE )
if ( argHandlerRes != LaunchArgHandler.ACTION_CONTINUE_LOCK_DISABLED )
{
SipCommunicatorLock lock = new SipCommunicatorLock();

@ -15,7 +15,7 @@
*
* @author Emil Ivov
*/
public interface UriDelegationPeer
public interface ArgDelegationPeer
{
/**
* Handles <tt>uriArg</tt> in whatever way it finds fit.
@ -23,4 +23,13 @@ public interface UriDelegationPeer
* @param uriArg the uri argument that this delegate has to handle.
*/
public void handleUri(String uriArg);
/**
* Called when the user has tried to launch a second instance of
* SIP Communicator while a first one was already running. A typical
* implementation of this method would simply bring the application on
* focus but it may also show an error/information message to the user
* notifying them that a second instance is not to be launched.
*/
public void handleConcurrentInvocationRequest();
}

@ -10,25 +10,26 @@
import net.java.sip.communicator.util.*;
/**
* The <tt>UriArgManager</tt> implements an utility for handling URIs that have
* been passed as command line arguments. The class maintains a list of
* registered delegates that do the actual URI handling. The UriArgDelegator
* is previewed for use with SIP Communicator argdelegation service. It would
* therefore record all URIs until the corresponding DelegationPeer has been
* registered with the UriArgManager.
* The <tt>ArgDelegator</tt> implements an utility for handling args that have
* been passed as command line arguments but that need the OSGi environment
* and SIP Communicator to be fully loaded. The class maintains a list of
* registered delegates (<tt>ArgDelegationPeer</tt>s) that do the actual arg
* handling. The <tt>ArgDelegator</tt> is previewed for use with the SIP
* Communicator argdelegation service. It would therefore record all args
* until the corresponding <tt>DelegationPeer</tt> has registered here.
*
* @author Emil Ivov
*/
class UriArgManager
class ArgDelegator
{
private static final Logger logger = Logger.getLogger(UriArgManager.class);
private static final Logger logger = Logger.getLogger(ArgDelegator.class);
/**
* The delegation peer that we pass arguments to. This peer is going to
* get set only after Felix starts and all its services have been properly
* loaded.
*/
private UriDelegationPeer uriDelegationPeer = null;
private ArgDelegationPeer uriDelegationPeer = null;
/**
* We use this list to store arguments that we have been asked to handle
@ -64,7 +65,7 @@ protected void handleUri(String uriArg)
* @param delegationPeer the delegation peer that we can use to deliver
* command line URIs to.
*/
public void setDelegationPeer(UriDelegationPeer delegationPeer)
public void setDelegationPeer(ArgDelegationPeer delegationPeer)
{
synchronized(recordedArgs)
{
@ -81,4 +82,22 @@ public void setDelegationPeer(UriDelegationPeer delegationPeer)
recordedArgs.clear();
}
}
/**
* Called when the user has tried to launch a second instance of
* SIP Communicator while a first one was already running. This method
* simply calls its peer method from the <tt>ArgDelegationPeer</tt> and
* does nothing if no peer is currently registered.
*/
public void handleConcurrentInvocationRequest()
{
synchronized(recordedArgs)
{
if(uriDelegationPeer != null)
{
uriDelegationPeer.handleConcurrentInvocationRequest();
}
}
}
}

@ -66,7 +66,7 @@ public class LaunchArgHandler
* successfully parsed and one of them indicates that the user has requested
* a multi instance launch.
*/
public static final int ACTION_CONTINUE_MULTIINSTANCE = 3;
public static final int ACTION_CONTINUE_LOCK_DISABLED = 3;
/**
* The error code returned when we couldn't parse one of the options.
@ -112,7 +112,7 @@ public class LaunchArgHandler
/**
* A reference to the instance of the
*/
private UriArgManager uriArgManager = new UriArgManager();
private ArgDelegator argDelegator = new ArgDelegator();
/**
* The singleton instance of this handler.
@ -205,7 +205,8 @@ else if (args[i].equals("-c"))
//make sure we have at least one more argument left.
if( i == args.length - 1)
{
System.out.println("The \"-c\" option expects a directory parameter.");
System.out.println(
"The \"-c\" option expects a directory parameter.");
returnAction = ACTION_ERROR;
break;
}
@ -214,7 +215,7 @@ else if (args[i].equals("-c"))
}
else if (args[i].equals("--multiple") || args[i].equals("-m"))
{
handleMultipleArg(args[i]);
returnAction = ACTION_CONTINUE_LOCK_DISABLED;
continue;
}
//if this is the last arg and it's not an option then it's probably
@ -245,7 +246,7 @@ else if ( i == args.length - 1
private void handleUri(String uri)
{
logger.trace("Handling uri "+ uri);
uriArgManager.handleUri(uri);
argDelegator.handleUri(uri);
}
/**
@ -256,15 +257,6 @@ private void handleDebugArg(String arg)
System.out.println("Option " + arg + " is not yet implemented!");
}
/**
* Instructs SIP Communicator to allow for more than a single running
* instance.
*/
private void handleMultipleArg(String arg)
{
System.out.println("Option " + arg + " is not yet implemented!");
}
/**
* Instructs SIP Communicator to allow for more than a single running
* instance.
@ -397,8 +389,35 @@ public int getErrorCode()
* @param delegationPeer the <tt>delegationPeer</tt> that should handle URIs
* or <tt>null</tt> if we'd like to unset a previously set peer.
*/
public void setDelegationPeer(UriDelegationPeer delegationPeer)
public void setDelegationPeer(ArgDelegationPeer delegationPeer)
{
this.argDelegator.setDelegationPeer(delegationPeer);
}
/**
* Called when the user has tried to launch a second instance of
* SIP Communicator while a first one was already running. This method
* only handles arguments that need to be handled by a running instance
* of SIP Communicator assuming that simple ones such as "--version" or
* "--help" have been handled by the calling instance.
*
* @param args the args that we need to handle.
*/
public void handleConcurrentInvocationRequestArgs(String[] args)
{
this.uriArgManager.setDelegationPeer(delegationPeer);
//if the arg list is empty, then we simply notify SC of the request
//so that it could do stuff like showing the contact list for example.
if(args.length == 0)
{
this.argDelegator.handleConcurrentInvocationRequest();
}
//if we 1 or more args then we only handle the last one as the only
//interinstance arg we currently know how to handle are URIs. Change
//this if we one day implement fun stuff like inter instance command
//execution.
else if(args.length >=1)
{
this.argDelegator.handleUri(args[args.length -1]);
}
}
}

@ -769,7 +769,8 @@ else if (line.startsWith(ARGUMENT))
// now let's handle what we've got
String[] args = new String[argsList.size()];
LaunchArgHandler.getInstance().handleArgs(
LaunchArgHandler.getInstance()
.handleConcurrentInvocationRequestArgs(
argsList.toArray(args));
}
catch (IOException exc)

Loading…
Cancel
Save