2020-08-02 22:22:19 +00:00
/*
SPDX - FileCopyrightText : 2003 Lubos Lunak < l . lunak @ kde . org >
2007-04-29 17:35:43 +00:00
2020-08-02 22:22:19 +00:00
SPDX - License - Identifier : MIT
2007-04-29 17:35:43 +00:00
2020-08-02 22:22:19 +00:00
*/
2007-04-29 17:35:43 +00:00
2014-03-17 15:24:10 +00:00
# include <KMessageBox>
# include <KLocalizedString>
2014-03-18 13:34:36 +00:00
# include <KAuth/KAuthAction>
2013-08-15 09:46:53 +00:00
# include <QApplication>
2019-07-09 19:19:26 +00:00
# include <QCommandLineParser>
2013-08-15 09:46:53 +00:00
# include <QDebug>
2007-06-17 17:09:40 +00:00
# include <QProcess>
2013-08-15 09:46:53 +00:00
# include <QtX11Extras/QX11Info>
2013-07-23 08:37:49 +00:00
# include <xcb/xcb.h>
2007-04-29 17:35:43 +00:00
2019-07-09 19:19:26 +00:00
# include <cerrno>
# include <csignal>
2011-01-30 14:34:42 +00:00
int main ( int argc , char * argv [ ] )
{
2014-04-29 06:51:04 +00:00
KLocalizedString : : setApplicationDomain ( " kwin " ) ;
2016-11-02 13:12:11 +00:00
qputenv ( " QT_QPA_PLATFORM " , QByteArrayLiteral ( " xcb " ) ) ;
2013-08-15 09:46:53 +00:00
QApplication app ( argc , argv ) ;
2019-09-16 11:49:52 +00:00
app . setAttribute ( Qt : : AA_UseHighDpiPixmaps , true ) ;
2014-05-30 06:45:57 +00:00
QApplication : : setWindowIcon ( QIcon : : fromTheme ( QStringLiteral ( " dialog-warning " ) ) ) ;
2013-08-15 09:46:53 +00:00
QCoreApplication : : setApplicationName ( QStringLiteral ( " kwin_killer_helper " ) ) ;
QCoreApplication : : setOrganizationDomain ( QStringLiteral ( " kde.org " ) ) ;
QApplication : : setApplicationDisplayName ( i18n ( " Window Manager " ) ) ;
QCoreApplication : : setApplicationVersion ( QStringLiteral ( " 1.0 " ) ) ;
2013-08-28 11:48:49 +00:00
QCommandLineOption pidOption ( QStringLiteral ( " pid " ) ,
i18n ( " PID of the application to terminate " ) , i18n ( " pid " ) ) ;
QCommandLineOption hostNameOption ( QStringLiteral ( " hostname " ) ,
i18n ( " Hostname on which the application is running " ) , i18n ( " hostname " ) ) ;
QCommandLineOption windowNameOption ( QStringLiteral ( " windowname " ) ,
i18n ( " Caption of the window to be terminated " ) , i18n ( " caption " ) ) ;
QCommandLineOption applicationNameOption ( QStringLiteral ( " applicationname " ) ,
i18n ( " Name of the application to be terminated " ) , i18n ( " name " ) ) ;
QCommandLineOption widOption ( QStringLiteral ( " wid " ) ,
i18n ( " ID of resource belonging to the application " ) , i18n ( " id " ) ) ;
QCommandLineOption timestampOption ( QStringLiteral ( " timestamp " ) ,
i18n ( " Time of user action causing termination " ) , i18n ( " time " ) ) ;
QCommandLineParser parser ;
parser . setApplicationDescription ( i18n ( " KWin helper utility " ) ) ;
parser . addHelpOption ( ) ;
parser . addVersionOption ( ) ;
parser . addOption ( pidOption ) ;
parser . addOption ( hostNameOption ) ;
parser . addOption ( windowNameOption ) ;
parser . addOption ( applicationNameOption ) ;
parser . addOption ( widOption ) ;
parser . addOption ( timestampOption ) ;
parser . process ( app ) ;
QString hostname = parser . value ( hostNameOption ) ;
2007-04-29 17:35:43 +00:00
bool pid_ok = false ;
2013-08-28 11:48:49 +00:00
pid_t pid = parser . value ( pidOption ) . toULong ( & pid_ok ) ;
QString caption = parser . value ( windowNameOption ) ;
QString appname = parser . value ( applicationNameOption ) ;
2007-04-29 17:35:43 +00:00
bool id_ok = false ;
2013-08-28 11:48:49 +00:00
xcb_window_t id = parser . value ( widOption ) . toULong ( & id_ok ) ;
2007-04-29 17:35:43 +00:00
bool time_ok = false ;
2013-08-28 11:48:49 +00:00
xcb_timestamp_t timestamp = parser . value ( timestampOption ) . toULong ( & time_ok ) ;
2013-07-23 08:37:49 +00:00
if ( ! pid_ok | | pid = = 0 | | ! id_ok | | id = = XCB_WINDOW_NONE | | ! time_ok | | timestamp = = XCB_TIME_CURRENT_TIME
2011-01-30 14:34:42 +00:00
| | hostname . isEmpty ( ) | | caption . isEmpty ( ) | | appname . isEmpty ( ) ) {
2013-08-28 11:48:49 +00:00
fprintf ( stdout , " %s \n " , qPrintable ( i18n ( " This helper utility is not supposed to be called directly. " ) ) ) ;
parser . showHelp ( 1 ) ;
2011-01-30 14:34:42 +00:00
}
2013-07-23 05:02:52 +00:00
bool isLocal = hostname = = QStringLiteral ( " localhost " ) ;
2013-05-08 15:16:38 +00:00
2013-08-15 09:46:53 +00:00
caption = caption . toHtmlEscaped ( ) ;
appname = appname . toHtmlEscaped ( ) ;
hostname = hostname . toHtmlEscaped ( ) ;
2013-05-08 15:16:38 +00:00
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
2016-11-02 12:55:11 +00:00
? xi18nc ( " @info " , " <p>You tried to close window \" %1 \" from application \" %2 \" (Process ID: %3) but the application is not responding.</p> " ,
2013-05-08 15:16:38 +00:00
caption , appname , pidString )
2016-11-02 12:55:11 +00:00
: xi18nc ( " @info " , " <p>You tried to close window \" %1 \" from application \" %2 \" (Process ID: %3), running on host \" %4 \" , but the application is not responding.</p> " ,
2013-05-08 15:16:38 +00:00
caption , appname , pidString , hostname ) ;
2014-06-05 16:02:43 +00:00
question + = xi18nc ( " @info " ,
2016-11-02 12:55:11 +00:00
" <p>Do you want to terminate this application?</p> "
" <p><warning>Terminating the application will close all of its child windows. Any unsaved data will be lost.</warning></p> "
2013-05-08 15:16:38 +00:00
) ;
2013-07-23 05:02:52 +00:00
KGuiItem continueButton = KGuiItem ( i18n ( " &Terminate Application %1 " , appname ) , QStringLiteral ( " edit-bomb " ) ) ;
KGuiItem cancelButton = KGuiItem ( i18n ( " Wait Longer " ) , QStringLiteral ( " chronometer " ) ) ;
2013-08-15 09:46:53 +00:00
QX11Info : : setAppUserTime ( timestamp ) ;
if ( KMessageBox : : warningContinueCancelWId ( id , question , QString ( ) , continueButton , cancelButton ) = = KMessageBox : : Continue ) {
2013-05-08 15:16:38 +00:00
if ( ! isLocal ) {
2011-01-30 14:34:42 +00:00
QStringList lst ;
2013-07-23 05:02:52 +00:00
lst < < hostname < < QStringLiteral ( " kill " ) < < QString : : number ( pid ) ;
QProcess : : startDetached ( QStringLiteral ( " xon " ) , lst ) ;
2011-03-07 17:03:28 +00:00
} else {
if ( : : kill ( pid , SIGKILL ) & & errno = = EPERM ) {
2013-07-23 05:02:52 +00:00
KAuth : : Action killer ( QStringLiteral ( " org.kde.ksysguard.processlisthelper.sendsignal " ) ) ;
2013-07-23 08:33:26 +00:00
killer . setHelperId ( QStringLiteral ( " org.kde.ksysguard.processlisthelper " ) ) ;
2013-07-23 05:02:52 +00:00
killer . addArgument ( QStringLiteral ( " pid0 " ) , pid ) ;
killer . addArgument ( QStringLiteral ( " pidcount " ) , 1 ) ;
killer . addArgument ( QStringLiteral ( " signal " ) , SIGKILL ) ;
2011-03-07 17:03:28 +00:00
if ( killer . isValid ( ) ) {
2013-08-15 09:46:53 +00:00
qDebug ( ) < < " Using KAuth to kill pid: " < < pid ;
2011-03-07 17:03:28 +00:00
killer . execute ( ) ;
} else {
2013-08-15 09:46:53 +00:00
qDebug ( ) < < " KWin process killer action not valid " ;
2011-03-07 17:03:28 +00:00
}
}
}
2007-04-29 17:35:43 +00:00
}
2011-01-30 14:34:42 +00:00
}