summaryrefslogtreecommitdiff
Unidiff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--core/launcher/runningappbar.cpp125
-rw-r--r--core/launcher/runningappbar.h8
2 files changed, 82 insertions, 51 deletions
diff --git a/core/launcher/runningappbar.cpp b/core/launcher/runningappbar.cpp
index c8f45d5..3ac66f2 100644
--- a/core/launcher/runningappbar.cpp
+++ b/core/launcher/runningappbar.cpp
@@ -26,3 +26,6 @@
26#include <signal.h> 26#include <signal.h>
27#include <stdio.h>
28#include <stdlib.h>
27 29
30#include <qdir.h>
28#include <qtimer.h> 31#include <qtimer.h>
@@ -31,3 +34,3 @@
31#include <qpainter.h> 34#include <qpainter.h>
32#include "qprocess.h" 35#include <opie/oprocess.h>
33#include <qpe/qpeapplication.h> 36#include <qpe/qpeapplication.h>
@@ -47,2 +50,3 @@ RunningAppBar::RunningAppBar(QWidget* parent)
47#ifdef QWS 50#ifdef QWS
51
48 connect(qwsServer, SIGNAL(newChannel(const QString&)), this, SLOT(newQcopChannel(const QString&))); 52 connect(qwsServer, SIGNAL(newChannel(const QString&)), this, SLOT(newQcopChannel(const QString&)));
@@ -50,2 +54,3 @@ RunningAppBar::RunningAppBar(QWidget* parent)
50#endif 54#endif
55
51 QCopChannel* channel = new QCopChannel( "QPE/System", this ); 56 QCopChannel* channel = new QCopChannel( "QPE/System", this );
@@ -57,6 +62,7 @@ RunningAppBar::RunningAppBar(QWidget* parent)
57 62
58RunningAppBar::~RunningAppBar() { 63RunningAppBar::~RunningAppBar()
59} 64{}
60 65
61void RunningAppBar::newQcopChannel(const QString& channelName) { 66void RunningAppBar::newQcopChannel(const QString& channelName)
67{
62 QString prefix("QPE/Application/"); 68 QString prefix("QPE/Application/");
@@ -72,3 +78,4 @@ void RunningAppBar::newQcopChannel(const QString& channelName) {
72 78
73void RunningAppBar::removedQcopChannel(const QString& channelName) { 79void RunningAppBar::removedQcopChannel(const QString& channelName)
80{
74 QString prefix("QPE/Application/"); 81 QString prefix("QPE/Application/");
@@ -84,3 +91,4 @@ void RunningAppBar::removedQcopChannel(const QString& channelName) {
84 91
85void RunningAppBar::received(const QCString& msg, const QByteArray& data) { 92void RunningAppBar::received(const QCString& msg, const QByteArray& data)
93{
86 // Since fast apps appear and disappear without disconnecting from their 94 // Since fast apps appear and disappear without disconnecting from their
@@ -92,3 +100,4 @@ void RunningAppBar::received(const QCString& msg, const QByteArray& data) {
92 addTask(*m_AppLnkSet->findExec(appName)); 100 addTask(*m_AppLnkSet->findExec(appName));
93 } else if ( msg == "fastAppHiding(QString)") { 101 }
102 else if ( msg == "fastAppHiding(QString)") {
94 QString appName; 103 QString appName;
@@ -99,3 +108,4 @@ void RunningAppBar::received(const QCString& msg, const QByteArray& data) {
99 108
100void RunningAppBar::addTask(const AppLnk& appLnk) { 109void RunningAppBar::addTask(const AppLnk& appLnk)
110{
101// qDebug("Added %s to app list.", appLnk.name().latin1()); 111// qDebug("Added %s to app list.", appLnk.name().latin1());
@@ -107,3 +117,4 @@ void RunningAppBar::addTask(const AppLnk& appLnk) {
107 117
108void RunningAppBar::removeTask(const AppLnk& appLnk) { 118void RunningAppBar::removeTask(const AppLnk& appLnk)
119{
109 unsigned int i = 0; 120 unsigned int i = 0;
@@ -114,2 +125,12 @@ void RunningAppBar::removeTask(const AppLnk& appLnk) {
114 m_AppList.remove(); 125 m_AppList.remove();
126
127 // grab the keyboard back, in case the app crashed/forgot
128
129 QPEApplication *qpeapp = (QPEApplication *) qApp;
130
131 if ( appLnk.exec() == qpeapp-> keyboardGrabbedBy ( )) {
132 qDebug ( "grabbing keyboard back from %s", appLnk.name().latin1());
133 qpeapp-> grabKeyboard ( );
134 }
135
115 delete target; 136 delete target;
@@ -136,3 +157,4 @@ void RunningAppBar::mousePressEvent(QMouseEvent *e)
136 } 157 }
137 } else { 158 }
159 else {
138 break; 160 break;
@@ -199,3 +221,4 @@ const int AppMonitor::RAISE_TIMEOUT_MS = 500;
199AppMonitor::AppMonitor(const AppLnk& app, RunningAppBar& owner) 221AppMonitor::AppMonitor(const AppLnk& app, RunningAppBar& owner)
200 : QObject(0L), m_Owner(owner), m_App(app), m_PsProc(0L), m_AppKillerBox(0L) { 222 : QObject(0L), m_Owner(owner), m_App(app), m_AppKillerBox(0L)
223{
201 QCopChannel* channel = new QCopChannel( "QPE/System", this ); 224 QCopChannel* channel = new QCopChannel( "QPE/System", this );
@@ -207,3 +230,4 @@ AppMonitor::AppMonitor(const AppLnk& app, RunningAppBar& owner)
207 230
208AppMonitor::~AppMonitor() { 231AppMonitor::~AppMonitor()
232{
209 if (m_AppKillerBox) { 233 if (m_AppKillerBox) {
@@ -214,3 +238,4 @@ AppMonitor::~AppMonitor() {
214 238
215void AppMonitor::received(const QCString& msg, const QByteArray& data) { 239void AppMonitor::received(const QCString& msg, const QByteArray& data)
240{
216 QDataStream stream( data, IO_ReadOnly ); 241 QDataStream stream( data, IO_ReadOnly );
@@ -239,4 +264,4 @@ void AppMonitor::received(const QCString& msg, const QByteArray& data) {
239 264
240void AppMonitor::timerExpired() { 265void AppMonitor::timerExpired()
241 // qDebug("Checking in on %s", m_App.name().latin1()); 266{
242 // We store this incase the application responds while we're 267 // We store this incase the application responds while we're
@@ -251,41 +276,47 @@ void AppMonitor::timerExpired() {
251 if (m_AppKillerBox->exec() == QMessageBox::Yes) { 276 if (m_AppKillerBox->exec() == QMessageBox::Yes) {
252 // qDebug("Killing the app!!! Bwuhahahaha!"); 277 QDir proc ( "/proc/", "[0-9]*", QDir::Name | QDir::Reversed, QDir::Dirs );
253 m_PsProc = new QProcess(QString("ps")); 278 QStringList allprocs = proc. entryList ( );
254 m_PsProc->addArgument("h");
255 m_PsProc->addArgument("-C");
256 m_PsProc->addArgument(m_App.exec());
257 m_PsProc->addArgument("-o");
258 m_PsProc->addArgument("pid");
259 connect(m_PsProc, SIGNAL(processExited()), this, SLOT(psProcFinished()));
260 m_PsProc->start();
261 }
262 else {
263 // qDebug("Wuss..");
264 // WE DELETE OURSELVES HERE! Don't do anything else!!
265 delete this;
266 }
267}
268 279
269void AppMonitor::psProcFinished() { 280 pid_t mypid = ::getpid ( );
270 QString pid = m_PsProc->readLineStdout();
271 delete m_PsProc;
272 m_PsProc = 0L;
273 281
274 // qDebug("Killing app %s", pid.latin1()); 282 for ( QStringList::Iterator it = allprocs. begin ( ); it != allprocs. end ( ); ++it ) {
275 if (pid.isEmpty()) { 283 if (( *it ). toInt ( ) <= mypid ) // only interested in children
276 // Hmm.. did the application bail before we got there? 284 continue;
277 qDebug("AppMonitor: Tried to kill application %s but ps couldn't find it.", m_App.exec().latin1()); 285
278 } 286 QCString s = QString ( "/proc/" + *it + "/stat" ). local8Bit ( );
279 else { 287
280 int success = kill(pid.toUInt(), SIGKILL); 288 FILE *fp = ::fopen ( s. data ( ), "r" );
281 if (success == 0) { 289 if ( fp ) {
290 pid_t pid, ppid;
291 char *execptr, *exec = 0;
292
293 if ( ::fscanf ( fp, "%d %as %*c %d ", &pid, &execptr, &ppid ) == 3 ) {
294 exec = execptr [0] ? execptr + 1 : execptr;
295 if ( exec [0] )
296 exec [::strlen ( exec ) - 1] = 0;
297
298 if (( ppid == ::getpid ( )) && ( m_App. exec ( ). local8Bit ( ) == exec )) {
299 bool success = false;
300
301 qDebug ( "trying to kill pid=%d, exec=%s, ppid=%d", pid, exec, ppid );
302
303
304 success |= ( ::kill ( pid, SIGTERM ) == 0 );
305 ::usleep ( 1000 * 500 );
306 success |= ( ::kill ( pid, SIGKILL ) == 0 );
307
308 if ( success )
282 m_Owner.removeTask(m_App); 309 m_Owner.removeTask(m_App);
310
311 ::free ( execptr );
312 break;
313 }
314 ::free ( execptr );
315 }
316 ::fclose ( fp );
283 } 317 }
284 else {
285 qWarning("Could not kill task %s", m_App.exec().latin1());
286 } 318 }
287 } 319 }
288
289 // WE DELETE OURSELVES HERE! Don't do anything else!!
290 delete this; 320 delete this;
291} 321}
322
diff --git a/core/launcher/runningappbar.h b/core/launcher/runningappbar.h
index 880bb69..eb5880e 100644
--- a/core/launcher/runningappbar.h
+++ b/core/launcher/runningappbar.h
@@ -33,3 +33,4 @@ class QMessageBox;
33 33
34class RunningAppBar : public QFrame { 34class RunningAppBar : public QFrame
35{
35 Q_OBJECT 36 Q_OBJECT
@@ -64,3 +65,4 @@ class RunningAppBar : public QFrame {
64 */ 65 */
65class AppMonitor : public QObject { 66class AppMonitor : public QObject
67{
66 Q_OBJECT 68 Q_OBJECT
@@ -76,3 +78,2 @@ class AppMonitor : public QObject {
76 void received(const QCString& msg, const QByteArray& data); 78 void received(const QCString& msg, const QByteArray& data);
77 void psProcFinished();
78 79
@@ -82,3 +83,2 @@ class AppMonitor : public QObject {
82 QTimer m_Timer; 83 QTimer m_Timer;
83 QProcess* m_PsProc;
84 QMessageBox* m_AppKillerBox; 84 QMessageBox* m_AppKillerBox;