File indexing completed on 2024-05-05 05:38:20
0001 /* 0002 SPDX-FileCopyrightText: 2012 Marco Martin <mart@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <KLocalizedString> 0008 #include <QApplication> 0009 0010 #include <QAction> 0011 #include <QCommandLineParser> 0012 #include <QDBusConnection> 0013 #include <QDBusMessage> 0014 #include <QDebug> 0015 #include <QQuickWindow> 0016 #include <QSessionManager> 0017 #include <QSurfaceFormat> 0018 #include <QUrl> 0019 0020 #include <KAboutData> 0021 #include <KAuthorized> 0022 #include <KDBusService> 0023 #include <KRunner/RunnerManager> 0024 0025 #include <PlasmaQuick/SharedQmlEngine> 0026 0027 #include <iostream> 0028 #include <qqmlengine.h> 0029 0030 #include "view.h" 0031 0032 using namespace Qt::StringLiterals; 0033 0034 int main(int argc, char **argv) 0035 { 0036 auto format = QSurfaceFormat::defaultFormat(); 0037 format.setOption(QSurfaceFormat::ResetNotification); 0038 QSurfaceFormat::setDefaultFormat(format); 0039 0040 QCommandLineParser parser; 0041 0042 // this is needed to fake window position so Plasma Dialog sets correct borders 0043 qputenv("QT_WAYLAND_DISABLE_FIXED_POSITIONS", {}); 0044 // this variable controls whether to reconnect or exit if the compositor dies, given plasmashell does a lot of 0045 // bespoke wayland code disable for now. Consider re-enabling when layer-shell support lands 0046 qunsetenv("QT_WAYLAND_RECONNECT"); 0047 QQuickWindow::setDefaultAlphaBuffer(true); 0048 QApplication app(argc, argv); 0049 qunsetenv("QT_WAYLAND_DISABLE_FIXED_POSITIONS"); 0050 qputenv("QT_WAYLAND_RECONNECT", "1"); 0051 0052 KLocalizedString::setApplicationDomain(QByteArrayLiteral("krunner")); 0053 0054 // TODO: Make it a QGuiApplication once we don't depend on KDELibs4Support 0055 // QGuiApplication app(argc, argv); 0056 0057 KAboutData aboutData(u"krunner"_s, i18n("KRunner"), QStringLiteral(PROJECT_VERSION), i18n("Run Command interface"), KAboutLicense::GPL); 0058 0059 KAboutData::setApplicationData(aboutData); 0060 app.setQuitOnLastWindowClosed(false); 0061 app.setQuitLockEnabled(false); 0062 0063 QCommandLineOption clipboardOption({u"c"_s, u"clipboard"_s}, i18n("Use the clipboard contents as query for KRunner")); 0064 QCommandLineOption daemonOption({u"d"_s, u"daemon"_s}, i18n("Start KRunner in the background, don't show it.")); 0065 QCommandLineOption replaceOption({u"replace"_s}, i18n("Replace an existing instance")); 0066 QCommandLineOption runnerId({u"runner"_s}, i18n("Show only results from the given plugin"), u"runner"_s); 0067 QCommandLineOption listOption({u"list"_s}, i18n("List available plugins")); 0068 0069 parser.addOption(clipboardOption); 0070 parser.addOption(daemonOption); 0071 parser.addOption(replaceOption); 0072 parser.addOption(runnerId); 0073 parser.addOption(listOption); 0074 parser.addPositionalArgument(u"query"_s, i18n("The query to run, only used if -c is not provided")); 0075 0076 aboutData.setupCommandLine(&parser); 0077 0078 parser.process(app); 0079 aboutData.processCommandLine(&parser); 0080 0081 if (parser.isSet(listOption)) { 0082 const auto runners = KRunner::RunnerManager::runnerMetaDataList(); 0083 const QString headline = i18nc("Header for command line output", "Available KRunner plugins, pluginId"); 0084 QString separator; 0085 separator.fill(u'-', headline.length()); 0086 std::cout << qPrintable(headline) << std::endl << qPrintable(separator) << std::endl; 0087 for (const auto &data : runners) { 0088 std::cout << qPrintable(data.name()) << ": " << qPrintable(data.pluginId()) << std::endl; 0089 } 0090 return 0; 0091 } 0092 0093 if (!KAuthorized::authorize(u"run_command"_s)) { 0094 return -1; 0095 } 0096 0097 KDBusService service(KDBusService::Unique | KDBusService::StartupOption(parser.isSet(replaceOption) ? KDBusService::Replace : 0)); 0098 0099 auto disableSessionManagement = [](QSessionManager &sm) { 0100 sm.setRestartHint(QSessionManager::RestartNever); 0101 }; 0102 QObject::connect(&app, &QGuiApplication::commitDataRequest, disableSessionManagement); 0103 QObject::connect(&app, &QGuiApplication::saveStateRequest, disableSessionManagement); 0104 0105 PlasmaQuick::SharedQmlEngine sharedEngine; 0106 // It is important this to be done before the view is created, as it creates internally a framesvgitem for the background 0107 // that needs to use the current plasma theme 0108 sharedEngine.engine()->setProperty("_kirigamiTheme", u"KirigamiPlasmaStyle"_s); 0109 sharedEngine.setInitializationDelayed(true); 0110 View view(&sharedEngine); 0111 0112 auto updateVisibility = [&]() { 0113 const QString query = parser.positionalArguments().value(0); 0114 const bool hasSingleRunnerModeId = parser.isSet(runnerId); 0115 0116 if (parser.isSet(daemonOption)) { 0117 view.setVisible(false); 0118 } else if (parser.isSet(clipboardOption)) { 0119 view.displayWithClipboardContents(); 0120 } else if (!query.isEmpty()) { 0121 if (hasSingleRunnerModeId) { 0122 view.querySingleRunner(parser.value(runnerId), query); 0123 } else { 0124 view.query(query); 0125 } 0126 } else if (hasSingleRunnerModeId) { 0127 view.displaySingleRunner(parser.value(runnerId)); 0128 } else { 0129 view.toggleDisplay(); 0130 } 0131 }; 0132 0133 updateVisibility(); 0134 0135 QObject::connect(&service, &KDBusService::activateRequested, &view, [&](const QStringList &arguments) { 0136 parser.parse(arguments); 0137 updateVisibility(); 0138 }); 0139 QObject::connect(&service, &KDBusService::activateActionRequested, &view, [&view](const QString &action) { 0140 if (action == QLatin1String("RunClipboard")) { 0141 view.displayWithClipboardContents(); 0142 } 0143 }); 0144 0145 return app.exec(); 0146 }