KontactInterface

pimuniqueapplication.cpp
1/* This file is part of the KDE project
2
3 SPDX-FileCopyrightText: 2008 David Faure <faure@kde.org>
4
5 SPDX-License-Identifier: LGPL-2.0-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6*/
7
8#include "pimuniqueapplication.h"
9#include "config-kontactinterface.h"
10#include "kontactinterface_debug.h"
11
12#include <KAboutData>
13#include <KWindowSystem>
14
15#include "config-kontactinterface.h"
16#if KONTACTINTERFACE_HAVE_X11
17#include <KStartupInfo>
18#include <private/qtx11extras_p.h>
19#endif
20
21#ifdef Q_OS_WINDOWS
22#include <QFont>
23#include <Windows.h>
24#endif
25
26#include <QCommandLineParser>
27#include <QDir>
28
29#include <QMainWindow>
30#include <QWidget>
31
32#include <QDBusConnectionInterface>
33#include <QDBusInterface>
34
35using namespace KontactInterface;
36
37namespace
38{
39const char kChromiumFlagsEnv[] = "QTWEBENGINE_CHROMIUM_FLAGS";
40const char kDisableInProcessStackTraces[] = "--disable-in-process-stack-traces";
41
42}
43
44//@cond PRIVATE
45class Q_DECL_HIDDEN KontactInterface::PimUniqueApplication::PimUniqueApplicationPrivate
46{
47public:
48 PimUniqueApplicationPrivate()
49 : cmdArgs(new QCommandLineParser())
50 {
51 }
52
53 ~PimUniqueApplicationPrivate()
54 {
55 delete cmdArgs;
56 }
57
58 static void disableChromiumCrashHandler()
59 {
60 // Disable Chromium's own crash handler, which overrides DrKonqi.
61 auto flags = qgetenv(kChromiumFlagsEnv);
62 if (!flags.contains(kDisableInProcessStackTraces)) {
63 qputenv(kChromiumFlagsEnv, QByteArray(flags + " " + kDisableInProcessStackTraces));
64 }
65 }
66
67 QCommandLineParser *const cmdArgs;
68};
69//@endcond
70
71PimUniqueApplication::PimUniqueApplication(int &argc, char **argv[])
72 : QApplication(argc, *argv)
73 , d(new PimUniqueApplicationPrivate())
74{
75#ifdef Q_OS_WINDOWS
76 if (AttachConsole(ATTACH_PARENT_PROCESS)) {
77 freopen("CONOUT$", "w", stdout);
78 freopen("CONOUT$", "w", stderr);
79 }
80
81 setStyle(QStringLiteral("breeze"));
82 QFont font(QStringLiteral("Segoe UI Emoji"));
83 font.setPointSize(10);
84 font.setHintingPreference(QFont::PreferNoHinting);
85 setFont(font);
86#endif
87}
88
89PimUniqueApplication::~PimUniqueApplication() = default;
90
91QCommandLineParser *PimUniqueApplication::cmdArgs() const
92{
93 return d->cmdArgs;
94}
95
96void PimUniqueApplication::setAboutData(KAboutData &aboutData)
97{
99 aboutData.setupCommandLine(d->cmdArgs);
100 // This object name is used in start(), and also in kontact's UniqueAppHandler.
103 this,
106}
107
108static bool callNewInstance(const QString &appName, const QString &serviceName, const QByteArray &asn_id, const QStringList &arguments)
109{
110 const QString objectName = QLatin1Char('/') + appName + QLatin1StringView("_PimApplication");
111 QDBusInterface iface(serviceName, objectName, QStringLiteral("org.kde.PIMUniqueApplication"), QDBusConnection::sessionBus());
112 if (iface.isValid()) {
113 QDBusReply<int> reply = iface.call(QStringLiteral("newInstance"), asn_id, arguments, QDir::currentPath());
114 if (reply.isValid()) {
115 return true;
116 }
117 }
118 return false;
119}
120
121int PimUniqueApplication::newInstance()
122{
124}
125
127{
128 const QString appName = QApplication::applicationName();
129
130 // Try talking to /appName_PimApplication in org.kde.appName,
131 // (which could be kontact or the standalone application),
132 // otherwise the current app being started will register to DBus.
133
134 const QString serviceName = QLatin1StringView("org.kde.") + appName;
135 if (QDBusConnection::sessionBus().interface()->isServiceRegistered(serviceName)) {
136 QByteArray new_asn_id;
138#if KONTACTINTERFACE_HAVE_X11
139 new_asn_id = QX11Info::nextStartupId();
140#endif
142 new_asn_id = qgetenv("XDG_ACTIVATION_TOKEN");
143 }
144
145 if (callNewInstance(appName, serviceName, new_asn_id, arguments)) {
146 return false; // success means that main() can exit now.
147 }
148 }
149
150 qCDebug(KONTACTINTERFACE_LOG) << "kontact not running -- start standalone application";
151
153
154 // Make sure we have DrKonqi
155 PimUniqueApplicationPrivate::disableChromiumCrashHandler();
156
157 static_cast<PimUniqueApplication *>(qApp)->activate(arguments, QDir::currentPath());
158 return true;
159}
160
161// This is called via DBus either by another instance that has just been
162// started or by Kontact when the module is activated
163int PimUniqueApplication::newInstance(const QByteArray &startupId, const QStringList &arguments, const QString &workingDirectory)
164{
166#if KONTACTINTERFACE_HAVE_X11
168#endif
171 }
172
173 const QWidgetList tlws = topLevelWidgets();
174 for (QWidget *win : tlws) {
175 if (qobject_cast<QMainWindow *>(win)) {
176 win->show();
177 win->setAttribute(Qt::WA_NativeWindow, true);
178
179 KWindowSystem::activateWindow(win->windowHandle());
180 break;
181 }
182 }
183
184 activate(arguments, workingDirectory);
185 return 0;
186}
187
188int PimUniqueApplication::activate(const QStringList &arguments, const QString &workingDirectory)
189{
190 Q_UNUSED(arguments)
191 Q_UNUSED(workingDirectory)
192 return 0;
193}
194
195#include "moc_pimuniqueapplication.cpp"
static void setApplicationData(const KAboutData &aboutData)
bool setupCommandLine(QCommandLineParser *parser)
static void setStartupId(const QByteArray &startup_id)
static Q_INVOKABLE void activateWindow(QWindow *window, long time=0)
static bool isPlatformX11()
static Q_INVOKABLE void setCurrentXdgActivationToken(const QString &token)
static bool isPlatformWayland()
KDEPIM applications which can be integrated into kontact should use PimUniqueApplication instead of Q...
static bool start(const QStringList &arguments)
Register this process as a unique application, if not already running.
QCA_EXPORT QString appName()
QWidgetList topLevelWidgets()
QStringList arguments()
bool registerObject(const QString &path, QObject *object, RegisterOptions options)
bool registerService(const QString &serviceName)
QDBusConnection sessionBus()
bool isValid() const const
QString currentPath()
PreferNoHinting
QString fromUtf8(QByteArrayView str)
WA_NativeWindow
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:21:21 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.