diff --git a/runners/kill/killrunner_config.h b/runners/kill/config_keys.h similarity index 61% copy from runners/kill/killrunner_config.h copy to runners/kill/config_keys.h index 2cdf1b948..f59b16b70 100644 --- a/runners/kill/killrunner_config.h +++ b/runners/kill/config_keys.h @@ -1,59 +1,32 @@ /* Copyright 2009 + * Copyright 2020 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public + * + * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ -#ifndef KILLRUNNERCONFIG_H -#define KILLRUNNERCONFIG_H +#ifndef KILLRUNNER_CONFIG_KEYS_H +#define KILLRUNNER_CONFIG_KEYS_H -//Project-Includes -#include "ui_killrunner_config.h" -//KDE-Includes -#include -//Qt static const char CONFIG_USE_TRIGGERWORD[] = "useTriggerWord"; static const char CONFIG_TRIGGERWORD[] = "triggerWord"; static const char CONFIG_SORTING[] = "sorting"; -class KillRunnerConfigForm : public QWidget, public Ui::KillRunnerConfigUi -{ - Q_OBJECT - -public: - explicit KillRunnerConfigForm(QWidget* parent); -}; - -class KillRunnerConfig : public KCModule -{ - Q_OBJECT - -public: - explicit KillRunnerConfig(QWidget* parent = nullptr, const QVariantList& args = QVariantList()); - - /** Possibilities to sort */ - enum Sort {NONE = 0, CPU, CPUI}; - -public Q_SLOTS: - void save() override; - void load() override; - void defaults() override; +/** Possibilities to sort */ +enum Sort {NONE = 0, CPU, CPUI}; -private: - KillRunnerConfigForm* m_ui; -}; #endif diff --git a/runners/kill/killrunner.cpp b/runners/kill/killrunner.cpp index acad423c3..ca2975179 100644 --- a/runners/kill/killrunner.cpp +++ b/runners/kill/killrunner.cpp @@ -1,225 +1,224 @@ /* Copyright 2009 Jan Gerrit Marker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "killrunner.h" #include #include #include #include #include #include +#include #include "processcore/processes.h" #include "processcore/process.h" -#include "killrunner_config.h" - K_EXPORT_PLASMA_RUNNER(kill, KillRunner) KillRunner::KillRunner(QObject *parent, const QVariantList& args) : Plasma::AbstractRunner(parent, args), m_processes(nullptr) { Q_UNUSED(args); setObjectName( QLatin1String("Kill Runner") ); reloadConfiguration(); connect(this, &Plasma::AbstractRunner::prepare, this, &KillRunner::prep); connect(this, &Plasma::AbstractRunner::teardown, this, &KillRunner::cleanup); m_delayedCleanupTimer.setInterval(50); m_delayedCleanupTimer.setSingleShot(true); connect(&m_delayedCleanupTimer, &QTimer::timeout, this, &KillRunner::cleanup); } KillRunner::~KillRunner() { } void KillRunner::reloadConfiguration() { KConfigGroup grp = config(); m_triggerWord.clear(); if (grp.readEntry(CONFIG_USE_TRIGGERWORD, true)) { m_triggerWord = grp.readEntry(CONFIG_TRIGGERWORD, i18n("kill")) + QLatin1Char(' '); } - m_sorting = (KillRunnerConfig::Sort) grp.readEntry(CONFIG_SORTING, 0); + m_sorting = (Sort) grp.readEntry(CONFIG_SORTING, static_cast(Sort::NONE)); QList syntaxes; syntaxes << Plasma::RunnerSyntax(m_triggerWord + QStringLiteral(":q:"), i18n("Terminate running applications whose names match the query.")); setSyntaxes(syntaxes); } void KillRunner::prep() { m_delayedCleanupTimer.stop(); } void KillRunner::cleanup() { if (!m_processes) { return; } if (m_prepLock.tryLockForWrite()) { delete m_processes; m_processes = nullptr; m_prepLock.unlock(); } else { m_delayedCleanupTimer.stop(); } } void KillRunner::match(Plasma::RunnerContext &context) { QString term = context.query(); const bool hasTrigger = !m_triggerWord.isEmpty(); if (hasTrigger && !term.startsWith(m_triggerWord, Qt::CaseInsensitive)) { return; } m_prepLock.lockForRead(); if (!m_processes) { m_prepLock.unlock(); m_prepLock.lockForWrite(); if (!m_processes) { suspendMatching(true); m_processes = new KSysGuard::Processes(); m_processes->updateAllProcesses(); suspendMatching(false); } } m_prepLock.unlock(); term = term.right(term.length() - m_triggerWord.length()); if (term.length() < 2) { return; } QList matches; const QList processlist = m_processes->getAllProcesses(); for (const KSysGuard::Process *process : processlist) { if (!context.isValid()) { return; } const QString name = process->name(); if (!name.contains(term, Qt::CaseInsensitive)) { //Process doesn't match the search term continue; } const quint64 pid = process->pid(); const qlonglong uid = process->uid(); const QString user = getUserName(uid); QVariantList data; data << pid << user; Plasma::QueryMatch match(this); match.setText(i18n("Terminate %1", name)); match.setSubtext(i18n("Process ID: %1\nRunning as user: %2", QString::number(pid), user)); match.setIconName(QStringLiteral("application-exit")); match.setData(data); match.setId(name); // Set the relevance switch (m_sorting) { - case KillRunnerConfig::CPU: + case Sort::CPU: match.setRelevance((process->userUsage() + process->sysUsage()) / 100); break; - case KillRunnerConfig::CPUI: + case Sort::CPUI: match.setRelevance(1 - (process->userUsage() + process->sysUsage()) / 100); break; - case KillRunnerConfig::NONE: + case Sort::NONE: match.setRelevance(name.compare(term, Qt::CaseInsensitive) == 0 ? 1 : 9); break; } matches << match; } qDebug() << "match count is" << matches.count(); context.addMatches(matches); } void KillRunner::run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) { Q_UNUSED(context) QVariantList data = match.data().value(); quint64 pid = data[0].toUInt(); // QString user = data[1].toString(); int signal; if (match.selectedAction() != nullptr) { signal = match.selectedAction()->data().toInt(); } else { signal = 9; //default: SIGKILL } QStringList args; args << QStringLiteral("-%1").arg(signal) << QStringLiteral("%1").arg(pid); KProcess process; int returnCode = process.execute(QStringLiteral("kill"), args); if (returnCode == 0) { return; } KAuth::Action killAction = QStringLiteral("org.kde.ksysguard.processlisthelper.sendsignal"); killAction.setHelperId(QStringLiteral("org.kde.ksysguard.processlisthelper")); killAction.addArgument(QStringLiteral("pid0"), pid); killAction.addArgument(QStringLiteral("pidcount"), 1); killAction.addArgument(QStringLiteral("signal"), signal); killAction.execute(); } QList KillRunner::actionsForMatch(const Plasma::QueryMatch &match) { Q_UNUSED(match) QList ret; if (!action(QStringLiteral("SIGTERM"))) { (addAction(QStringLiteral("SIGTERM"), QIcon::fromTheme(QStringLiteral("application-exit")), i18n("Send SIGTERM")))->setData(15); (addAction(QStringLiteral("SIGKILL"), QIcon::fromTheme(QStringLiteral("process-stop")), i18n("Send SIGKILL")))->setData(9); } ret << action(QStringLiteral("SIGTERM")) << action(QStringLiteral("SIGKILL")); return ret; } QString KillRunner::getUserName(qlonglong uid) { KUser user(uid); if (user.isValid()) { return user.loginName(); } qDebug() << QStringLiteral("No user with UID %1 was found").arg(uid); return QStringLiteral("root");//No user with UID uid was found, so root is used } #include "killrunner.moc" diff --git a/runners/kill/killrunner.h b/runners/kill/killrunner.h index c992617d8..56fdf11ef 100644 --- a/runners/kill/killrunner.h +++ b/runners/kill/killrunner.h @@ -1,76 +1,76 @@ /* Copyright 2009 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef KILLRUNNER_H #define KILLRUNNER_H #include #include #include -#include "killrunner_config.h" +#include "config_keys.h" class QAction; namespace KSysGuard { class Processes; class Process; } class KillRunner : public Plasma::AbstractRunner { Q_OBJECT public: KillRunner(QObject *parent, const QVariantList& args); ~KillRunner() override; void match(Plasma::RunnerContext &context) override; void run(const Plasma::RunnerContext &context, const Plasma::QueryMatch &match) override; QList actionsForMatch(const Plasma::QueryMatch &match) override; void reloadConfiguration() override; private Q_SLOTS: void prep(); void cleanup(); private: /** @param uid the uid of the user * @return the username of the user with the UID uid */ QString getUserName(qlonglong uid); /** The trigger word */ QString m_triggerWord; /** How to sort */ - KillRunnerConfig::Sort m_sorting; + Sort m_sorting; /** process lister */ KSysGuard::Processes *m_processes; /** lock for initializing m_processes */ QReadWriteLock m_prepLock; /** timer for retrying the cleanup due to lock contention */ QTimer m_delayedCleanupTimer; }; #endif diff --git a/runners/kill/killrunner_config.cpp b/runners/kill/killrunner_config.cpp index effb8b538..9bf58a9da 100644 --- a/runners/kill/killrunner_config.cpp +++ b/runners/kill/killrunner_config.cpp @@ -1,100 +1,101 @@ /* Copyright 2009 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ //Project-Includes #include "killrunner_config.h" #include //KDE-Includes #include #include #include +#include "config_keys.h" K_PLUGIN_FACTORY(KillRunnerConfigFactory, registerPlugin(QStringLiteral("kcm_krunner_kill"));) KillRunnerConfigForm::KillRunnerConfigForm(QWidget* parent) : QWidget(parent) { setupUi(this); } KillRunnerConfig::KillRunnerConfig(QWidget* parent, const QVariantList& args) : KCModule(parent, args) { m_ui = new KillRunnerConfigForm(this); QGridLayout* layout = new QGridLayout(this); layout->addWidget(m_ui, 0, 0); m_ui->sorting->addItem(i18n("CPU usage"), CPU); m_ui->sorting->addItem(i18n("inverted CPU usage"), CPUI); m_ui->sorting->addItem(i18n("nothing"), NONE); #if KCONFIGWIDGETS_VERSION < QT_VERSION_CHECK(5, 64, 0) connect(m_ui->useTriggerWord, &QCheckBox::stateChanged, this, QOverload<>::of(&KillRunnerConfig::changed)); connect(m_ui->triggerWord, &KLineEdit::textChanged, this, QOverload<>::of(&KillRunnerConfig::changed)); connect(m_ui->sorting, QOverload::of(&QComboBox::currentIndexChanged), this, QOverload<>::of(&KillRunnerConfig::changed)); #else connect(m_ui->useTriggerWord, &QCheckBox::stateChanged, this, &KillRunnerConfig::markAsChanged); connect(m_ui->triggerWord, &KLineEdit::textChanged, this, &KillRunnerConfig::markAsChanged); connect(m_ui->sorting, QOverload::of(&QComboBox::currentIndexChanged), this, &KillRunnerConfig::markAsChanged); #endif load(); } void KillRunnerConfig::load() { KCModule::load(); KSharedConfig::Ptr cfg = KSharedConfig::openConfig(QStringLiteral("krunnerrc")); KConfigGroup grp = cfg->group("Runners"); grp = KConfigGroup(&grp, "Kill Runner"); m_ui->useTriggerWord->setChecked(grp.readEntry(CONFIG_USE_TRIGGERWORD,true)); m_ui->triggerWord->setText(grp.readEntry(CONFIG_TRIGGERWORD,i18n("kill"))); m_ui->sorting->setCurrentIndex(m_ui->sorting->findData(grp.readEntry(CONFIG_SORTING, static_cast(NONE)))); emit changed(false); } void KillRunnerConfig::save() { KCModule::save(); KSharedConfig::Ptr cfg = KSharedConfig::openConfig(QStringLiteral("krunnerrc")); KConfigGroup grp = cfg->group("Runners"); grp = KConfigGroup(&grp, "Kill Runner"); grp.writeEntry(CONFIG_USE_TRIGGERWORD,m_ui->useTriggerWord->isChecked()); grp.writeEntry(CONFIG_TRIGGERWORD,m_ui->triggerWord->text()); grp.writeEntry(CONFIG_SORTING,m_ui->sorting->itemData(m_ui->sorting->currentIndex())); emit changed(false); } void KillRunnerConfig::defaults() { KCModule::defaults(); m_ui->useTriggerWord->setChecked(true); m_ui->triggerWord->setText(i18n("kill")); m_ui->sorting->setCurrentIndex(m_ui->sorting->findData((int) NONE)); emit changed(true); } #include "killrunner_config.moc" diff --git a/runners/kill/killrunner_config.h b/runners/kill/killrunner_config.h index 2cdf1b948..4cae88ef7 100644 --- a/runners/kill/killrunner_config.h +++ b/runners/kill/killrunner_config.h @@ -1,59 +1,52 @@ /* Copyright 2009 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef KILLRUNNERCONFIG_H #define KILLRUNNERCONFIG_H //Project-Includes #include "ui_killrunner_config.h" //KDE-Includes #include //Qt -static const char CONFIG_USE_TRIGGERWORD[] = "useTriggerWord"; -static const char CONFIG_TRIGGERWORD[] = "triggerWord"; -static const char CONFIG_SORTING[] = "sorting"; - class KillRunnerConfigForm : public QWidget, public Ui::KillRunnerConfigUi { Q_OBJECT public: explicit KillRunnerConfigForm(QWidget* parent); }; class KillRunnerConfig : public KCModule { Q_OBJECT public: explicit KillRunnerConfig(QWidget* parent = nullptr, const QVariantList& args = QVariantList()); - - /** Possibilities to sort */ - enum Sort {NONE = 0, CPU, CPUI}; public Q_SLOTS: void save() override; void load() override; void defaults() override; private: KillRunnerConfigForm* m_ui; }; #endif