File indexing completed on 2024-05-12 05:20:45
0001 /* 0002 * kmail: KDE mail client 0003 * SPDX-FileCopyrightText: 1996-1998 Stefan Taferner <taferner@kde.org> 0004 * 0005 * SPDX-License-Identifier: GPL-2.0-or-later 0006 * 0007 */ 0008 0009 #include <kontactinterface/pimuniqueapplication.h> 0010 0011 #include "kmail_options.h" 0012 #include "kmkernel.h" //control center 0013 0014 #include "kmail_debug.h" 0015 #undef Status // stupid X headers 0016 0017 #include "aboutdata.h" 0018 0019 #include <KCrash> 0020 #include <KStartupInfo> 0021 #include <KWindowSystem> 0022 #include <QApplication> 0023 #include <QDir> 0024 #include <QSessionManager> 0025 #include <QWebEngineUrlScheme> 0026 0027 #ifdef WITH_KUSERFEEDBACK 0028 #include "userfeedback/kmailuserfeedbackprovider.h" 0029 #include <KUserFeedback/Provider> 0030 #endif 0031 0032 //----------------------------------------------------------------------------- 0033 0034 class KMailApplication : public KontactInterface::PimUniqueApplication 0035 { 0036 public: 0037 KMailApplication(int &argc, char **argv[]) 0038 : KontactInterface::PimUniqueApplication(argc, argv) 0039 { 0040 } 0041 0042 int activate(const QStringList &args, const QString &workingDir) override; 0043 void commitData(QSessionManager &sm); 0044 void setEventLoopReached(); 0045 void delayedInstanceCreation(const QStringList &args, const QString &workingDir); 0046 0047 public Q_SLOTS: 0048 int newInstance(const QByteArray &startupId, const QStringList &arguments, const QString &workingDirectory) override; 0049 0050 protected: 0051 bool mDelayedInstanceCreation = false; 0052 bool mEventLoopReached = false; 0053 }; 0054 0055 void KMailApplication::commitData(QSessionManager &) 0056 { 0057 kmkernel->dumpDeadLetters(); 0058 kmkernel->setShuttingDown(true); // Prevent further dumpDeadLetters calls 0059 } 0060 0061 void KMailApplication::setEventLoopReached() 0062 { 0063 mEventLoopReached = true; 0064 } 0065 0066 int KMailApplication::newInstance(const QByteArray &startupId, const QStringList &arguments, const QString &workingDirectory) 0067 { 0068 if (KWindowSystem::isPlatformX11()) { 0069 KStartupInfo::setNewStartupId(kmkernel->mainWin()->windowHandle(), startupId); 0070 } else if (KWindowSystem::isPlatformWayland()) { 0071 KWindowSystem::setCurrentXdgActivationToken(QString::fromUtf8(startupId)); 0072 } 0073 0074 if (!kmkernel->firstInstance() && !arguments.isEmpty()) { 0075 // if we're going to create a new window (viewer or composer), 0076 // don't bring the mainwindow onto the current desktop 0077 return activate(arguments, workingDirectory); 0078 } else { 0079 return PimUniqueApplication::newInstance(startupId, arguments, workingDirectory); 0080 } 0081 } 0082 0083 int KMailApplication::activate(const QStringList &args, const QString &workingDir) 0084 { 0085 // If the event loop hasn't been reached yet, the kernel is probably not 0086 // fully initialized. Creating an instance would therefore fail, this is why 0087 // that is delayed until delayedInstanceCreation() is called. 0088 if (!mEventLoopReached) { 0089 qCDebug(KMAIL_LOG) << "Delaying instance creation."; 0090 mDelayedInstanceCreation = true; 0091 return 0; 0092 } 0093 0094 if (!kmkernel) { 0095 return 0; 0096 } 0097 if (kmkernel->shuttingDown()) { 0098 qCDebug(KMAIL_LOG) << "KMail is in a shutdown mode."; 0099 return 0; 0100 } 0101 0102 if (!kmkernel->firstInstance() || !qApp->isSessionRestored()) { 0103 kmkernel->handleCommandLine(true, args, workingDir); 0104 } 0105 kmkernel->setFirstInstance(false); 0106 0107 KWindowSystem::activateWindow(kmkernel->mainWin()->windowHandle()); 0108 0109 return 0; 0110 } 0111 0112 void KMailApplication::delayedInstanceCreation(const QStringList &args, const QString &workingDir) 0113 { 0114 if (mDelayedInstanceCreation) { 0115 activate(args, workingDir); 0116 } 0117 } 0118 0119 int main(int argc, char *argv[]) 0120 { 0121 QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts, true); 0122 // Necessary for "cid" support in kmail. 0123 QWebEngineUrlScheme cidScheme("cid"); 0124 cidScheme.setFlags(QWebEngineUrlScheme::SecureScheme | QWebEngineUrlScheme::ContentSecurityPolicyIgnored | QWebEngineUrlScheme::LocalScheme 0125 | QWebEngineUrlScheme::LocalAccessAllowed); 0126 cidScheme.setSyntax(QWebEngineUrlScheme::Syntax::Path); 0127 QWebEngineUrlScheme::registerScheme(cidScheme); 0128 0129 KMailApplication app(argc, &argv); 0130 KLocalizedString::setApplicationDomain(QByteArrayLiteral("kmail")); 0131 app.setWindowIcon(QIcon::fromTheme(QStringLiteral("kmail"))); 0132 app.setDesktopFileName(QStringLiteral("org.kde.kmail2")); 0133 KCrash::initialize(); 0134 KMail::AboutData about; 0135 app.setAboutData(about); 0136 0137 QCommandLineParser *cmdArgs = app.cmdArgs(); 0138 kmail_options(cmdArgs); 0139 0140 const QStringList args = QApplication::arguments(); 0141 cmdArgs->process(args); 0142 about.processCommandLine(cmdArgs); 0143 0144 #ifdef WITH_KUSERFEEDBACK 0145 if (cmdArgs->isSet(QStringLiteral("feedback"))) { 0146 KMailUserFeedbackProvider userFeedback(nullptr); 0147 QTextStream(stdout) << userFeedback.describeDataSources() << '\n'; 0148 return 0; 0149 } 0150 #endif 0151 0152 if (!KMailApplication::start(args)) { 0153 qCDebug(KMAIL_LOG) << "Another instance of KMail already running"; 0154 return 0; 0155 } 0156 // local, do the init 0157 KMKernel kmailKernel; 0158 kmailKernel.init(); 0159 0160 // and session management 0161 kmailKernel.doSessionManagement(); 0162 0163 // any dead letters? 0164 kmailKernel.recoverDeadLetters(); 0165 0166 kmkernel->setupDBus(); // Ok. We are ready for D-Bus requests. 0167 0168 // If the instance hasn't been created yet, do that now 0169 app.setEventLoopReached(); 0170 app.delayedInstanceCreation(args, QDir::currentPath()); 0171 // kmkernel->setSystemTryAssociatedWindow(app.focusWindow()); 0172 0173 // Go! 0174 int ret = qApp->exec(); 0175 // clean up 0176 kmailKernel.cleanup(); 0177 return ret; 0178 }