helpers/killer: Modernize UI

This overhauls the kill prompt UI to make it more modern and more
easily to grasp.

* Reduce the amount of text and redundancy.
  Give the window a title and drop the "app is not responding" heading.
  Try to remove the application name from the displayed window title.
  Also use the bold emphasis used in other places like deleting files.

* Use the application icon if available with a warning overlay.
  This makes it easier to grasp which application it's talking about.

* Move technical information (like PID and hostname) into an
  expandable "Details" section.

KGuiAddons has been implicitly pulled in by KConfigWidgets already.
wilder/Plasma/6.2
Kai Uwe Broulik 2 years ago committed by Vlad Zahorodnii
parent 5c96c38e39
commit 7bd9ae8d0b
  1. 1
      CMakeLists.txt
  2. 2
      src/helpers/killer/CMakeLists.txt
  3. 55
      src/helpers/killer/killer.cpp

@ -83,6 +83,7 @@ find_package(KF6 ${KF6_MIN_VERSION} REQUIRED COMPONENTS
Crash
DBusAddons
GlobalAccel
GuiAddons
I18n
IdleTime
Package

@ -8,7 +8,9 @@ qt6_generate_wayland_protocol_client_sources(kwin_killer_helper FILES ${WaylandP
target_link_libraries(kwin_killer_helper
KF6::AuthCore
KF6::GuiAddons
KF6::I18n
KF6::Service
KF6::WidgetsAddons
Qt::GuiPrivate
Qt::WaylandClient

@ -7,9 +7,11 @@
*/
#include <KAuth/Action>
#include <KIconUtils>
#include <KLocalizedString>
#include <KMessageBox>
#include <KMessageDialog>
#include <KService>
#include <QApplication>
#include <QCommandLineParser>
@ -65,7 +67,7 @@ int main(int argc, char *argv[])
{
KLocalizedString::setApplicationDomain(QByteArrayLiteral("kwin"));
QApplication app(argc, argv);
QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("dialog-warning")));
QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("tools-report-bug")));
QCoreApplication::setApplicationName(QStringLiteral("kwin_killer_helper"));
QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org"));
QApplication::setApplicationDisplayName(i18n("Window Manager"));
@ -126,23 +128,32 @@ int main(int argc, char *argv[])
}
bool isLocal = hostname == QStringLiteral("localhost");
const auto service = KService::serviceByDesktopName(appname);
if (service) {
appname = service->name();
QApplication::setApplicationDisplayName(appname);
}
// Drop redundant application name, cf. QXcbWindow::setWindowTitle.
const QString titleSeparator = QString::fromUtf8(" \xe2\x80\x94 "); // // U+2014, EM DASH
caption.remove(titleSeparator + appname);
caption.remove(QStringLiteral("") + appname); // EN dash (Firefox)
caption.remove(QStringLiteral(" - ") + appname); // classic minus :-)
caption = caption.toHtmlEscaped();
appname = appname.toHtmlEscaped();
hostname = hostname.toHtmlEscaped();
QString pidString = QString::number(pid); // format pid ourself as it does not make sense to format an ID according to locale settings
QString question = i18nc("@info", "<b>Application \"%1\" is not responding</b>", appname);
question += isLocal
? xi18nc("@info", "<para>You tried to close window \"%1\" from application \"%2\" (Process ID: %3) but the application is not responding.</para>",
caption, appname, pidString)
: xi18nc("@info", "<para>You tried to close window \"%1\" from application \"%2\" (Process ID: %3), running on host \"%4\", but the application is not responding.</para>",
caption, appname, pidString, hostname);
QString question = (caption == appname) ? xi18nc("@info", "<para><application>%1</application> is not responding. Do you want to terminate this application?</para>",
appname)
: xi18nc("@info \"window title\" of application name is not responding.", "<para>\"%1\" of <application>%2</application> is not responding. Do you want to terminate this application?</para>",
caption, appname);
question += xi18nc("@info",
"<para>Do you want to terminate this application?</para>"
"<para><warning>Terminating the application will close all of its child windows. Any unsaved data will be lost.</warning></para>");
"<para><emphasis strong='true'>Terminating this application will close all of its windows. Any unsaved data will be lost.</emphasis></para>");
KGuiItem continueButton = KGuiItem(i18n("&Terminate Application %1", appname), QStringLiteral("edit-bomb"));
KGuiItem cancelButton = KGuiItem(i18n("Wait Longer"), QStringLiteral("chronometer"));
KGuiItem continueButton = KGuiItem(i18nc("@action:button Terminate app", "&Terminate %1", appname), QStringLiteral("application-exit"));
KGuiItem cancelButton = KGuiItem(i18nc("@action:button Wait for frozen app to maybe respond again", "&Wait Longer"), QStringLiteral("chronometer"));
if (isX11) {
QX11Info::setAppUserTime(timestamp);
@ -150,9 +161,27 @@ int main(int argc, char *argv[])
auto *dialog = new KMessageDialog(KMessageDialog::WarningContinueCancel, question);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setCaption(QString()); // use default caption.
dialog->setIcon(QIcon()); // use default warning icon.
dialog->setCaption(i18nc("@title:window", "Not Responding"));
QIcon icon;
if (service) {
const QIcon appIcon = QIcon::fromTheme(service->icon());
if (!appIcon.isNull()) {
// emblem-warning is non-standard, fall back to emblem-important if necessary.
const QIcon warningBadge = QIcon::fromTheme(QStringLiteral("emblem-warning"), QIcon::fromTheme(QStringLiteral("emblem-important")));
icon = KIconUtils::addOverlay(appIcon, warningBadge, qApp->isRightToLeft() ? Qt::BottomLeftCorner : Qt::BottomRightCorner);
}
}
dialog->setIcon(icon); // null icon will result in default warning icon.
dialog->setButtons(continueButton, KGuiItem(), cancelButton);
QStringList details{
i18nc("@info", "Process ID: %1", pidString)};
if (!isLocal) {
details << i18nc("@info", "Host name: %1", hostname);
}
dialog->setDetails(details.join(QLatin1Char('\n')));
dialog->winId();
std::unique_ptr<XdgImporter> xdgImporter;

Loading…
Cancel
Save