diff --git a/includes/CMakeLists.txt b/includes/CMakeLists.txt index 2363bd2f..2f90510a 100644 --- a/includes/CMakeLists.txt +++ b/includes/CMakeLists.txt @@ -342,7 +342,6 @@ install( NETRootInfo NETWinInfo OrgKdeKDirNotifyInterface - OrgKdeKLauncherInterface ThumbCreator KCategorizedView KCategoryDrawer diff --git a/includes/OrgKdeKLauncherInterface b/includes/OrgKdeKLauncherInterface deleted file mode 100644 index bfa89b17..00000000 --- a/includes/OrgKdeKLauncherInterface +++ /dev/null @@ -1 +0,0 @@ -#include "../klauncher_iface.h" diff --git a/kdecore/CMakeLists.txt b/kdecore/CMakeLists.txt index 873d4002..41c9f308 100644 --- a/kdecore/CMakeLists.txt +++ b/kdecore/CMakeLists.txt @@ -160,7 +160,6 @@ set(kdecore_LIB_SRCS util/kdedmodule.cpp util/kdevicedatabase.cpp util/kdeversion.cpp - util/klauncher_iface.cpp util/kmacroexpander.cpp util/kpluginfactory.cpp util/kpluginloader.cpp @@ -300,7 +299,6 @@ install( util/kde_file.h util/kdedmodule.h util/kdevicedatabase.h - util/klauncher_iface.h util/kmacroexpander.h util/kpluginfactory.h util/kpluginloader.h diff --git a/kdecore/kernel/ktoolinvocation.cpp b/kdecore/kernel/ktoolinvocation.cpp index 028ed302..28b5982c 100644 --- a/kdecore/kernel/ktoolinvocation.cpp +++ b/kdecore/kernel/ktoolinvocation.cpp @@ -35,7 +35,34 @@ #include #include -static inline void printError(const QString& text, QString* error) +#define KTOOLINVOCATION_TIMEOUT 250 +#define KTOOLINVOCATION_SLEEPTIME 150 + +// NOTE: keep in sync with: +// kdelibs/kinit/klauncher_adaptor.h +static inline QString getKLauncherError(const int result, const QString &app) +{ + switch (result) { + case -1: { + return i18n("Application service is not valid or does not support multiple files: %1.", app); + } + case -2: { + return i18n("Application not found: %1.", app); + } + case -3: { + return i18n("Application could not be processed: %1.", app); + } + case -4: { + return i18n("Application failed to start: %1.", app); + } + case -5: { + return i18n("D-Bus error occured while starting application: %1.", app); + } + } + return i18n("Unknown KLauncher error for application: %1.", app); +} + +static inline void printError(const QString &text, QString *error) { if (error) *error = text; @@ -53,10 +80,12 @@ KToolInvocation::KToolInvocation() : QObject(0), klauncherIface(nullptr) { - klauncherIface = new org::kde::KLauncher( + klauncherIface = new QDBusInterface( QString::fromLatin1("org.kde.klauncher"), QString::fromLatin1("/KLauncher"), - QDBusConnection::sessionBus() + QString::fromLatin1("org.kde.KLauncher"), + QDBusConnection::sessionBus(), + this ); } @@ -67,130 +96,124 @@ KToolInvocation::~KToolInvocation() void KToolInvocation::setLaunchEnv(const QString &name, const QString &value) { - self()->klauncherIface->setLaunchEnv(name, value); + self()->klauncherIface->asyncCall(QString::fromLatin1("setLaunchEnv"), name, value); } int KToolInvocation::startServiceInternal(const char *_function, - const QString& name, const QStringList &URLs, - QString *error, QString *serviceName, qint64 *pid, - const QByteArray& startup_id, bool noWait, - const QString& workdir) + const QString &name, const QStringList &URLs, + QString *error, + const QByteArray &startup_id, bool noWait, + const QString &workdir) { QString function = QString::fromLatin1(_function); - QDBusMessage msg = QDBusMessage::createMethodCall( - klauncherIface->service(), - klauncherIface->path(), - klauncherIface->interface(), - function - ); - msg << name << URLs; - if (function == QLatin1String("kdeinit_exec_with_workdir")) - msg << workdir; -#ifdef Q_WS_X11 // make sure there is id, so that user timestamp exists QStringList envs; - QByteArray s = startup_id; - emit kapplication_hook(envs, s); - msg << envs; - msg << QString::fromLatin1(s, s.size()); -#else - msg << QStringList(); - msg << QString(); -#endif - if( !function.startsWith( QLatin1String("kdeinit_exec") ) ) - msg << noWait; + QByteArray asn = startup_id; + emit kapplication_hook(envs, asn); - QDBusMessage reply = QDBusConnection::sessionBus().call(msg, QDBus::Block, INT_MAX); - if ( reply.type() != QDBusMessage::ReplyMessage ) - { - QDBusReply replyObj(reply); - if (replyObj.error().type() == QDBusError::NoReply) { - printError(i18n("Error launching %1. Either KLauncher is not running anymore, or it failed to start the application.", name), error); - } else { - const QString rpl = reply.arguments().count() > 0 ? reply.arguments().at(0).toString() : reply.errorMessage(); - printError(i18n("KLauncher could not be reached via D-Bus. Error when calling %1:\n%2\n",function, rpl), error); - } - //qDebug() << reply; + QDBusPendingReply reply; + if (qstrcmp(_function, "kdeinit_exec_with_workdir") == 0) { + reply = klauncherIface->asyncCall( + function, name, URLs, envs, QString::fromLatin1(asn, asn.size()), workdir + ); + } else if (qstrcmp(_function, "start_service_by_desktop_name") == 0 || qstrcmp(_function, "start_service_by_desktop_path") == 0) { + reply = klauncherIface->asyncCall( + function, name, URLs, envs, QString::fromLatin1(asn, asn.size()), noWait + ); + } else { + reply = klauncherIface->asyncCall( + function, name, URLs, envs, QString::fromLatin1(asn, asn.size()) + ); + } + kDebug() << "Waiting for klauncher call to finish" << function; + while (!reply.isFinished()) { + QCoreApplication::processEvents(QEventLoop::AllEvents, KTOOLINVOCATION_TIMEOUT); + QThread::msleep(KTOOLINVOCATION_SLEEPTIME); + } + kDebug() << "Done waiting for klauncher call to finish" << function; + if (!reply.isValid()) { + printError( + i18n("KLauncher error: %1.", reply.error().message()), + error + ); return EINVAL; } - if (noWait) - return 0; - - Q_ASSERT(reply.arguments().count() == 4); - if (serviceName) - *serviceName = reply.arguments().at(1).toString(); - if (error) - *error = reply.arguments().at(2).toString(); - if (pid) - *pid = reply.arguments().at(3).toLongLong(); - return reply.arguments().at(0).toInt(); + const int result = reply.value(); + if (result < 0) { + printError( + getKLauncherError(result, name), + error + ); + // compat + return -result; + } else if (result != 0) { + printError( + i18n("Application failed to start: %1.", name), + error + ); + } + return result; } - - -int -KToolInvocation::startServiceByDesktopPath( const QString& name, const QString &URL, - QString *error, QString *serviceName, - qint64 *pid, const QByteArray& startup_id, bool noWait ) +int KToolInvocation::startServiceByDesktopPath(const QString &name, const QString &URL, + QString *error, + const QByteArray &startup_id, bool noWait) { QStringList URLs; if (!URL.isEmpty()) URLs.append(URL); return self()->startServiceInternal("start_service_by_desktop_path", - name, URLs, error, serviceName, pid, startup_id, noWait); + name, URLs, error, startup_id, noWait); } -int -KToolInvocation::startServiceByDesktopPath( const QString& name, const QStringList &URLs, - QString *error, QString *serviceName, qint64 *pid, - const QByteArray& startup_id, bool noWait ) +int KToolInvocation::startServiceByDesktopPath(const QString &name, const QStringList &URLs, + QString *error, + const QByteArray &startup_id, bool noWait) { return self()->startServiceInternal("start_service_by_desktop_path", - name, URLs, error, serviceName, pid, startup_id, noWait); + name, URLs, error, startup_id, noWait); } -int -KToolInvocation::startServiceByDesktopName( const QString& name, const QString &URL, - QString *error, QString *serviceName, qint64 *pid, - const QByteArray& startup_id, bool noWait ) +int KToolInvocation::startServiceByDesktopName(const QString& name, const QString &URL, + QString *error, + const QByteArray &startup_id, bool noWait) { QStringList URLs; if (!URL.isEmpty()) URLs.append(URL); return self()->startServiceInternal("start_service_by_desktop_name", - name, URLs, error, serviceName, pid, startup_id, noWait); + name, URLs, error, startup_id, noWait); } -int -KToolInvocation::startServiceByDesktopName( const QString& name, const QStringList &URLs, - QString *error, QString *serviceName, qint64 *pid, - const QByteArray& startup_id, bool noWait ) +int KToolInvocation::startServiceByDesktopName(const QString &name, const QStringList &URLs, + QString *error, + const QByteArray &startup_id, bool noWait) { return self()->startServiceInternal("start_service_by_desktop_name", - name, URLs, error, serviceName, pid, startup_id, noWait); + name, URLs, error, startup_id, noWait); } -int -KToolInvocation::kdeinitExec( const QString& name, const QStringList &args, - QString *error, qint64 *pid, const QByteArray& startup_id ) +int KToolInvocation::kdeinitExec(const QString &name, const QStringList &args, + QString *error, + const QByteArray &startup_id) { return self()->startServiceInternal("kdeinit_exec", - name, args, error, 0, pid, startup_id, false); + name, args, error, startup_id, false); } -int -KToolInvocation::kdeinitExecWait( const QString& name, const QStringList &args, - QString *error, qint64 *pid, const QByteArray& startup_id ) +int KToolInvocation::kdeinitExecWait(const QString &name, const QStringList &args, + QString *error, + const QByteArray &startup_id) { return self()->startServiceInternal("kdeinit_exec_wait", - name, args, error, 0, pid, startup_id, false); + name, args, error, startup_id, false); } -void KToolInvocation::invokeHelp( const QString& anchor, - const QString& _appname, - const QByteArray& startup_id ) +void KToolInvocation::invokeHelp(const QString &anchor, + const QString &_appname, + const QByteArray &startup_id) { KUrl url; QString appname; @@ -219,12 +242,12 @@ void KToolInvocation::invokeHelp( const QString& anchor, invokeBrowser(url.url()); } -void KToolInvocation::invokeMailer(const QString &address, const QString &subject, const QByteArray& startup_id) +void KToolInvocation::invokeMailer(const QString &address, const QString &subject, const QByteArray &startup_id) { invokeMailer(address, QString(), subject, QString(), QStringList(), startup_id ); } -void KToolInvocation::invokeMailer(const KUrl &mailtoURL, const QByteArray& startup_id, bool allowAttachments ) +void KToolInvocation::invokeMailer(const KUrl &mailtoURL, const QByteArray& startup_id, bool allowAttachments) { QString address = mailtoURL.path(); QString subject; diff --git a/kdecore/kernel/ktoolinvocation.h b/kdecore/kernel/ktoolinvocation.h index a77d972a..9f6460e4 100644 --- a/kdecore/kernel/ktoolinvocation.h +++ b/kdecore/kernel/ktoolinvocation.h @@ -26,11 +26,10 @@ #define KTOOLINVOCATION_H #include -#include -#include +#include +#include -class OrgKdeKLauncherInterface; class KUrl; /** @@ -91,9 +90,9 @@ public Q_SLOTS: * "" ( empty string ) is the default */ - static void invokeHelp( const QString& anchor = QString(), - const QString& appname = QString(), - const QByteArray& startup_id = QByteArray()); + static void invokeHelp(const QString &anchor = QString(), + const QString &appname = QString(), + const QByteArray &startup_id = QByteArray()); /** * Convenience method; invokes the standard email application. @@ -103,8 +102,8 @@ public Q_SLOTS: * @param startup_id for app startup notification, "0" for none, * "" ( empty string ) is the default */ - static void invokeMailer( const QString &address, const QString &subject, - const QByteArray& startup_id = QByteArray() ); + static void invokeMailer(const QString &address, const QString &subject, + const QByteArray &startup_id = QByteArray()); /** * Invokes the standard email application. @@ -115,8 +114,8 @@ public Q_SLOTS: * @param allowAttachments whether attachments specified in mailtoURL should be honoured. The default is false; do not honor requests for attachments. */ - static void invokeMailer( const KUrl &mailtoURL, const QByteArray& startup_id = QByteArray(), - bool allowAttachments = false ); + static void invokeMailer(const KUrl &mailtoURL, const QByteArray &startup_id = QByteArray(), + bool allowAttachments = false ); /** * Convenience method; invokes the standard email application. @@ -132,9 +131,9 @@ public Q_SLOTS: * "" ( empty string ) is the default */ static void invokeMailer(const QString &to, const QString &cc, - const QString &subject, const QString &body, - const QStringList &attachURLs = QStringList(), - const QByteArray& startup_id = QByteArray() ); + const QString &subject, const QString &body, + const QStringList &attachURLs = QStringList(), + const QByteArray &startup_id = QByteArray()); /** * Invokes the user's preferred browser. @@ -150,8 +149,8 @@ public Q_SLOTS: * @param startup_id for app startup notification, "0" for none, * "" ( empty string ) is the default */ - static void invokeBrowser( const QString &url, - const QByteArray& startup_id = QByteArray() ); + static void invokeBrowser(const QString &url, + const QByteArray &startup_id = QByteArray()); /** * Invokes the standard terminal application. @@ -164,7 +163,7 @@ public Q_SLOTS: * @since 4.1 */ static void invokeTerminal(const QString &command, - const QString& workdir = QString(), + const QString &workdir = QString(), const QByteArray &startup_id = ""); public: @@ -186,20 +185,14 @@ public: * @param error On failure, @p error contains a description of the error * that occurred. If the pointer is 0, the argument will be * ignored - * @param serviceName On success, @p serviceName contains the DCOP name - * under which this service is available. If empty, the service does - * not provide DCOP services. If the pointer is 0 the argument - * will be ignored - * @param pid On success, the process id of the new service will be written - * here. If the pointer is 0, the argument will be ignored. * @param startup_id for app startup notification, "0" for none, * "" ( empty string ) is the default * @param noWait if set, the function does not wait till the service is running. * @return an error code indicating success (== 0) or failure (> 0). */ - static int startServiceByDesktopPath( const QString& name, const QString &URL, - QString *error=0, QString *serviceName=0, qint64 *pid = 0, - const QByteArray &startup_id = QByteArray(), bool noWait = false ); + static int startServiceByDesktopPath(const QString &name, const QString &URL, + QString *error = 0, + const QByteArray &startup_id = QByteArray(), bool noWait = false); /** * Starts a service based on the desktop path of the service. @@ -209,20 +202,15 @@ public: * @param URLs if not empty these URLs will be passed to the service * @param error On failure, @p error contains a description of the error * that occurred. If the pointer is 0, the argument will be - * ignored * @param serviceName On success, @p serviceName contains the DCOP name - * under which this service is available. If empty, the service does - * not provide DCOP services. If the pointer is 0 the argument - * will be ignored - * @param pid On success, the process id of the new service will be written - * here. If the pointer is 0, the argument will be ignored. + * ignored * @param startup_id for app startup notification, "0" for none, * "" ( empty string ) is the default * @param noWait if set, the function does not wait till the service is running. * @return an error code indicating success (== 0) or failure (> 0). */ - static int startServiceByDesktopPath( const QString& name, const QStringList &URLs=QStringList(), - QString *error=0, QString *serviceName=0, qint64 *pid = 0, - const QByteArray &startup_id = QByteArray(), bool noWait = false ); + static int startServiceByDesktopPath(const QString &name, const QStringList &URLs = QStringList(), + QString *error = 0, + const QByteArray &startup_id = QByteArray(), bool noWait = false); /** * Starts a service based on the desktop name of the service. @@ -233,20 +221,14 @@ public: * @param error On failure, @p error contains a description of the error * that occurred. If the pointer is 0, the argument will be * ignored - * @param serviceName On success, @p serviceName contains the D-Bus service name - * under which this service is available. If empty, the service does - * not provide D-Bus services. If the pointer is 0 the argument - * will be ignored - * @param pid On success, the process id of the new service will be written - * here. If the pointer is 0, the argument will be ignored. * @param startup_id for app startup notification, "0" for none, * "" ( empty string ) is the default * @param noWait if set, the function does not wait till the service is running. * @return an error code indicating success (== 0) or failure (> 0). */ - static int startServiceByDesktopName( const QString& name, const QString &URL, - QString *error=0, QString *serviceName=0, qint64 *pid = 0, - const QByteArray &startup_id = QByteArray(), bool noWait = false ); + static int startServiceByDesktopName(const QString &name, const QString &URL, + QString *error = 0, + const QByteArray &startup_id = QByteArray(), bool noWait = false); /** * Starts a service based on the desktop name of the service. @@ -257,20 +239,14 @@ public: * @param error On failure, @p error contains a description of the error * that occurred. If the pointer is 0, the argument will be * ignored - * @param serviceName On success, @p serviceName contains the D-Bus service name - * under which this service is available. If empty, the service does - * not provide D-Bus services. If the pointer is 0 the argument - * will be ignored - * @param pid On success, the process id of the new service will be written - * here. If the pointer is 0, the argument will be ignored. * @param startup_id for app startup notification, "0" for none, * "" ( empty string ) is the default * @param noWait if set, the function does not wait till the service is running. * @return an error code indicating success (== 0) or failure (> 0). */ - static int startServiceByDesktopName( const QString& name, const QStringList &URLs=QStringList(), - QString *error=0, QString *serviceName=0, qint64 *pid = 0, - const QByteArray &startup_id = QByteArray(), bool noWait = false ); + static int startServiceByDesktopName(const QString &name, const QStringList &URLs = QStringList(), + QString *error = 0, + const QByteArray &startup_id = QByteArray(), bool noWait = false); /** * Starts a program via kdeinit. @@ -283,14 +259,12 @@ public: * @param error On failure, @p error contains a description of the error * that occurred. If the pointer is 0, the argument will be * ignored - * @param pid On success, the process id of the new service will be written - * here. If the pointer is 0, the argument will be ignored. * @param startup_id for app startup notification, "0" for none, * "" ( empty string ) is the default * @return an error code indicating success (== 0) or failure (> 0). */ - static int kdeinitExec( const QString& name, const QStringList &args=QStringList(), - QString *error=0, qint64 *pid = 0, const QByteArray& startup_id = QByteArray() ); + static int kdeinitExec( const QString& name, const QStringList &args = QStringList(), + QString *error = 0, const QByteArray &startup_id = QByteArray()); /** * Starts a program via kdeinit and wait for it to finish. @@ -303,21 +277,19 @@ public: * @param error On failure, @p error contains a description of the error * that occurred. If the pointer is 0, the argument will be * ignored - * @param pid On success, the process id of the new service will be written - * here. If the pointer is 0, the argument will be ignored. * @param startup_id for app startup notification, "0" for none, * "" ( empty string ) is the default * @return an error code indicating success (== 0) or failure (> 0). */ - static int kdeinitExecWait( const QString& name, const QStringList &args=QStringList(), - QString *error=0, qint64 *pid = 0, const QByteArray& startup_id = QByteArray() ); + static int kdeinitExecWait(const QString& name, const QStringList &args = QStringList(), + QString *error = 0, const QByteArray &startup_id = QByteArray()); Q_SIGNALS: /** * Hook for KApplication in kdeui * @internal */ - void kapplication_hook(QStringList& env , QByteArray& startup_id); + void kapplication_hook(QStringList &env , QByteArray &startup_id); private: /** @@ -325,11 +297,11 @@ private: */ int startServiceInternal(const char *_function, const QString& name, const QStringList &URLs, - QString *error, QString *serviceName, qint64 *pid, - const QByteArray& startup_id, bool noWait, - const QString& workdir = QString()); + QString *error, + const QByteArray &startup_id, bool noWait, + const QString &workdir = QString()); - org::kde::KLauncher *klauncherIface; + QDBusInterface *klauncherIface; }; #endif diff --git a/kdecore/kernel/ktoolinvocation_x11.cpp b/kdecore/kernel/ktoolinvocation_x11.cpp index 54c6879f..e0e37869 100644 --- a/kdecore/kernel/ktoolinvocation_x11.cpp +++ b/kdecore/kernel/ktoolinvocation_x11.cpp @@ -206,7 +206,7 @@ void KToolInvocation::invokeMailer(const QString &to, const QString &cc, QString error; // TODO this should check if cmd has a .desktop file, and use data from it, together // with sending more ASN data - if (kdeinitExec(cmd, cmdTokens, &error, NULL, startup_id )) + if (kdeinitExec(cmd, cmdTokens, &error, startup_id )) { KMessage::message(KMessage::Error, i18n("Could not launch the mail client:\n\n%1", error), @@ -253,7 +253,7 @@ void KToolInvocation::invokeBrowser( const QString &url, const QByteArray& start if (service) { kDebug() << "Starting service" << service->entryPath(); if (startServiceByDesktopPath(service->entryPath(), args, - &error, 0, 0, startup_id)) { + &error, startup_id)) { KMessage::message(KMessage::Error, // TODO: i18n("Could not launch %1:\n\n%2", exe, error), i18n("Could not launch the browser:\n\n%1", error), @@ -266,8 +266,7 @@ void KToolInvocation::invokeBrowser( const QString &url, const QByteArray& start const KService::Ptr htmlApp = KMimeTypeTrader::self()->preferredService(QLatin1String("text/html")); if (htmlApp) { QString error; - qint64 pid = 0; - int err = startServiceByDesktopPath(htmlApp->entryPath(), url, &error, 0, &pid, startup_id); + int err = startServiceByDesktopPath(htmlApp->entryPath(), url, &error, startup_id); if (err != 0) { KMessage::message(KMessage::Error, // TODO: i18n("Could not launch %1:\n\n%2", htmlApp->exec(), error), @@ -287,7 +286,7 @@ void KToolInvocation::invokeBrowser( const QString &url, const QByteArray& start } kDebug(180) << "Using" << exe << "to open" << url; - if (kdeinitExec(exe, args, &error, NULL, startup_id )) + if (kdeinitExec(exe, args, &error, startup_id )) { KMessage::message(KMessage::Error, // TODO: i18n("Could not launch %1:\n\n%2", exe, error), @@ -325,7 +324,7 @@ void KToolInvocation::invokeTerminal(const QString &command, QString error; if (self()->startServiceInternal("kdeinit_exec_with_workdir", - cmd, cmdTokens, &error, 0, NULL, startup_id, false, workdir)) { + cmd, cmdTokens, &error, startup_id, false, workdir)) { KMessage::message(KMessage::Error, i18n("Could not launch the terminal client:\n\n%1", error), i18n("Could not launch Terminal Client")); diff --git a/kdecore/util/klauncher_iface.cpp b/kdecore/util/klauncher_iface.cpp deleted file mode 100644 index 07bf42e2..00000000 --- a/kdecore/util/klauncher_iface.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file was generated by dbusxml2cpp version 0.6 - * Command line was: dbusxml2cpp -p klauncher_iface -m ../kinit/org.kde.KLauncher.xml - * - * dbusxml2cpp is Copyright (C) 2006 Trolltech AS. All rights reserved. - * - * This is an auto-generated file. - * This file may have been hand-edited. Look for HAND-EDIT comments - * before re-generating it. - */ - -#include "klauncher_iface.h" - -/* - * Implementation of interface class OrgKdeKLauncherInterface - */ - -OrgKdeKLauncherInterface::OrgKdeKLauncherInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent) - : QDBusAbstractInterface(service, path, staticInterfaceName(), connection, parent) -{ -} - -OrgKdeKLauncherInterface::~OrgKdeKLauncherInterface() -{ -} - - -#include "moc_klauncher_iface.cpp" diff --git a/kdecore/util/klauncher_iface.h b/kdecore/util/klauncher_iface.h deleted file mode 100644 index 731a2304..00000000 --- a/kdecore/util/klauncher_iface.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * This file was generated by dbusxml2cpp version 0.6 - * Command line was: dbusxml2cpp -p klauncher_iface -m ../kinit/org.kde.KLauncher.xml - * - * dbusxml2cpp is Copyright (C) 2006 Trolltech AS. All rights reserved. - * - * This is an auto-generated file. - * Do not edit! All changes made to it will be lost. - */ - -/* - KDE5: - This is a manual copy of an automatically generated file, and the output from dbusxml2cpp - can change between dbusxml2cpp versions. This is currently no binary compatible - with what dbusxml2cpp generates these days, so if something else autogenerates the interface, - there will be crashes on systems with no symbol visibility (happened in ksmserver). - Either dbusxml2cpp should be fixed or this should be removed from kdelibs. -*/ - -#ifndef KLAUNCHER_IFACE_H_84591156096727 -#define KLAUNCHER_IFACE_H_84591156096727 - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Proxy class for interface org.kde.KLauncher - */ -class KDECORE_EXPORT OrgKdeKLauncherInterface: public QDBusAbstractInterface -{ - Q_OBJECT -public: - static inline const char *staticInterfaceName() - { return "org.kde.KLauncher"; } - -public: - OrgKdeKLauncherInterface(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); - - ~OrgKdeKLauncherInterface(); - -public Q_SLOTS: // METHODS - inline QDBusReply autoStart() - { - QList argumentList; - return callWithArgumentList(QDBus::Block, QLatin1String("autoStart"), argumentList); - } - - inline QDBusReply autoStart(int phase) - { - QList argumentList; - argumentList << qVariantFromValue(phase); - return callWithArgumentList(QDBus::Block, QLatin1String("autoStart"), argumentList); - } - - inline QDBusReply exec_blind(const QString &name, const QStringList &arg_list) - { - QList argumentList; - argumentList << qVariantFromValue(name) << qVariantFromValue(arg_list); - return callWithArgumentList(QDBus::Block, QLatin1String("exec_blind"), argumentList); - } - - inline QDBusReply kdeinit_exec(const QString &app, const QStringList &args, const QStringList &env, const QString &startup_id, QString &dbusServiceName, QString &error, qint64 &pid) - { - QList argumentList; - argumentList << qVariantFromValue(app) << qVariantFromValue(args) << qVariantFromValue(env) << qVariantFromValue(startup_id); - QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("kdeinit_exec"), argumentList); - if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 4) { - dbusServiceName = qdbus_cast(reply.arguments().at(1)); - error = qdbus_cast(reply.arguments().at(2)); - pid = qdbus_cast(reply.arguments().at(3)); - } - return reply; - } - - inline QDBusReply kdeinit_exec_wait(const QString &app, const QStringList &args, const QStringList &env, const QString &startup_id, QString &dbusServiceName, QString &error, qint64 &pid) - { - QList argumentList; - argumentList << qVariantFromValue(app) << qVariantFromValue(args) << qVariantFromValue(env) << qVariantFromValue(startup_id); - QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("kdeinit_exec_wait"), argumentList); - if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 4) { - dbusServiceName = qdbus_cast(reply.arguments().at(1)); - error = qdbus_cast(reply.arguments().at(2)); - pid = qdbus_cast(reply.arguments().at(3)); - } - return reply; - } - - inline QDBusReply setLaunchEnv(const QString &name, const QString &value) - { - QList argumentList; - argumentList << qVariantFromValue(name) << qVariantFromValue(value); - return callWithArgumentList(QDBus::Block, QLatin1String("setLaunchEnv"), argumentList); - } - - inline QDBusReply start_service_by_desktop_name(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id, bool blind, QString &dbusServiceName, QString &error, qint64 &pid) - { - QList argumentList; - argumentList << qVariantFromValue(serviceName) << qVariantFromValue(urls) << qVariantFromValue(envs) << qVariantFromValue(startup_id) << qVariantFromValue(blind); - QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("start_service_by_desktop_name"), argumentList); - if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 4) { - dbusServiceName = qdbus_cast(reply.arguments().at(1)); - error = qdbus_cast(reply.arguments().at(2)); - pid = qdbus_cast(reply.arguments().at(3)); - } - return reply; - } - - inline QDBusReply start_service_by_desktop_path(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id, bool blind, QString &dbusServiceName, QString &error, qint64 &pid) - { - QList argumentList; - argumentList << qVariantFromValue(serviceName) << qVariantFromValue(urls) << qVariantFromValue(envs) << qVariantFromValue(startup_id) << qVariantFromValue(blind); - QDBusMessage reply = callWithArgumentList(QDBus::Block, QLatin1String("start_service_by_desktop_path"), argumentList); - if (reply.type() == QDBusMessage::ReplyMessage && reply.arguments().count() == 4) { - dbusServiceName = qdbus_cast(reply.arguments().at(1)); - error = qdbus_cast(reply.arguments().at(2)); - pid = qdbus_cast(reply.arguments().at(3)); - } - return reply; - } - -Q_SIGNALS: // SIGNALS - void autoStart0Done(); - void autoStart1Done(); - void autoStart2Done(); -}; - -namespace org { - namespace kde { - typedef ::OrgKdeKLauncherInterface KLauncher; - } -} -#endif diff --git a/kinit/CMakeLists.txt b/kinit/CMakeLists.txt index 607eaa8d..edb113c7 100644 --- a/kinit/CMakeLists.txt +++ b/kinit/CMakeLists.txt @@ -26,7 +26,7 @@ set(klauncher_SRCS ${CMAKE_CURRENT_BINARY_DIR}/org.kde.KLauncher.xml ) -# The adaptor is manually edited, generate the xml from it. +# Generate the xml from the adaptor. qt4_generate_dbus_interface(klauncher_adaptor.h org.kde.KLauncher.xml) add_executable(klauncher4 ${klauncher_SRCS}) @@ -40,8 +40,6 @@ kde4_add_dbus_service(org.kde.klauncher.service.in) install(TARGETS klauncher4 DESTINATION ${KDE4_BIN_INSTALL_DIR}) -########### install files ############### - install( FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.KLauncher.xml diff --git a/kinit/klauncher_adaptor.cpp b/kinit/klauncher_adaptor.cpp index be60c394..785627be 100644 --- a/kinit/klauncher_adaptor.cpp +++ b/kinit/klauncher_adaptor.cpp @@ -90,7 +90,7 @@ void KLauncherAdaptor::autoStart(int phase) ); } - kDebug() << "autostart, phase" << phase; + kDebug() << "autostart phase" << phase; foreach(const QString &it, m_autostart) { KAutostart kautostart(it); if (!kautostart.autostarts(QString::fromLatin1("KDE"), KAutostart::CheckAll)) { @@ -148,16 +148,16 @@ void KLauncherAdaptor::exec_blind(const QString &name, const QStringList &arg_li QProcess::startDetached(envexe, envargs); } -int KLauncherAdaptor::kdeinit_exec(const QString &app, const QStringList &args, const QStringList &env, const QString& startup_id, - const QDBusMessage &msg, QString &dbusServiceName, QString &error, qint64 &pid) +int KLauncherAdaptor::kdeinit_exec(const QString &app, const QStringList &args, const QStringList &envs, const QString& startup_id) { - return kdeinit_exec_with_workdir(app, args, QDir::currentPath(), env, startup_id, msg, dbusServiceName, error, pid); + return kdeinit_exec_with_workdir(app, args, envs, startup_id, QDir::currentPath()); } -int KLauncherAdaptor::kdeinit_exec_wait(const QString &app, const QStringList &args, const QStringList &env, const QString& startup_id, - const QDBusMessage &msg, QString &dbusServiceName, QString &error, qint64 &pid) +int KLauncherAdaptor::kdeinit_exec_wait(const QString &app, const QStringList &args, const QStringList &envs, const QString &startup_id) { - int result = kdeinit_exec(app, args, env, startup_id, msg, dbusServiceName, error, pid); + QMutexLocker locker(&m_mutex); + qint64 pid = 0; + int result = startProgram(app, args, envs, startup_id, QDir::currentPath(), pid); if (result != KLauncherAdaptor::NoError) { return result; } @@ -171,61 +171,11 @@ int KLauncherAdaptor::kdeinit_exec_wait(const QString &app, const QStringList &a return result; } -int KLauncherAdaptor::kdeinit_exec_with_workdir(const QString &app, const QStringList &args, const QString& workdir, const QStringList &env, const QString& startup_id, - const QDBusMessage &msg, QString &dbusServiceName, QString &error, qint64 &pid) +int KLauncherAdaptor::kdeinit_exec_with_workdir(const QString &app, const QStringList &args, const QStringList &envs, const QString &startup_id, const QString &workdir) { - const QString appexe = findExe(app); - if (appexe.isEmpty()) { - error = i18n("Could not find: %1", app); - return KLauncherAdaptor::FindError; - } - - QProcess* process = new QProcess(this); - connect(process, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(slotProcessStateChanged(QProcess::ProcessState))); - connect(process, SIGNAL(finished(int)), this, SLOT(slotProcessFinished(int))); - m_processes.append(process); - QProcessEnvironment processenv = m_environment; - foreach (const QString &it, env) { - const int equalindex = it.indexOf(QLatin1Char('=')); - if (equalindex <= 0) { - kWarning() << "invalid environment variable" << it; - continue; - } - const QString environmentvar = it.mid(0, equalindex); - const QString environmentvalue = it.mid(equalindex + 1, it.size() - equalindex - 1); - kDebug() << "adding to environment" << environmentvar << environmentvalue; - processenv.insert(environmentvar, environmentvalue); - } - process->setProcessEnvironment(processenv); - process->setWorkingDirectory(workdir); - kDebug() << "starting" << appexe << args << env; - // either start_service_by_desktop_path() or this method send ASN - if (!startup_id.isEmpty()) { - Q_ASSERT(m_kstartupinfoid.none() == true); - m_kstartupinfoid = KStartupInfoId(); - m_kstartupinfodata = KStartupInfoData(); - m_kstartupinfoid.initId(startup_id.toLatin1()); - m_kstartupinfodata.setBin(QFileInfo(appexe).fileName()); - m_kstartupinfodata.setDescription(i18n("Launching %1", m_kstartupinfodata.bin())); - sendSIStart(); - } - process->start(appexe, args); - while (process->state() == QProcess::Starting) { - QApplication::processEvents(QEventLoop::AllEvents, s_eventstime); - QThread::msleep(s_sleeptime); - } - if (process->error() == QProcess::FailedToStart || process->error() == QProcess::Crashed) { - sendSIFinish(); - error = i18n("Could not start: %1", appexe); - return KLauncherAdaptor::ExecError; - } - if (!startup_id.isEmpty()) { - sendSIFinish(); - } - - error.clear(); - pid = process->pid(); - return KLauncherAdaptor::NoError; + QMutexLocker locker(&m_mutex); + qint64 pid = 0; + return startProgram(app, args, envs, startup_id, workdir, pid); } void KLauncherAdaptor::setLaunchEnv(const QString &name, const QString &value) @@ -238,33 +188,32 @@ void KLauncherAdaptor::setLaunchEnv(const QString &name, const QString &value) m_environment.insert(name, value); } -int KLauncherAdaptor::start_service_by_desktop_name(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id, bool blind, - const QDBusMessage &msg, QString &dbusServiceName, QString &error, qint64 &pid) +int KLauncherAdaptor::start_service_by_desktop_name(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id, bool blind) { KService::Ptr kservice = KService::serviceByDesktopName(serviceName); if (!kservice) { - error = i18n("Invalid service name: %1", serviceName); + kWarning() << "invalid service name" << serviceName; return KLauncherAdaptor::ServiceError; } - return start_service_by_desktop_path(kservice->entryPath(), urls, envs, startup_id, blind, msg, dbusServiceName, error, pid); + return start_service_by_desktop_path(kservice->entryPath(), urls, envs, startup_id, blind); } -int KLauncherAdaptor::start_service_by_desktop_path(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id, bool blind, - const QDBusMessage &msg, QString &dbusServiceName, QString &error, qint64 &pid) +int KLauncherAdaptor::start_service_by_desktop_path(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id, bool blind) { + QMutexLocker locker(&m_mutex); KService::Ptr kservice = KService::serviceByStorageId(serviceName); if (!kservice) { - error = i18n("Invalid service path: %1", serviceName); + kWarning() << "invalid service path" << serviceName; return KLauncherAdaptor::ServiceError; } const KService::DBusStartupType dbusstartuptype = kservice->dbusStartupType(); - dbusServiceName = kservice->property(QString::fromLatin1("X-DBUS-ServiceName"), QVariant::String).toString(); + QString dbusServiceName = kservice->property(QString::fromLatin1("X-DBUS-ServiceName"), QVariant::String).toString(); // any unique Katana application/service checks if another instance is running, if it is // already running starting it may raise its window instead (if it uses KUniqueApplication) if (dbusstartuptype == KService::DBusUnique && !dbusServiceName.startsWith(QLatin1String("org.kde."))) { QDBusReply sessionreply = m_dbusconnectioninterface->isServiceRegistered(dbusServiceName); if (!sessionreply.isValid()) { - error = i18n("Invalid D-Bus reply for: %1", dbusServiceName); + kWarning() << "invalid D-Bus reply for" << dbusServiceName; return KLauncherAdaptor::DBusError; } if (sessionreply.value() == true) { @@ -274,12 +223,12 @@ int KLauncherAdaptor::start_service_by_desktop_path(const QString &serviceName, } if (urls.size() > 1 && !kservice->allowMultipleFiles()) { // TODO: start multiple instances for each URL - error = i18n("Service does not support multiple files: %1", serviceName); + kWarning() << "service does not support multiple files" << serviceName; return KLauncherAdaptor::ServiceError; } QStringList programandargs = KRun::processDesktopExec(*kservice, urls); if (programandargs.isEmpty()) { - error = i18n("Could not process service: %1", kservice->entryPath()); + kWarning() << "could not process service" << kservice->entryPath(); return KLauncherAdaptor::ArgumentsError; } kDebug() << "starting" << kservice->entryPath() << urls << blind << dbusServiceName; @@ -302,7 +251,8 @@ int KLauncherAdaptor::start_service_by_desktop_path(const QString &serviceName, } else { kDebug() << "no ASN for" << kservice->entryPath(); } - int result = kdeinit_exec(program, programargs, envs, QString(), msg, dbusServiceName, error, pid); + qint64 pid = 0; + int result = startProgram(program, programargs, envs, QString(), QDir::currentPath(), pid); if (result != KLauncherAdaptor::NoError) { // sendSIFinish() is called on exec error return result; @@ -328,7 +278,6 @@ int KLauncherAdaptor::start_service_by_desktop_path(const QString &serviceName, if (!sessionreply.isValid()) { kWarning() << "invalid D-Bus reply for" << dbusServiceName; sendSIFinish(); - error = i18n("Invalid D-Bus reply for: %1", dbusServiceName); return KLauncherAdaptor::DBusError; } // the service unregistered @@ -398,6 +347,60 @@ QString KLauncherAdaptor::findExe(const QString &app) const return KStandardDirs::findExe(app, environmentpath); } +int KLauncherAdaptor::startProgram(const QString &app, const QStringList &args, const QStringList &envs, const QString &startup_id, const QString &workdir, qint64 &pid) +{ + const QString appexe = findExe(app); + if (appexe.isEmpty()) { + kWarning() << "could not find" << app; + return KLauncherAdaptor::FindError; + } + + QProcess* process = new QProcess(this); + connect(process, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(slotProcessStateChanged(QProcess::ProcessState))); + connect(process, SIGNAL(finished(int)), this, SLOT(slotProcessFinished(int))); + m_processes.append(process); + QProcessEnvironment processenv = m_environment; + foreach (const QString &env, envs) { + const int equalindex = env.indexOf(QLatin1Char('=')); + if (equalindex <= 0) { + kWarning() << "invalid environment variable" << env; + continue; + } + const QString environmentvar = env.mid(0, equalindex); + const QString environmentvalue = env.mid(equalindex + 1, env.size() - equalindex - 1); + kDebug() << "adding to environment" << environmentvar << environmentvalue; + processenv.insert(environmentvar, environmentvalue); + } + process->setProcessEnvironment(processenv); + process->setWorkingDirectory(workdir); + kDebug() << "starting" << appexe << args << envs; + if (!startup_id.isEmpty()) { + Q_ASSERT(m_kstartupinfoid.none() == true); + m_kstartupinfoid = KStartupInfoId(); + m_kstartupinfodata = KStartupInfoData(); + m_kstartupinfoid.initId(startup_id.toLatin1()); + m_kstartupinfodata.setBin(QFileInfo(appexe).fileName()); + m_kstartupinfodata.setDescription(i18n("Launching %1", m_kstartupinfodata.bin())); + sendSIStart(); + } + process->start(appexe, args); + while (process->state() == QProcess::Starting) { + QApplication::processEvents(QEventLoop::AllEvents, s_eventstime); + QThread::msleep(s_sleeptime); + } + if (process->error() == QProcess::FailedToStart || process->error() == QProcess::Crashed) { + sendSIFinish(); + kWarning() << "could not start" << appexe; + return KLauncherAdaptor::ExecError; + } + if (!startup_id.isEmpty()) { + sendSIFinish(); + } + + pid = process->pid(); + return KLauncherAdaptor::NoError; +} + void KLauncherAdaptor::sendSIStart() const { if (m_kstartupinfoid.none()) { diff --git a/kinit/klauncher_adaptor.h b/kinit/klauncher_adaptor.h index 6de900e0..8a06f816 100644 --- a/kinit/klauncher_adaptor.h +++ b/kinit/klauncher_adaptor.h @@ -25,6 +25,7 @@ #include #include #include +#include // #define KLAUNCHER_DEBUG @@ -36,11 +37,11 @@ class KLauncherAdaptor: public QDBusAbstractAdaptor public: enum KLauncherError { NoError = 0, - ServiceError = 1, - FindError = 2, - ArgumentsError = 3, - ExecError = 4, - DBusError = 5 + ServiceError = -1, + FindError = -2, + ArgumentsError = -3, + ExecError = -4, + DBusError = -5 }; KLauncherAdaptor(QObject *parent); @@ -56,11 +57,11 @@ public Q_SLOTS: // used by KToolInvocation void setLaunchEnv(const QString &name, const QString &value); - int kdeinit_exec(const QString &app, const QStringList &args, const QStringList &env, const QString& startup_id, const QDBusMessage &msg, QString &dbusServiceName, QString &error, qint64 &pid); - int kdeinit_exec_wait(const QString &app, const QStringList &args, const QStringList &env, const QString& startup_id, const QDBusMessage &msg, QString &dbusServiceName, QString &error, qint64 &pid); - int kdeinit_exec_with_workdir(const QString &app, const QStringList &args, const QString& workdir, const QStringList &env, const QString& startup_id, const QDBusMessage &msg, QString &dbusServiceName, QString &error, qint64 &pid); - int start_service_by_desktop_name(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id, bool blind, const QDBusMessage &msg, QString &dbusServiceName, QString &error, qint64 &pid); - int start_service_by_desktop_path(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id, bool blind, const QDBusMessage &msg, QString &dbusServiceName, QString &error, qint64 &pid); + int kdeinit_exec(const QString &app, const QStringList &args, const QStringList &envs, const QString &startup_id); + int kdeinit_exec_wait(const QString &app, const QStringList &args, const QStringList &envs, const QString &startup_id); + int kdeinit_exec_with_workdir(const QString &app, const QStringList &args, const QStringList &envs, const QString &startup_id, const QString &workdir); + int start_service_by_desktop_name(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id, bool blind); + int start_service_by_desktop_path(const QString &serviceName, const QStringList &urls, const QStringList &envs, const QString &startup_id, bool blind); // for debugging #ifdef KLAUNCHER_DEBUG @@ -78,10 +79,12 @@ private Q_SLOTS: private: QString findExe(const QString &app) const; + int startProgram(const QString &app, const QStringList &args, const QStringList &envs, const QString &startup_id, const QString &workdir, qint64 &pid); void sendSIStart() const; void sendSIChange(); void sendSIFinish(); + QMutex m_mutex; QProcessEnvironment m_environment; QDBusConnectionInterface* m_dbusconnectioninterface; KStartupInfoId m_kstartupinfoid; diff --git a/kio/kio/krun.cpp b/kio/kio/krun.cpp index ffa306cd..06298b9a 100644 --- a/kio/kio/krun.cpp +++ b/kio/kio/krun.cpp @@ -944,7 +944,6 @@ bool KRun::run(const KService& _service, const KUrl::List& _urls, QWidget* windo const KUrl::List urls = resolveURLs(_urls, _service); QString error; - qint64 pid = 0; QByteArray myasn = asn; // startServiceByDesktopPath() doesn't take QWidget*, add it to the startup info now @@ -962,8 +961,8 @@ bool KRun::run(const KService& _service, const KUrl::List& _urls, QWidget* windo } int i = KToolInvocation::startServiceByDesktopPath( - _service.entryPath(), urls.toStringList(), &error, 0L, &pid, myasn - ); + _service.entryPath(), urls.toStringList(), &error, myasn + ); if (i != 0) { kDebug(7010) << error;