1 /****************************************************************************
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
6 ** This file is part of the Qt Solutions component.
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
14 ** * Redistributions of source code must retain the above copyright
15 ** notice, this list of conditions and the following disclaimer.
16 ** * Redistributions in binary form must reproduce the above copyright
17 ** notice, this list of conditions and the following disclaimer in
18 ** the documentation and/or other materials provided with the
20 ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 ** of its contributors may be used to endorse or promote products derived
22 ** from this software without specific prior written permission.
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
39 ****************************************************************************/
42 #include "qtsingleapplication.h"
43 #include "qtlocalpeer.h"
48 \class QtSingleApplication qtsingleapplication.h
49 \brief The QtSingleApplication class provides an API to detect and
50 communicate with running instances of an application.
52 This class allows you to create applications where only one
53 instance should be running at a time. I.e., if the user tries to
54 launch another instance, the already running instance will be
55 activated instead. Another usecase is a client-server system,
56 where the first started instance will assume the role of server,
57 and the later instances will act as clients of that server.
59 By default, the full path of the executable file is used to
60 determine whether two processes are instances of the same
61 application. You can also provide an explicit identifier string
62 that will be compared instead.
64 The application should create the QtSingleApplication object early
65 in the startup phase, and call isRunning() to find out if another
66 instance of this application is already running. If isRunning()
67 returns false, it means that no other instance is running, and
68 this instance has assumed the role as the running instance. In
69 this case, the application should continue with the initialization
70 of the application user interface before entering the event loop
71 with exec(), as normal.
73 The messageReceived() signal will be emitted when the running
74 application receives messages from another instance of the same
75 application. When a message is received it might be helpful to the
76 user to raise the application so that it becomes visible. To
77 facilitate this, QtSingleApplication provides the
78 setActivationWindow() function and the activateWindow() slot.
80 If isRunning() returns true, another instance is already
81 running. It may be alerted to the fact that another instance has
82 started by using the sendMessage() function. Also data such as
83 startup parameters (e.g. the name of the file the user wanted this
84 new instance to open) can be passed to the running instance with
85 this function. Then, the application should terminate (or enter
88 If isRunning() returns true, but sendMessage() fails, that is an
89 indication that the running instance is frozen.
91 Here's an example that shows how to convert an existing
92 application to use QtSingleApplication. It is very simple and does
93 not make use of all QtSingleApplication's functionality (see the
98 int main(int argc, char **argv)
100 QApplication app(argc, argv);
108 int main(int argc, char **argv)
110 QtSingleApplication app(argc, argv);
113 return !app.sendMessage(someDataString);
116 app.setActivationWindow(&mmw);
122 Once this QtSingleApplication instance is destroyed (normally when
123 the process exits or crashes), when the user next attempts to run the
124 application this instance will not, of course, be encountered. The
125 next instance to call isRunning() or sendMessage() will assume the
126 role as the new running instance.
128 For console (non-GUI) applications, QtSingleCoreApplication may be
129 used instead of this class, to avoid the dependency on the QtGui
132 \sa QtSingleCoreApplication
136 void QtSingleApplication::sysInit(const QString &appId)
139 peer = new QtLocalPeer(this, appId);
140 connect(peer, SIGNAL(messageReceived(const QString&)), SIGNAL(messageReceived(const QString&)));
145 Creates a QtSingleApplication object. The application identifier
146 will be QCoreApplication::applicationFilePath(). \a argc, \a
147 argv, and \a GUIenabled are passed on to the QAppliation constructor.
149 If you are creating a console application (i.e. setting \a
150 GUIenabled to false), you may consider using
151 QtSingleCoreApplication instead.
154 QtSingleApplication::QtSingleApplication(int &argc, char **argv, bool GUIenabled)
155 : QApplication(argc, argv, GUIenabled)
162 Creates a QtSingleApplication object with the application
163 identifier \a appId. \a argc and \a argv are passed on to the
164 QAppliation constructor.
167 QtSingleApplication::QtSingleApplication(const QString &appId, int &argc, char **argv)
168 : QApplication(argc, argv)
173 #if QT_VERSION < 0x050000
176 Creates a QtSingleApplication object. The application identifier
177 will be QCoreApplication::applicationFilePath(). \a argc, \a
178 argv, and \a type are passed on to the QAppliation constructor.
180 QtSingleApplication::QtSingleApplication(int &argc, char **argv, Type type)
181 : QApplication(argc, argv, type)
187 # if defined(Q_WS_X11)
189 Special constructor for X11, ref. the documentation of
190 QApplication's corresponding constructor. The application identifier
191 will be QCoreApplication::applicationFilePath(). \a dpy, \a visual,
192 and \a cmap are passed on to the QApplication constructor.
194 QtSingleApplication::QtSingleApplication(Display* dpy, Qt::HANDLE visual, Qt::HANDLE cmap)
195 : QApplication(dpy, visual, cmap)
201 Special constructor for X11, ref. the documentation of
202 QApplication's corresponding constructor. The application identifier
203 will be QCoreApplication::applicationFilePath(). \a dpy, \a argc, \a
204 argv, \a visual, and \a cmap are passed on to the QApplication
207 QtSingleApplication::QtSingleApplication(Display *dpy, int &argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
208 : QApplication(dpy, argc, argv, visual, cmap)
214 Special constructor for X11, ref. the documentation of
215 QApplication's corresponding constructor. The application identifier
216 will be \a appId. \a dpy, \a argc, \a
217 argv, \a visual, and \a cmap are passed on to the QApplication
220 QtSingleApplication::QtSingleApplication(Display* dpy, const QString &appId, int argc, char **argv, Qt::HANDLE visual, Qt::HANDLE cmap)
221 : QApplication(dpy, argc, argv, visual, cmap)
226 #endif // QT_VERSION < 0x050000
230 Returns true if another instance of this application is running;
233 This function does not find instances of this application that are
234 being run by a different user (on Windows: that are running in
240 bool QtSingleApplication::isRunning()
242 return peer->isClient();
247 Tries to send the text \a message to the currently running
248 instance. The QtSingleApplication object in the running instance
249 will emit the messageReceived() signal when it receives the
252 This function returns true if the message has been sent to, and
253 processed by, the current instance. If there is no instance
254 currently running, or if the running instance fails to process the
255 message within \a timeout milliseconds, this function return false.
257 \sa isRunning(), messageReceived()
259 bool QtSingleApplication::sendMessage(const QString &message, int timeout)
261 return peer->sendMessage(message, timeout);
266 Returns the application identifier. Two processes with the same
267 identifier will be regarded as instances of the same application.
269 QString QtSingleApplication::id() const
271 return peer->applicationId();
276 Sets the activation window of this application to \a aw. The
277 activation window is the widget that will be activated by
278 activateWindow(). This is typically the application's main window.
280 If \a activateOnMessage is true (the default), the window will be
281 activated automatically every time a message is received, just prior
282 to the messageReceived() signal being emitted.
284 \sa activateWindow(), messageReceived()
287 void QtSingleApplication::setActivationWindow(QWidget* aw, bool activateOnMessage)
290 if (activateOnMessage)
291 connect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
293 disconnect(peer, SIGNAL(messageReceived(const QString&)), this, SLOT(activateWindow()));
298 Returns the applications activation window if one has been set by
299 calling setActivationWindow(), otherwise returns 0.
301 \sa setActivationWindow()
303 QWidget* QtSingleApplication::activationWindow() const
310 De-minimizes, raises, and activates this application's activation window.
311 This function does nothing if no activation window has been set.
313 This is a convenience function to show the user that this
314 application instance has been activated when he has tried to start
317 This function should typically be called in response to the
318 messageReceived() signal. By default, that will happen
319 automatically, if an activation window has been set.
321 \sa setActivationWindow(), messageReceived(), initialize()
323 void QtSingleApplication::activateWindow()
326 actWin->setWindowState(actWin->windowState() & ~Qt::WindowMinimized);
328 actWin->activateWindow();
334 \fn void QtSingleApplication::messageReceived(const QString& message)
336 This signal is emitted when the current instance receives a \a
337 message from another instance of this application.
339 \sa sendMessage(), setActivationWindow(), activateWindow()
344 \fn void QtSingleApplication::initialize(bool dummy = true)