2007-04-29 17:35:43 +00:00
/****************************************************************************
Copyright ( C ) 2003 Lubos Lunak < l . lunak @ kde . org >
Permission is hereby granted , free of charge , to any person obtaining a
copy of this software and associated documentation files ( the " Software " ) ,
to deal in the Software without restriction , including without limitation
the rights to use , copy , modify , merge , publish , distribute , sublicense ,
and / or sell copies of the Software , and to permit persons to whom the
Software is furnished to do so , subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software .
THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING
FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2014-03-17 15:24:10 +00:00
# include <KMessageBox>
# include <KLocalizedString>
# include <KAuth/Action>
2013-08-15 09:46:53 +00:00
# include <QApplication>
2013-08-29 14:22:30 +00:00
# include <qcommandlineparser.h>
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>
2007-06-17 17:09:40 +00:00
# include <signal.h>
2011-03-07 17:03:28 +00:00
# include <errno.h>
2013-07-23 08:37:49 +00:00
# include <xcb/xcb.h>
2007-04-29 17:35:43 +00:00
2011-01-30 14:34:42 +00:00
int main ( int argc , char * argv [ ] )
{
2013-08-15 09:46:53 +00:00
QApplication app ( argc , argv ) ;
QApplication : : setWindowIcon ( QIcon : : fromTheme ( QStringLiteral ( " kwin " ) ) ) ;
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
? i18nc ( " @info " , " <para>You tried to close window \" %1 \" from application \" %2 \" (Process ID: %3) but the application is not responding.</para> " ,
caption , appname , pidString )
: i18nc ( " @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 ) ;
question + = i18nc ( " @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> "
) ;
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
}