Changeset View
Changeset View
Standalone View
Standalone View
kstart/kstart.cpp
Show All 23 Lines | |||||
24 | */ | 24 | */ | ||
25 | 25 | | |||
26 | #include <config-kde-cli-tools.h> | 26 | #include <config-kde-cli-tools.h> | ||
27 | 27 | | |||
28 | #include <ktoolinvocation.h> | 28 | #include <ktoolinvocation.h> | ||
29 | #include "kstart.h" | 29 | #include "kstart.h" | ||
30 | 30 | | |||
31 | #include <fcntl.h> | 31 | #include <fcntl.h> | ||
32 | #include <iostream> | ||||
32 | #include <stdlib.h> | 33 | #include <stdlib.h> | ||
33 | 34 | | |||
34 | #include <QRegExp> | 35 | #include <QRegExp> | ||
35 | #include <QTimer> | 36 | #include <QTimer> | ||
36 | #include <QDesktopWidget> | 37 | #include <QDesktopWidget> | ||
37 | #include <QApplication> | 38 | #include <QApplication> | ||
38 | #include <QCommandLineParser> | 39 | #include <QCommandLineParser> | ||
39 | #include <QCommandLineOption> | 40 | #include <QCommandLineOption> | ||
40 | #include <QDebug> | 41 | #include <QDebug> | ||
42 | #include <QUrl> | ||||
41 | 43 | | |||
42 | #include <kprocess.h> | 44 | #include <kprocess.h> | ||
43 | #include <kwindowsystem.h> | 45 | #include <kwindowsystem.h> | ||
44 | #include <kaboutdata.h> | 46 | #include <kaboutdata.h> | ||
45 | #include <klocalizedstring.h> | 47 | #include <klocalizedstring.h> | ||
46 | 48 | | |||
47 | #include <kstartupinfo.h> | 49 | #include <kstartupinfo.h> | ||
48 | #include <kxmessages.h> | 50 | #include <kxmessages.h> | ||
49 | 51 | | |||
52 | #include <KIO/ApplicationLauncherJob> | ||||
53 | #include <KIO/CommandLauncherJob> | ||||
54 | | ||||
50 | #include <netwm.h> | 55 | #include <netwm.h> | ||
51 | #include <QX11Info> | 56 | #include <QX11Info> | ||
52 | #include <X11/Xlib.h> | 57 | #include <X11/Xlib.h> | ||
53 | #include <X11/Xutil.h> | 58 | #include <X11/Xutil.h> | ||
54 | 59 | | |||
55 | // some globals | 60 | // some globals | ||
56 | 61 | | |||
57 | static KProcess* proc = nullptr; | 62 | static QString servicePath; // TODO KF6 remove | ||
63 | static QString serviceName; | ||||
58 | static QString exe; | 64 | static QString exe; | ||
65 | static QStringList exeArgs; | ||||
59 | static QString url; | 66 | static QString url; | ||
60 | static QString windowtitle; | 67 | static QString windowtitle; | ||
61 | static QString windowclass; | 68 | static QString windowclass; | ||
62 | static int desktop = 0; | 69 | static int desktop = 0; | ||
63 | static bool activate = false; | 70 | static bool activate = false; | ||
64 | static bool iconify = false; | 71 | static bool iconify = false; | ||
65 | static bool fullscreen = false; | 72 | static bool fullscreen = false; | ||
66 | static NET::States state = {}; | 73 | static NET::States state = {}; | ||
Show All 18 Lines | 91 | else { | |||
85 | // connect to window add to get the NEW windows | 92 | // connect to window add to get the NEW windows | ||
86 | connect(KWindowSystem::self(), &KWindowSystem::windowAdded, this, &KStart::windowAdded); | 93 | connect(KWindowSystem::self(), &KWindowSystem::windowAdded, this, &KStart::windowAdded); | ||
87 | } | 94 | } | ||
88 | // propagate the app startup notification info to the started app | 95 | // propagate the app startup notification info to the started app | ||
89 | // We are not using KApplication, so the env remained set | 96 | // We are not using KApplication, so the env remained set | ||
90 | KStartupInfoId id = KStartupInfo::currentStartupIdEnv(); | 97 | KStartupInfoId id = KStartupInfo::currentStartupIdEnv(); | ||
91 | 98 | | |||
92 | //finally execute the comand | 99 | //finally execute the comand | ||
93 | if (proc) { | 100 | if (!servicePath.isEmpty()) { // TODO KF6 remove | ||
94 | if( int pid = proc->startDetached() ) { | | |||
95 | KStartupInfoData data; | | |||
96 | data.addPid( pid ); | | |||
97 | data.setName( exe ); | | |||
98 | data.setBin( exe.mid( exe.lastIndexOf( QLatin1Char('/') ) + 1 )); | | |||
99 | KStartupInfo::sendChange( id, data ); | | |||
100 | } | | |||
101 | else | | |||
102 | KStartupInfo::sendFinish( id ); // failed to start | | |||
103 | } else { | | |||
104 | QString error; | 101 | QString error; | ||
105 | QString dbusService; | 102 | QString dbusService; | ||
106 | int pid; | 103 | int pid; | ||
107 | if (KToolInvocation::startServiceByDesktopPath(exe, url, &error, &dbusService, &pid) == 0) { | 104 | if (KToolInvocation::startServiceByDesktopPath(exe, url, &error, &dbusService, &pid) == 0) { | ||
108 | printf("%s\n", qPrintable(dbusService)); | 105 | printf("%s\n", qPrintable(dbusService)); | ||
109 | } else { | 106 | } else { | ||
110 | qCritical() << error; | 107 | qCritical() << error; | ||
111 | } | 108 | } | ||
109 | } else if (!serviceName.isEmpty()) { | ||||
110 | KService::Ptr service = KService::serviceByDesktopName(serviceName); | ||||
111 | if (!service) { | ||||
112 | qCritical() << "No such service" << exe; | ||||
113 | } else { | ||||
114 | auto *job = new KIO::ApplicationLauncherJob(service); | ||||
115 | if (!url.isEmpty()) { | ||||
116 | job->setUrls({QUrl(url)}); // TODO use QUrl::fromUserInput(PreferLocalFile)? | ||||
117 | } | ||||
118 | job->exec(); | ||||
119 | if (job->error()) { | ||||
120 | qCritical() << job->errorString(); | ||||
121 | } else { | ||||
122 | std::cout << job->pid() << std::endl; | ||||
davidedmundson: I know it's copied but, there's no need to randomly go to C to use std::cout | |||||
123 | } | ||||
124 | } | ||||
125 | } else { | ||||
126 | auto *job = new KIO::CommandLauncherJob(exe, exeArgs); | ||||
127 | job->exec(); | ||||
112 | } | 128 | } | ||
113 | 129 | | |||
davidedmundson: Isn't command launcherjob doing KStartupInfo things? | |||||
114 | QTimer::singleShot( useRule ? 0 : 120 * 1000, qApp, SLOT( quit())); | 130 | QTimer::singleShot( useRule ? 0 : 120 * 1000, qApp, SLOT( quit())); | ||
115 | } | 131 | } | ||
116 | 132 | | |||
117 | void KStart::sendRule() { | 133 | void KStart::sendRule() { | ||
118 | KXMessages msg; | 134 | KXMessages msg; | ||
119 | QString message; | 135 | QString message; | ||
120 | if( !windowtitle.isEmpty() ) | 136 | if( !windowtitle.isEmpty() ) | ||
121 | message += QStringLiteral("title=") + windowtitle + QStringLiteral("\ntitlematch=3\n"); // 3 = regexp match | 137 | message += QStringLiteral("title=") + windowtitle + QStringLiteral("\ntitlematch=3\n"); // 3 = regexp match | ||
▲ Show 20 Lines • Show All 189 Lines • ▼ Show 20 Line(s) | 315 | { | |||
311 | aboutData.addAuthor( i18n("Matthias Ettrich"), QString(), QStringLiteral("ettrich@kde.org") ); | 327 | aboutData.addAuthor( i18n("Matthias Ettrich"), QString(), QStringLiteral("ettrich@kde.org") ); | ||
312 | aboutData.addAuthor( i18n("David Faure"), QString(), QStringLiteral("faure@kde.org") ); | 328 | aboutData.addAuthor( i18n("David Faure"), QString(), QStringLiteral("faure@kde.org") ); | ||
313 | aboutData.addAuthor( i18n("Richard J. Moore"), QString(), QStringLiteral("rich@kde.org") ); | 329 | aboutData.addAuthor( i18n("Richard J. Moore"), QString(), QStringLiteral("rich@kde.org") ); | ||
314 | KAboutData::setApplicationData(aboutData); | 330 | KAboutData::setApplicationData(aboutData); | ||
315 | 331 | | |||
316 | QCommandLineParser parser; | 332 | QCommandLineParser parser; | ||
317 | aboutData.setupCommandLine(&parser); | 333 | aboutData.setupCommandLine(&parser); | ||
318 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("!+command"), i18n("Command to execute"))); | 334 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("!+command"), i18n("Command to execute"))); | ||
319 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("service"), i18n("Alternative to <command>: desktop file to start. D-Bus service will be printed to stdout"), QLatin1String("desktopfile"))); | 335 | // TODO KF6 remove | ||
336 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("service"), i18n("Alternative to <command>: desktop file path to start. D-Bus service will be printed to stdout. Deprecated: use --application"), QLatin1String("desktopfile"))); | ||||
337 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("application"), i18n("Alternative to <command>: desktop file to start."), QLatin1String("desktopfile"))); | ||||
320 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("url"), i18n("Optional URL to pass <desktopfile>, when using --service"), QLatin1String("url"))); | 338 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("url"), i18n("Optional URL to pass <desktopfile>, when using --service"), QLatin1String("url"))); | ||
321 | // "!" means: all options after command are treated as arguments to the command | 339 | // "!" means: all options after command are treated as arguments to the command | ||
322 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("window"), i18n("A regular expression matching the window title"), QLatin1String("regexp"))); | 340 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("window"), i18n("A regular expression matching the window title"), QLatin1String("regexp"))); | ||
323 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("windowclass"), | 341 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("windowclass"), | ||
324 | i18n("A string matching the window class (WM_CLASS property)\n" | 342 | i18n("A string matching the window class (WM_CLASS property)\n" | ||
325 | "The window class can be found out by running\n" | 343 | "The window class can be found out by running\n" | ||
326 | "'xprop | grep WM_CLASS' and clicking on a window\n" | 344 | "'xprop | grep WM_CLASS' and clicking on a window\n" | ||
327 | "(use either both parts separated by a space or only the right part).\n" | 345 | "(use either both parts separated by a space or only the right part).\n" | ||
Show All 16 Lines | |||||
344 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("onbottom") << QLatin1String("keepbelow"), i18n("Try to keep the window below other windows"))); | 362 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("onbottom") << QLatin1String("keepbelow"), i18n("Try to keep the window below other windows"))); | ||
345 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("skiptaskbar"), i18n("The window does not get an entry in the taskbar"))); | 363 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("skiptaskbar"), i18n("The window does not get an entry in the taskbar"))); | ||
346 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("skippager"), i18n("The window does not get an entry on the pager"))); | 364 | parser.addOption(QCommandLineOption(QStringList() << QLatin1String("skippager"), i18n("The window does not get an entry on the pager"))); | ||
347 | 365 | | |||
348 | parser.process(app); | 366 | parser.process(app); | ||
349 | aboutData.processCommandLine(&parser); | 367 | aboutData.processCommandLine(&parser); | ||
350 | 368 | | |||
351 | if (parser.isSet(QStringLiteral("service"))) { | 369 | if (parser.isSet(QStringLiteral("service"))) { | ||
352 | exe = parser.value(QStringLiteral("service")); | 370 | servicePath = parser.value(QStringLiteral("service")); | ||
371 | url = parser.value(QStringLiteral("url")); | ||||
372 | } else if (parser.isSet(QStringLiteral("application"))) { | ||||
373 | serviceName = parser.value(QStringLiteral("application")); | ||||
353 | url = parser.value(QStringLiteral("url")); | 374 | url = parser.value(QStringLiteral("url")); | ||
354 | } else { | 375 | } else { | ||
355 | if ( parser.positionalArguments().isEmpty() ) { | 376 | QStringList positionalArgs = parser.positionalArguments(); | ||
377 | if (positionalArgs.isEmpty()) { | ||||
356 | qCritical() << i18n("No command specified"); | 378 | qCritical() << i18n("No command specified"); | ||
357 | parser.showHelp(1); | 379 | parser.showHelp(1); | ||
358 | } | 380 | } | ||
359 | 381 | | |||
360 | exe = parser.positionalArguments().at(0); | 382 | exe = positionalArgs.takeFirst(); | ||
361 | proc = new KProcess; | 383 | exeArgs = positionalArgs; | ||
362 | for(int i=0; i < parser.positionalArguments().count(); i++) | | |||
363 | (*proc) << parser.positionalArguments().at(i); | | |||
364 | } | 384 | } | ||
365 | 385 | | |||
366 | desktop = parser.value( QStringLiteral("desktop") ).toInt(); | 386 | desktop = parser.value( QStringLiteral("desktop") ).toInt(); | ||
367 | if ( parser.isSet ( QStringLiteral("alldesktops")) ) | 387 | if ( parser.isSet ( QStringLiteral("alldesktops")) ) | ||
368 | desktop = NETWinInfo::OnAllDesktops; | 388 | desktop = NETWinInfo::OnAllDesktops; | ||
369 | if ( parser.isSet ( QStringLiteral("currentdesktop")) ) | 389 | if ( parser.isSet ( QStringLiteral("currentdesktop")) ) | ||
370 | desktop = KWindowSystem::currentDesktop(); | 390 | desktop = KWindowSystem::currentDesktop(); | ||
371 | 391 | | |||
▲ Show 20 Lines • Show All 80 Lines • Show Last 20 Lines |
I know it's copied but, there's no need to randomly go to C to use std::cout