1 | /* This file is part of the KDE project |
2 | |
3 | Copyright 2008 David Faure <faure@kde.org> |
4 | |
5 | This library is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU Library General Public License as published |
7 | by the Free Software Foundation; either version 2 of the License or |
8 | ( at your option ) version 3 or, at the discretion of KDE e.V. |
9 | ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. |
10 | |
11 | This library is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | Library General Public License for more details. |
15 | |
16 | You should have received a copy of the GNU Library General Public License |
17 | along with this library; see the file COPYING.LIB. If not, write to |
18 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
19 | Boston, MA 02110-1301, USA. |
20 | */ |
21 | |
22 | #include "pimuniqueapplication.h" |
23 | |
24 | #include <kaboutdata.h> |
25 | #include <kcmdlineargs.h> |
26 | #include <kdebug.h> |
27 | #include <kstartupinfo.h> |
28 | #include <kwindowsystem.h> |
29 | |
30 | #include <qdbusconnectioninterface.h> |
31 | #include <qdbusinterface.h> |
32 | |
33 | using namespace KontactInterface; |
34 | |
35 | //@cond PRIVATE |
36 | class KontactInterface::PimUniqueApplication::Private |
37 | { |
38 | }; |
39 | //@endcond |
40 | |
41 | PimUniqueApplication::PimUniqueApplication() |
42 | : KUniqueApplication(), d( new Private() ) |
43 | { |
44 | // This object name is used in start(), and also in kontact's UniqueAppHandler. |
45 | const QString objectName = QLatin1Char( '/' ) + applicationName() + QLatin1String("_PimApplication" ); |
46 | QDBusConnection::sessionBus().registerObject( |
47 | objectName, this, |
48 | QDBusConnection::ExportScriptableSlots | |
49 | QDBusConnection::ExportScriptableProperties | |
50 | QDBusConnection::ExportAdaptors ); |
51 | } |
52 | |
53 | static const char _k_sessionBusName[] = "kdepimapplication_session_bus" ; |
54 | |
55 | PimUniqueApplication::~PimUniqueApplication() |
56 | { |
57 | delete d; |
58 | } |
59 | |
60 | static QDBusConnection tryToInitDBusConnection() |
61 | { |
62 | // Check the D-Bus connection health, and connect - but not using QDBusConnection::sessionBus() |
63 | // since we can't close that one before forking. |
64 | QDBusConnection connection = QDBusConnection::connectToBus( |
65 | QDBusConnection::SessionBus, QLatin1String(_k_sessionBusName) ); |
66 | if ( !connection.isConnected() ) { |
67 | kError() << "Cannot find the D-Bus session server" << endl; //krazy:exclude=kdebug |
68 | ::exit( 255 ); |
69 | } |
70 | return connection; |
71 | } |
72 | |
73 | bool PimUniqueApplication::start() |
74 | { |
75 | return start( KUniqueApplication::StartFlags() ); |
76 | } |
77 | |
78 | bool PimUniqueApplication::start( KUniqueApplication::StartFlags flags ) |
79 | { |
80 | const QString appName = KCmdLineArgs::aboutData()->appName(); |
81 | // Try talking to /appName_PimApplication in org.kde.appName, |
82 | // (which could be kontact or the standalone application), |
83 | // otherwise fall back to standard KUniqueApplication behavior (start appName). |
84 | |
85 | const QString serviceName = QLatin1String("org.kde." ) + appName; |
86 | if ( tryToInitDBusConnection().interface()->isServiceRegistered( serviceName ) ) { |
87 | QByteArray saved_args; |
88 | QDataStream ds( &saved_args, QIODevice::WriteOnly ); |
89 | KCmdLineArgs::saveAppArgs( ds ); |
90 | |
91 | QByteArray new_asn_id; |
92 | #if defined Q_WS_X11 |
93 | KStartupInfoId id; |
94 | if ( kapp ) { // KApplication constructor unsets the env. variable |
95 | id.initId( kapp->startupId() ); |
96 | } else { |
97 | id = KStartupInfo::currentStartupIdEnv(); |
98 | } |
99 | if ( !id.none() ) { |
100 | new_asn_id = id.id(); |
101 | } |
102 | #endif |
103 | |
104 | KWindowSystem::allowExternalProcessWindowActivation(); |
105 | |
106 | const QString objectName = QLatin1Char( '/' ) + appName + QLatin1String("_PimApplication" ); |
107 | //kDebug() << objectName; |
108 | QDBusInterface iface( |
109 | serviceName, objectName, QLatin1String("org.kde.KUniqueApplication" ), QDBusConnection::sessionBus() ); |
110 | QDBusReply<int> reply; |
111 | if ( iface.isValid() && |
112 | ( reply = iface.call( QLatin1String("newInstance" ), new_asn_id, saved_args ) ).isValid() ) { |
113 | return false; // success means that main() can exit now. |
114 | } |
115 | } |
116 | |
117 | QDBusConnection::disconnectFromBus( QLatin1String(_k_sessionBusName) ); |
118 | |
119 | //kDebug() << "kontact not running -- start standalone application"; |
120 | // kontact not running -- start standalone application. |
121 | return KUniqueApplication::start( flags ); |
122 | } |
123 | |