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 .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <kcmdlineargs.h>
# include <kapplication.h>
# include <kmessagebox.h>
2013-03-15 14:44:08 +00:00
# include <KDE/KIcon>
2013-03-07 11:55:39 +00:00
# include <KDE/KLocalizedString>
2011-03-07 17:03:28 +00:00
# include <kauth.h>
# include <kdebug.h>
2007-04-29 17:35:43 +00:00
# include <unistd.h>
2007-06-17 17:09:40 +00:00
# include <QProcess>
2012-05-19 08:20:03 +00:00
// TODO: remove with Qt 5, only for HTML escaping the caption
# include <QTextDocument>
2013-07-23 08:29:01 +00:00
# include <QWidget>
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-05-08 15:16:38 +00:00
KCmdLineArgs : : init ( argc , argv , " kwin_killer_helper " , " kwin " , ki18n ( " Window Manager " ) , " 1.0 " ,
2011-01-30 14:34:42 +00:00
ki18n ( " KWin helper utility " ) ) ;
2007-07-02 08:49:20 +00:00
KCmdLineOptions options ;
2008-04-19 22:36:47 +00:00
options . add ( " pid <pid> " , ki18n ( " PID of the application to terminate " ) ) ;
options . add ( " hostname <hostname> " , ki18n ( " Hostname on which the application is running " ) ) ;
options . add ( " windowname <caption> " , ki18n ( " Caption of the window to be terminated " ) ) ;
options . add ( " applicationname <name> " , ki18n ( " Name of the application to be terminated " ) ) ;
options . add ( " wid <id> " , ki18n ( " ID of resource belonging to the application " ) ) ;
options . add ( " timestamp <time> " , ki18n ( " Time of user action causing termination " ) ) ;
2011-01-30 14:34:42 +00:00
KCmdLineArgs : : addCmdLineOptions ( options ) ;
2007-04-29 17:35:43 +00:00
KApplication app ;
2013-07-23 05:02:52 +00:00
KApplication : : setWindowIcon ( KIcon ( QStringLiteral ( " kwin " ) ) ) ;
2007-04-29 17:35:43 +00:00
KCmdLineArgs * args = KCmdLineArgs : : parsedArgs ( ) ;
2011-01-30 14:34:42 +00:00
QString hostname = args - > getOption ( " hostname " ) ;
2007-04-29 17:35:43 +00:00
bool pid_ok = false ;
2011-01-30 14:34:42 +00:00
pid_t pid = QString ( args - > getOption ( " pid " ) ) . toULong ( & pid_ok ) ;
QString caption = args - > getOption ( " windowname " ) ;
QString appname = args - > getOption ( " applicationname " ) ;
2007-04-29 17:35:43 +00:00
bool id_ok = false ;
2013-07-23 08:37:49 +00:00
xcb_window_t id = QString ( args - > getOption ( " wid " ) ) . toULong ( & id_ok ) ;
2007-04-29 17:35:43 +00:00
bool time_ok = false ;
2013-07-23 08:37:49 +00:00
xcb_timestamp_t timestamp = QString ( args - > getOption ( " timestamp " ) ) . toULong ( & time_ok ) ;
2007-04-29 17:35:43 +00:00
args - > clear ( ) ;
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 ( ) ) {
KCmdLineArgs : : usageError ( i18n ( " This helper utility is not supposed to be called directly. " ) ) ;
return 1 ;
}
2013-07-23 05:02:52 +00:00
bool isLocal = hostname = = QStringLiteral ( " localhost " ) ;
2013-05-08 15:16:38 +00:00
caption = Qt : : escape ( caption ) ;
appname = Qt : : escape ( appname ) ;
hostname = Qt : : escape ( hostname ) ;
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 " ) ) ;
2011-01-30 14:34:42 +00:00
app . updateUserTimestamp ( timestamp ) ;
2013-07-23 08:29:01 +00:00
if ( KMessageBox : : warningContinueCancel ( QWidget : : find ( 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 ( ) ) {
kDebug ( 1212 ) < < " Using KAuth to kill pid: " < < pid ;
killer . execute ( ) ;
} else {
kDebug ( 1212 ) < < " KWin process killer action not valid " ;
}
}
}
2007-04-29 17:35:43 +00:00
}
2011-01-30 14:34:42 +00:00
}