KDBusAddons

kdbusservice.h
1/*
2 This file is part of libkdbusaddons
3
4 SPDX-FileCopyrightText: 2011 David Faure <faure@kde.org>
5 SPDX-FileCopyrightText: 2011 Kevin Ottens <ervin@kde.org>
6
7 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
8*/
9
10#ifndef KDBUSSERVICE_H
11#define KDBUSSERVICE_H
12
13#include <QObject>
14#include <QUrl>
15#include <memory>
16
17#include <kdbusaddons_export.h>
18
19class KDBusServicePrivate;
20
21/**
22 * @class KDBusService kdbusservice.h <KDBusService>
23 *
24 * KDBusService takes care of registering the current process with D-Bus.
25 *
26 * This registers the application at a predictable location on D-Bus, registers
27 * the QCoreApplication (or subclass) object at /MainApplication, and
28 * assists in implementing the application side of D-Bus activation from
29 * the <a
30 * href="http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html">Desktop
31 * Entry Specification</a>.
32 *
33 * An application can either work in Multiple mode or Unique mode.
34 *
35 * In Multiple mode, the application can be launched many times. The service
36 * name in the D-Bus registration will contain the PID to distinguish the
37 * various instances; for example: <tt>org.kde.konqueror-12345</tt>.
38 *
39 * In Unique mode, only one instance of this application can ever run.
40 * The first instance of the application registers with D-Bus without the PID,
41 * and any attempt to run the application again will cause the
42 * activateRequested() signal to be emitted in the already-running instance; the
43 * duplicate instance will then quit. The exit value can be set by the already
44 * running instance with setExitValue(), the default value is @c 0.
45 *
46 * Unique-mode applications should usually delay parsing command-line arguments
47 * until after creating a KDBusService object; that way they know they are the
48 * original instance of the application.
49 *
50 * Applications that set the D-Bus activation entry (DBusActivatable=true) in
51 * their desktop files will use Unique mode and connect to the signals emitted
52 * by this class.
53 * Note that the D-Bus interface is exported for Multiple-mode applications as
54 * well, so it also makes sense for such applications to connect to the signals
55 * emitted by this class.
56 *
57 * @note In order to avoid a race, the application should export its objects to
58 * D-Bus before allowing the event loop to run (for example, by calling
59 * QCoreApplication::exec()). Otherwise, the application will appear on the bus
60 * before its objects are accessible via D-Bus, which could be a problem for
61 * other applications or scripts which start the application in order to talk
62 * D-Bus to it immediately.
63 *
64 * Example usage:
65 *
66 * @code
67 QApplication app(argc, argv);
68 app.setApplicationName("kuiserver");
69 app.setOrganizationDomain("kde.org");
70 // Create your D-Bus objects here
71 // ...
72 KDBusService service(KDBusService::Unique);
73 // If this point is reached, this is the only running instance
74 // i.e. org.kde.kuiserver has been registered
75 return app.exec();
76 * @endcode
77 *
78 * @since 5.0
79 */
80class KDBUSADDONS_EXPORT KDBusService : public QObject
81{
82 Q_OBJECT
83
84public:
85 /**
86 * Options to control the behaviour of KDBusService
87 * @see StartupOptions
88 */
90 /**
91 * Indicates that only one instance of this application should ever exist.
92 *
93 * Cannot be combined with @c Multiple.
94 */
95 Unique = 1,
96 /**
97 * Indicates that multiple instances of the application may exist.
98 *
99 * Cannot be combined with @c Unique. This is the default.
100 */
101 Multiple = 2,
102 /** Indicates that the application should not exit if it failed to
103 * register with D-Bus.
104 *
105 * If not set, KDBusService will quit the application if it failed to
106 * register the service with D-Bus or a @c Unique instance can not be
107 * activated. A @c Multiple instance will exit with error code @c 1.
108 * The exit value of a @c Unique instance can be set from the running
109 * instance with setExitValue(), the default value is @c 0.
110 */
111 NoExitOnFailure = 4,
112 /**
113 * Indicates that if there's already a unique service running, to be quit and replaced
114 * with our own.
115 *
116 * If exported, it will try first quitting the service calling @c org.qtproject.Qt.QCoreApplication.quit,
117 * which is exported by KDBusService by default.
118 *
119 * @since 5.65
120 */
121 Replace = 8
122 };
123 Q_ENUM(StartupOption)
124
125 /**
126 * Stores a combination of #StartupOption values.
127 */
129 Q_FLAG(StartupOptions)
130
131 /**
132 * Tries to register the current process to D-Bus at an address based on the
133 * application name and organization domain.
134 *
135 * The D-Bus service name is the reversed organization domain, followed by
136 * the application name. If @p options includes the @c Multiple flag, the
137 * application PID will be appended. For example,
138 * @code
139 * app.setApplicationName("kuiserver");
140 * app.setOrganizationDomain("kde.org");
141 * @endcode
142 * will make KDBusService register as @c org.kde.kuiserver in @c Unique
143 * mode, and @c org.kde.kuiserver-1234 (if the process has PID @c 1234) in
144 * @c Multiple mode.
145 */
146 explicit KDBusService(StartupOptions options = Multiple, QObject *parent = nullptr);
147
148 /**
149 * Destroys this object (but does not unregister the application).
150 *
151 * Deleting this object before unregister() is called (either manually or
152 * because QCoreApplication::aboutToQuit() was emitted) could confuse
153 * clients, who will see the service on the bus but will be unable to use
154 * the activation methods.
155 */
156 ~KDBusService() override;
157
158 /**
159 * Returns true if the D-Bus registration succeeded.
160 *
161 * Note that this is only useful when specifying the option NoExitOnFailure.
162 * Otherwise, the simple fact that this process is still running indicates
163 * that the registration succeeded.
164 */
165 bool isRegistered() const;
166
167 /**
168 * Returns the name of the D-Bus service registered by this class.
169 * Mostly useful when using the option Multiple.
170 * @since 5.33
171 */
172 QString serviceName() const;
173
174 /**
175 * Returns the error message from the D-Bus registration if it failed.
176 *
177 * Note that this is only useful when specifying the option NoExitOnFailure.
178 * Otherwise the process has quit by the time you can get a chance to call this.
179 */
180 QString errorMessage() const;
181
182 /**
183 * Sets the exit value to be used for a duplicate instance.
184 *
185 * If this is a @c Unique application, a slot connected to
186 * activateRequested() can use this to specify a non-zero exit value for the
187 * duplicate instance. This would typically be done if invalid command-line
188 * arguments are passed.
189 *
190 * Note that this will only work if the signal-slot connection type is
191 * Qt::DirectConnection.
192 *
193 * @param value The exit value for the duplicate instance.
194 */
195 void setExitValue(int value);
196
197Q_SIGNALS:
198 /**
199 * Signals that the application is to be activated.
200 *
201 * If this is a @c Unique application, when KDBusService is constructed in
202 * subsequent instances of the application (ie: when the executable is run
203 * when an instance is already running), it will cause this signal to be
204 * emitted in the already-running instance (with the arguments passed to the
205 * duplicate instance), and the duplicate instance will then exit.
206 *
207 * If this application's desktop file indicates that it supports D-Bus
208 * activation (DBusActivatable=true), a command launcher may also call the Activate()
209 * D-Bus method to trigger this signal. In this case, @p args will be empty.
210 *
211 * In single-window applications, the connected signal should typically
212 * raise the window.
213 *
214 * @param arguments The arguments the executable was called with, starting with the executable file name.
215 * See QCoreApplication::arguments().
216 * This can also be empty.
217 *
218 * A typical implementation of the signal handler would be:
219 * @code
220 * if (!arguments.isEmpty()) {
221 * commandLineParser->parse(arguments); // same QCommandLineParser instance as the one used in main()
222 * handleCmdLine(workingDirectory); // shared method with main(), which uses commandLineParser to handle options and positional arguments
223 * }
224 * @endcode
225 *
226 * For GUI applications, the handler also needs to deal with any platform-specific startup ids
227 * and make sure the mainwindow is shown as well as request its activation from the window manager.
228 * For X11, KDBusService makes the id for the Startup Notification protocol available
229 * from QX11Info::nextStartupId(), if there is one.
230 * For Wayland, KDBusService provides the token for the XDG Activation protocol in the
231 * "XDG_ACTIVATION_TOKEN" environment variable and unsets it again after the signal, if there is one.
232 * The util method @c KWindowSystem::updateStartupId(QWindow *window) (since KF 5.91) takes care of that.
233 * A typical implementation in the signal handler would be:
234 * @code
235 * mainWindow->show();
236 * KWindowSystem::updateStartupId(mainWindow->windowHandle());
237 * mainWindow->raise();
238 * KWindowSystem::activateWindow(mainWindow->windowHandle());
239 * @endcode
240 *
241 * If you're using the builtin handling of @c --help and @c --version in QCommandLineParser,
242 * you should call parser.process(arguments) before creating the KDBusService instance,
243 * since parse() doesn't handle those (and exiting the already-running instance would be wrong anyway).
244 *
245 * @see setExitValue()
246 */
247 void activateRequested(const QStringList &arguments, const QString &workingDirectory);
248
249 /**
250 * Signals that one or more files should be opened in the application.
251 *
252 * This signal is emitted to request handling of the respective method of the D-Bus activation.
253 * For GUI applications, the signal handler also needs to deal with any platform-specific startup ids
254 * and make sure the mainwindow is shown as well as request its activation from the window manager.
255 * See documentation of activateRequested(const QStringList &arguments, const QString &)
256 * for details.
257 *
258 * @param uris The URLs of the files to open.
259 */
260 void openRequested(const QList<QUrl> &uris);
261
262 /**
263 * Signals that an application action should be triggered.
264 *
265 * This signal is emitted to request handling of the respective method of the D-Bus activation.
266 * For GUI applications, the signal handler also needs to deal with any platform-specific startup ids
267 * and make sure the mainwindow is shown as well as request its activation from the window manager.
268 * See documentation of activateRequested(const QStringList &arguments, const QString &)
269 * for details.
270 *
271 * See the desktop entry specification for more information about action activation.
272 */
273 void activateActionRequested(const QString &actionName, const QVariant &parameter);
274
275public Q_SLOTS:
276 /**
277 * Unregister from D-Bus.
278 *
279 * This is called automatically when the application is about to quit, to
280 * make sure it doesn't keep receiving calls to its D-Bus interface while it
281 * is doing final cleanups.
282 */
283 void unregister();
284
285private:
286 // fdo.Application spec
287 KDBUSADDONS_NO_EXPORT void Activate(const QVariantMap &platform_data);
288 KDBUSADDONS_NO_EXPORT void Open(const QStringList &uris, const QVariantMap &platform_data);
289 KDBUSADDONS_NO_EXPORT void ActivateAction(const QString &action_name, const QVariantList &maybeParameter, const QVariantMap &platform_data);
290 friend class KDBusServiceAdaptor;
291
292 // org.kde.KDBusService
293 KDBUSADDONS_NO_EXPORT int CommandLine(const QStringList &arguments, const QString &workingDirectory, const QVariantMap &platform_data);
294 friend class KDBusServiceExtensionsAdaptor;
295
296private:
297 std::unique_ptr<KDBusServicePrivate> const d;
298};
299
300Q_DECLARE_OPERATORS_FOR_FLAGS(KDBusService::StartupOptions)
301
302#endif /* KDBUSSERVICE_H */
KDBusService takes care of registering the current process with D-Bus.
StartupOption
Options to control the behaviour of KDBusService.
Q_ENUM(...)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:13:12 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.