Commit d039c8c7 authored by Gregor Mi's avatar Gregor Mi

Add new "Tools" button above System Monitor's process list

Summary:
This adds a new "Tools" button to the libksysguard widget which opens a menu that contains tools that help with system diagnostics.

- Patch migrated from ReviewBoard https://git.reviewboard.kde.org/r/128854/

Screenshots:

Original (English):
{F5877637}

Localized (German):
{F5877629}

Some tools not installed / old menu version:
{F5712736}

Test Plan:
- Verify that each action in the menu works.
- Verify that if the global keyboard shortcut for Kill Window is changed, that it is updated accordingly in the menu item.

Reviewers: #plasma, colomar, kossebau, broulik, mart, hein, rkflx

Reviewed By: rkflx

Subscribers: apol, anthonyfieroni, andreaska, rkflx, ngraham, plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D10297
parent bdc5b321
......@@ -34,7 +34,7 @@ set_package_properties(Qt5WebKitWidgets PROPERTIES
PURPOSE "Used by the HTML-based GUI ksysguard library"
)
find_package(KF5 REQUIRED COMPONENTS CoreAddons Config I18n WindowSystem Completion Auth WidgetsAddons IconThemes ConfigWidgets Service)
find_package(KF5 REQUIRED COMPONENTS CoreAddons Config I18n WindowSystem Completion Auth WidgetsAddons IconThemes ConfigWidgets Service GlobalAccel KIO)
find_package(KF5 OPTIONAL_COMPONENTS Plasma)
set_package_properties(KF5Plasma PROPERTIES
URL "https://cgit.kde.org/plasma-framework.git/"
......
......@@ -44,6 +44,9 @@ target_link_libraries(processui
KF5::ConfigWidgets
KF5::WidgetsAddons
KF5::IconThemes
KF5::GlobalAccel
KF5::Service
KF5::KIOWidgets
)
target_include_directories(processui
PUBLIC
......
......@@ -135,6 +135,16 @@ Kernel threads are shown as normal processes, but are actually running inside th
</item>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnTools">
<property name="text">
<string>Tools</string>
</property>
<property name="icon">
<iconset theme="application-menu"/>
</property>
</widget>
</item>
</layout>
</item>
<item>
......
......@@ -44,6 +44,7 @@
#include <QToolTip>
#include <QAbstractItemModel>
#include <QDBusMetaType>
#include <QtDBus>
#include <QPointer>
#include <QDialog>
#include <QIcon>
......@@ -57,6 +58,9 @@
#include <klocalizedstring.h>
#include <kmessagebox.h>
#include <KWindowSystem>
#include <KService>
#include <KRun>
#include <KGlobalAccel>
#include "ReniceDlg.h"
#include "ui_ProcessWidgetUI.h"
......@@ -193,7 +197,7 @@ class ProgressBarItemDelegate : public QStyledItemDelegate
struct KSysGuardProcessListPrivate {
KSysGuardProcessListPrivate(KSysGuardProcessList* q, const QString &hostName)
: mModel(q, hostName), mFilterModel(q), mUi(new Ui::ProcessWidget()), mProcessContextMenu(nullptr), mUpdateTimer(nullptr)
: mModel(q, hostName), mFilterModel(q), mUi(new Ui::ProcessWidget()), mProcessContextMenu(nullptr), mUpdateTimer(nullptr), mToolsMenu(new QMenu(q))
{
mScripting = nullptr;
mNeedToExpandInit = false;
......@@ -286,6 +290,8 @@ struct KSysGuardProcessListPrivate {
QAction *sigKill;
QAction *sigUsr1;
QAction *sigUsr2;
QMenu* mToolsMenu;
};
KSysGuardProcessList::KSysGuardProcessList(QWidget* parent, const QString &hostName)
......@@ -378,7 +384,76 @@ KSysGuardProcessList::KSysGuardProcessList(QWidget* parent, const QString &hostN
retranslateUi();
d->mUi->btnKillProcess->setIcon(QIcon::fromTheme(QStringLiteral("process-stop")));
d->mUi->btnKillProcess->setToolTip(i18n("<qt>End the selected process. Warning - you may lose unsaved work.<br>Right click on a process to send other signals.<br>See What's This for technical information.<br>To target a specific window to kill, press Ctrl+Alt+Esc at any time."));
d->mUi->btnKillProcess->setToolTip(i18n("<qt>End the selected process. Warning - you may lose unsaved work.<br>Right click on a process to send other signals.<br>See What's This for technical information."));
auto addByDesktopName = [this](const QString& desktopName)
{
auto kService = KService::serviceByDesktopName(desktopName);
if (kService) {
auto action = new QAction(QIcon::fromTheme(kService->icon()),
kService->name(), nullptr);
connect(action, &QAction::triggered, this,
[kService](bool) {
KRun::runService(*kService, { }, nullptr);
});
d->mToolsMenu->addAction(action);
}
};
addByDesktopName(QStringLiteral("org.kde.konsole"));
const QString ksysguardDesktopName = QStringLiteral("org.kde.ksysguard");
// The following expression is true when the libksysguard process list is _not_ embedded in KSysGuard.
// Only then we add KSysGuard to the menu
if (qApp->desktopFileName() != ksysguardDesktopName) {
addByDesktopName(ksysguardDesktopName);
}
addByDesktopName(QStringLiteral("org.kde.ksystemlog"));
addByDesktopName(QStringLiteral("org.kde.kinfocenter"));
addByDesktopName(QStringLiteral("org.kde.filelight"));
addByDesktopName(QStringLiteral("org.kde.sweeper"));
addByDesktopName(QStringLiteral("org.kde.kmag"));
addByDesktopName(QStringLiteral("htop"));
// Add Run Command...
//
auto runCommandAction = new QAction(i18nc("@action:inmenu", "Run Command"), this);
// //INFO: This is one way of how to find out the two required parameters for the globalShortcut method:
// auto list = KGlobalAccel::getGlobalShortcutsByKey(QKeySequence(QStringLiteral("Alt+Space")));
// foreach (auto item, list) {
// qDebug() << item.componentUniqueName() << item.uniqueName();
// //prints: 'krunner', 'run command'
// }
const auto runCommandShortcutList = KGlobalAccel::self()->globalShortcut(QStringLiteral("krunner"), QStringLiteral("run command"));
runCommandAction->setShortcuts(runCommandShortcutList);
runCommandAction->setIcon(QIcon::fromTheme(QStringLiteral("system-run")));
connect(runCommandAction, &QAction::triggered, this, [](){
KRun::runCommand(QStringLiteral("krunner"), nullptr);
});
d->mToolsMenu->addAction(runCommandAction);
// Add the xkill functionality...
auto killWindowAction = new QAction(QIcon::fromTheme(QStringLiteral("document-close")),
i18nc("@action:inmenu", "Kill a Window"), this);
// Find shortcut of xkill functionality which is defined in KWin
const auto killWindowShortcutList = KGlobalAccel::self()->globalShortcut(QStringLiteral("kwin"), QStringLiteral("Kill Window"));
killWindowAction->setShortcuts(killWindowShortcutList);
// We don't use xkill directly but the method in KWin which allows to press Esc to abort.
auto killWindowKwinMethod = new QDBusInterface(QStringLiteral("org.kde.KWin"), QStringLiteral("/KWin"), QStringLiteral("org.kde.KWin"));
// If KWin is not the window manager, then we disable the entry:
if (!killWindowKwinMethod->isValid()) {
killWindowAction->setEnabled(false);
}
connect(killWindowAction, &QAction::triggered, this, [this, killWindowKwinMethod](bool) {
// with DBus call, always use the async method.
// Otherwise it could wait up to 30 seconds in certain situations.
killWindowKwinMethod->asyncCall(QStringLiteral("killWindow"));
});
d->mToolsMenu->addAction(killWindowAction);
d->mUi->btnTools->setMenu(d->mToolsMenu);
}
KSysGuardProcessList::~KSysGuardProcessList()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment