1/* This file is part of the KDE libraries
2 Copyright (c) 1999 Preston Brown <pbrown@kde.org>
3 Copyright (c) 2000-2001 Waldo Bastian <bastian@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#ifndef KUNIQUEAPP_H
22#define KUNIQUEAPP_H
23
24#include <kapplication.h>
25
26/**
27 * KUniqueApplication is a KApplication which only uses a single process. When
28 * a KUniqueApplication is started, it attempts to contact an existing copy
29 * of the application. If successful, the program asks the
30 * existing process to create a new instance by calling its newInstance() method
31 * and then exits. If there is no existing process then the program forks and
32 * calls the newInstance() method. When newInstance() is called, the application
33 * will typically create a new window or activate an existing one.
34 *
35 * Instances of KUniqueApplication can be made to behave like a normal application by passing
36 * the StartFlag::NonUniqueInstance flag to start().
37 *
38 * Please note that this supports only one process per KDE session. If
39 * your application can only be opened once per user or once per host, you
40 * need to ensure this independently of KUniqueApplication.
41 *
42 * The .desktop file for the application should state X-DBUS-StartupType=Unique,
43 * see ktoolinvocation.h
44 *
45 * If you use command line options before start() is called, you MUST call addCmdLineOptions()
46 * so that the KUniqueApplication-specific command-line options can still work.
47 *
48 * If your application is used to open files, it should also support the --tempfile
49 * option (see KCmdLineArgs::addTempFileOption()), to delete tempfiles after use.
50 * Add X-KDE-HasTempFileOption=true to the .desktop file to indicate this.
51 *
52 * @see KApplication
53 * @author Preston Brown <pbrown@kde.org>
54 */
55class KDEUI_EXPORT KUniqueApplication : public KApplication
56{
57 Q_OBJECT
58public:
59 /**
60 * Constructor. Takes command line arguments from KCmdLineArgs
61 *
62 * @param GUIenabled Set to false to disable all GUI stuff. This implies
63 * no styles either.
64 * @param configUnique If true, the uniqueness of the application will
65 * depend on the value of the "MultipleInstances"
66 * key in the "KDE" group of the application config file.
67 */
68 explicit KUniqueApplication( bool GUIenabled=true,
69 bool configUnique=false);
70
71#ifdef Q_WS_X11
72 /**
73 * Constructor. Takes command line arguments from KCmdLineArgs
74 *
75 * @param display Will be passed to Qt as the X display. The display
76 * must be valid and already opened.
77 *
78 * @param visual Pointer to the X11 visual that should be used by the
79 * application. If NULL, the default visual will be used instead.
80 *
81 * @param colormap The colormap that should be used by the application.
82 * If 0, the default colormap will be used instead.
83 *
84 * @param configUnique If true, the uniqueness of the application will
85 * depend on the value of the "MultipleInstances"
86 * key in the "KDE" group of the application config file.
87 */
88 explicit KUniqueApplication( Display *display,
89 Qt::HANDLE visual=0,
90 Qt::HANDLE colormap=0,
91 bool configUnique=false);
92#endif
93
94 /**
95 * Adds command line options specific for KUniqueApplication.
96 *
97 * Should be called before calling KUniqueApplication constructor
98 * and / or start().
99 */
100 static void addCmdLineOptions();
101
102 /**
103 * These flags can be used to specify how new instances of
104 * unique applications are created.
105 */
106 enum StartFlag
107 {
108 /**
109 * Create a new instance of the application in a new process and
110 * do not attempt to re-use an existing process.
111 *
112 * With this flag set, the new instance of the application will
113 * behave as if it were a plain KApplication rather than a KUniqueApplication.
114 *
115 * This is useful if you have an application where all instances are typically run
116 * in a single process but under certain circumstances new instances may require
117 * their own process.
118 */
119 NonUniqueInstance = 0x1
120 };
121 Q_DECLARE_FLAGS(StartFlags,StartFlag)
122
123 /**
124 * Forks and registers with D-Bus.
125 *
126 * The command line arguments are being sent via D-Bus to newInstance()
127 * and will be received once the application enters the event loop.
128 *
129 * Typically this is used like:
130 * \code
131 * int main(int argc, char **argv) {
132 * KAboutData about("myappname", 0, ki18n("myAppName"), .....);
133 * KCmdLineArgs::init(argc, argv, &about);
134 * KCmdLineArgs::addCmdLineOptions( myCmdOptions );
135 * KUniqueApplication::addCmdLineOptions();
136 *
137 * if (!KUniqueApplication::start()) {
138 * fprintf(stderr, "myAppName is already running!\n");
139 * return 0;
140 * }
141 * KUniqueApplication a;
142 * return a.exec();
143 * }
144 * \endcode
145 * Note that it's not necessary to call start() explicitly. It will be
146 * called automatically before creating KUniqueApplication if it hasn't
147 * been called yet, without any performance impact.
148 *
149 * Also note that you MUST call KUniqueApplication::addCmdLineOptions(),
150 * if you use command line options before start() is called.
151 *
152 * @param flags Optional flags which control how a new instance
153 * of the application is started.
154 * @return true if registration is successful.
155 * false if another process was already running.
156 */
157 static bool start(StartFlags flags);
158 // BIC: merge with start(StartFlags flags = StartFlags())
159 static bool start();
160
161 /**
162 * Destructor
163 */
164 virtual ~KUniqueApplication();
165
166 /**
167 * Creates a new "instance" of the application.
168 *
169 * Usually this will involve making some calls into the GUI portion of your
170 * application asking for a new window to be created, possibly with
171 * some data already loaded based on the arguments received.
172 *
173 * Command line arguments have been passed to KCmdLineArgs before this
174 * function is called and can be checked in the usual way.
175 *
176 * The default implementation ensures the mainwindow of the already
177 * running instance is shown and activated if necessary. If your
178 * application has only one mainwindow, you should call this default
179 * implementation and only add your special handling if needed.
180 *
181 * Note that newInstance() is called also in the first started
182 * application process.
183 *
184 * For applications that share one process for several mainwindows,
185 * the reimplementation could be:
186 * \code
187 int MyApp::newInstance()
188 {
189 KCmdLineArgs::setCwd(QDir::currentPath().toUtf8());
190 KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
191 static bool first = true;
192 if (args->count() > 0) {
193 for (int i = 0; i < args->count(); ++i) {
194 openWindow(args->url(i));
195 }
196 } else if( !first || !isSessionRestored()) {
197 openWindow(KUrl()); // create a new window
198 }
199 first = false;
200 args->clear();
201 return 0;
202 }
203 * \endcode
204 *
205 * @return An exit value. The calling process will exit with this value.
206 */
207 virtual int newInstance();
208
209 /**
210 * Returns whether newInstance() is being called while session
211 * restoration is in progress.
212 */
213 bool restoringSession();
214
215 /**
216 * @internal
217 */
218#ifndef KDE_NO_DEPRECATED
219 KDE_DEPRECATED static void setHandleAutoStarted();
220#endif
221
222private:
223 friend class KUniqueApplicationAdaptor;
224 class Private;
225 Private * const d;
226
227 Q_PRIVATE_SLOT(d, void _k_newInstanceNoFork())
228};
229Q_DECLARE_OPERATORS_FOR_FLAGS(KUniqueApplication::StartFlags)
230
231#endif
232