File indexing completed on 2024-05-12 04:34:57
0001 /* 0002 * SPDX-FileCopyrightText: 2019 David Redondo <kde@david-redondo.de> 0003 * SPDX-FileCopyrightText: 2015 Boudhayan Gupta <bgupta@kde.org> 0004 * 0005 * SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "Config.h" 0009 #include "ShortcutActions.h" 0010 #include "SpectacleCore.h" 0011 #include "CommandLineOptions.h" 0012 #include "SpectacleDBusAdapter.h" 0013 #include "ScreenShotEffect.h" 0014 #include "settings.h" 0015 0016 #include <QApplication> 0017 #include <QCommandLineParser> 0018 #include <QDBusConnection> 0019 #include <QDir> 0020 #include <QSessionManager> 0021 0022 #include <KAboutData> 0023 #include <KDBusService> 0024 #include <KLocalizedString> 0025 #include <KMessageBox> 0026 #include <KWindowSystem> 0027 0028 using namespace Qt::StringLiterals; 0029 0030 int main(int argc, char **argv) 0031 { 0032 // set up the application 0033 0034 QCoreApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); 0035 QApplication app(argc, argv); 0036 0037 KLocalizedString::setApplicationDomain(QByteArrayLiteral("spectacle")); 0038 QCoreApplication::setOrganizationDomain(u"org.kde"_s); 0039 0040 KAboutData aboutData(u"spectacle"_s, 0041 i18n("Spectacle"), 0042 QStringLiteral(SPECTACLE_VERSION), 0043 i18n("KDE Screenshot Utility"), 0044 KAboutLicense::GPL_V2, 0045 i18n("(C) 2015 Boudhayan Gupta")); 0046 aboutData.addAuthor(u"Boudhayan Gupta"_s, {}, u"bgupta@kde.org"_s); 0047 aboutData.addAuthor(u"David Redondo"_s, {}, u"kde@david-redondo.de"_s); 0048 aboutData.addAuthor(u"Noah Davis"_s, {}, u"noahadvs@gmail.com"_s); 0049 aboutData.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), i18nc("EMAIL OF TRANSLATORS", "Your emails")); 0050 KAboutData::setApplicationData(aboutData); 0051 app.setWindowIcon(QIcon::fromTheme(u"spectacle"_s)); 0052 0053 QCommandLineParser commandLineParser; 0054 aboutData.setupCommandLine(&commandLineParser); 0055 commandLineParser.addOptions(CommandLineOptions::self()->allOptions); 0056 0057 // first parsing for help-about 0058 commandLineParser.process(app.arguments()); 0059 aboutData.processCommandLine(&commandLineParser); 0060 0061 // BUG: https://bugs.kde.org/show_bug.cgi?id=451842 0062 // We currently don't support desktop environments besides KDE Plasma on Wayland 0063 // because we have to rely on KWin's DBus API. 0064 if (KWindowSystem::isPlatformWayland() && !ScreenShotEffect::isLoaded()) { 0065 auto message = i18n("On Wayland, Spectacle requires KDE Plasma's KWin compositor, which does not seem to be available. Use Spectacle on KDE Plasma, or use a different screenshot tool."); 0066 qWarning().noquote() << message; 0067 if (commandLineParser.isSet(CommandLineOptions::self()->background) 0068 || commandLineParser.isSet(CommandLineOptions::self()->dbus)) { 0069 // Return early if not in GUI mode. 0070 return 1; 0071 } else { 0072 KMessageBox::error(nullptr, message); 0073 } 0074 } 0075 0076 // Prevent session manager from restoring the app on start up. 0077 // https://bugs.kde.org/show_bug.cgi?id=430411 0078 auto disableSessionManagement = [](QSessionManager &sm) { 0079 sm.setRestartHint(QSessionManager::RestartNever); 0080 }; 0081 QObject::connect(&app, &QGuiApplication::commitDataRequest, disableSessionManagement); 0082 QObject::connect(&app, &QGuiApplication::saveStateRequest, disableSessionManagement); 0083 0084 // If the new instance command line option has been specified, 0085 // use this alternative path for executing Spectacle. 0086 if (commandLineParser.isSet(CommandLineOptions::self()->newInstance)) { 0087 SpectacleCore spectacleCore; 0088 0089 QObject::connect(qApp, &QApplication::aboutToQuit, Settings::self(), &Settings::save); 0090 QObject::connect(&spectacleCore, &SpectacleCore::allDone, &app, &QCoreApplication::quit, Qt::QueuedConnection); 0091 0092 // fire it up 0093 spectacleCore.activate(app.arguments(), QDir::currentPath()); 0094 0095 return app.exec(); 0096 } 0097 0098 // With the StartupOption::Unique flag, this process will exit during the construction of 0099 // KDBusService if Spectacle has already been registered. 0100 // This object does not need a parent since it will be deleted when it falls out of scope. 0101 KDBusService service(KDBusService::Unique); 0102 0103 SpectacleCore spectacleCore; 0104 0105 QObject::connect(&service, &KDBusService::activateRequested, &spectacleCore, &SpectacleCore::activate); 0106 QObject::connect(&service, &KDBusService::activateActionRequested, &spectacleCore, &SpectacleCore::activateAction); 0107 0108 QObject::connect(&app, &QCoreApplication::aboutToQuit, Settings::self(), &Settings::save); 0109 QObject::connect(&spectacleCore, &SpectacleCore::allDone, &app, &QCoreApplication::quit, Qt::QueuedConnection); 0110 0111 // create the dbus connections 0112 SpectacleDBusAdapter *dbusAdapter = new SpectacleDBusAdapter(&spectacleCore); 0113 QObject::connect(&spectacleCore, &SpectacleCore::dbusScreenshotFailed, dbusAdapter, &SpectacleDBusAdapter::ScreenshotFailed); 0114 QObject::connect(&spectacleCore, &SpectacleCore::dbusRecordingFailed, dbusAdapter, &SpectacleDBusAdapter::RecordingFailed); 0115 QObject::connect(ExportManager::instance(), &ExportManager::imageExported, 0116 &spectacleCore, [dbusAdapter](const ExportManager::Actions &actions, const QUrl &url) { 0117 Q_UNUSED(actions) 0118 Q_EMIT dbusAdapter->ScreenshotTaken(url.toLocalFile()); 0119 }); 0120 QObject::connect(ExportManager::instance(), &ExportManager::videoExported, 0121 &spectacleCore, [dbusAdapter](const ExportManager::Actions &actions, const QUrl &url) { 0122 Q_UNUSED(actions) 0123 Q_EMIT dbusAdapter->RecordingTaken(url.toLocalFile()); 0124 }); 0125 QDBusConnection::sessionBus().registerObject(u"/"_s, &spectacleCore); 0126 QDBusConnection::sessionBus().registerService(u"org.kde.Spectacle"_s); 0127 0128 // fire it up 0129 spectacleCore.activate(app.arguments(), QDir::currentPath()); 0130 0131 return app.exec(); 0132 }