API review: KDBusApplicationStarter

Christoph Feck christoph at maxiom.de
Tue May 22 22:52:18 UTC 2012


On Tuesday 22 May 2012 23:03:22 David Faure wrote:
> I'm about to write this class for libkdbus
> (or possibly for Qt, if thiago thinks this could go into
> libQtDBus?), to replace KToolInvocation::startService*.
> 
> Comments welcome :-)
> 
> 
> /**
>  * KDBusApplicationStarter starts an application with QProcess, and
> waits for * it to register to D-Bus.
>  *
>  * This makes it possible to make D-Bus calls to the new process
> without the * risk of making these calls too early.
>  *
>  * @since 5.0
>  */
> class KDBUSADDONS_EXPORT KDBusApplicationStarter : public 
QObject
> {
>     Q_OBJECT
> 
> public:
>     /**
>      * Constructor.
>      */
>     explicit KDBusApplicationStarter(QObject *parent = 0);
> 
>     /**
>      * Destructor.
>      */
>     ~KDBusApplicationStarter();
> 
>     /**
>      * Sets the process to start.
>      * This method allows to use the full QProcess API, for things
> like setting the work directory. */
>     void setProcess(QProcess *process);
> 
>     /**
>      * Sets the D-Bus service name that we expect this process to
> register with. * For instance, korganizer will register as
> "org.kde.korganizer" */
>     void setExpectedServiceName(const QString& service);
> 
>     /**
>      * Starts the process, and returns immediately.
>      *
>      * Connect to the applicationReady signal to be notified that
> the application * has registered to D-Bus, or use waitForReady().
>      */
>     bool start(const QString &program, const QStringList &arguments
> = QStringList());

How immediately is immediately, i.e. does it return before trying to 
load the segment? What does the return value mean?

If it is supposed to return after loading the segment, I rather like 
non-blocking API, and have an "applicationFailed()" signal, so that it 
really can return immediately, instead of waiting for the process to 
load.

Additionally, even if the application could be loaded, it is still 
possible it could not register on the bus, for whatever reason, so 
that's another case for "applicationFailed()".

> 
>     /**
>      * Blocks until the application has registered to D-Bus.
>      *
>      * This doesn't use an event loop, so there is no risk of
> unexpected re-entrancy. */
>     bool waitForReady(int msecs = 30000);
> 
>     /**
>      * Returns the error string that can be shown to the user.
>      * This can be either an error coming from QProcess, or a
> timeout * waiting for the application to register to DBus.
>      */
>     QString errorString() const;
> 
>     /**
>      * Convenience method. Starts the given application and waits
> for it to register. */
>     static bool execute(const QString &program, const QString
> &expectedServiceName, const QStringList &arguments =
> QStringList(), QString *error = 0);
> 
> Q_SIGNALS:
>     /**
>      * Emitted when the process has registered to D-Bus.
>      */
>     void applicationReady(const QString& serviceName);
> };
> 
> In the simplest case, this allows to port directly:
> - int ret =
> KToolInvocation::startServiceByDesktopPath("kglobalaccel.desktop",
> QStringList(), &error); + bool ret =
> KDBusApplicationStarter::execute("kglobalaccel",
> "org.kde.kglobalaccel", QStringList(), &error);
> 
> Same for the code that starts kwalletd, kuiserver, knotify4, or
> kttsd. So all of the kdeui cases, actually.
> 
> All these are "unique applications" so setting an expected service
> name works. The other case, though, is starting a non-unique
> application (e.g. konqueror), to then talk dbus to it -- so the
> above is missing an enum ServiceMode { Unique, Multiple }, where
> Multiple watches for the first new process to register with
> expectedService + "-$PID".
> 
> I think what's also missing is to add a method to KService which
> returns a QProcess, all configured for starting the service
> (program, args, working dir). For more direct porting, i.e. to
> keep the idea of these things coming from the desktop file rather
> than being hardcoded in the calling code. For KRun. Hmm, not sure
> there's really a need for waiting until the app registers to DBus
> in the KRun case.... so let's postpone this part.

Christoph Feck (kdepepo)
KDE Quality Team


More information about the Kde-frameworks-devel mailing list