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 
19 class 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  */
80 class KDBUSADDONS_EXPORT KDBusService : public QObject
81 {
82  Q_OBJECT
83 
84 public:
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  */
128  Q_DECLARE_FLAGS(StartupOptions, StartupOption)
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 
197 Q_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 
275 public 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 
285 private:
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 
296 private:
297  std::unique_ptr<KDBusServicePrivate> const d;
298 };
299 
300 Q_DECLARE_OPERATORS_FOR_FLAGS(KDBusService::StartupOptions)
301 
302 #endif /* KDBUSSERVICE_H */
Q_ENUM(...)
StartupOption
Options to control the behaviour of KDBusService.
Definition: kdbusservice.h:89
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Thu Feb 15 2024 03:49:05 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.