summaryrefslogtreecommitdiff
path: root/core/launcher/runningappbar.cpp
authorzecke <zecke>2003-08-28 14:40:33 (UTC)
committer zecke <zecke>2003-08-28 14:40:33 (UTC)
commitfcc9c16cbd679ebc459ff0ec6228bbdedbfdfe1d (patch) (unidiff)
tree3a304196f52e12761cab01420a189be4369a9522 /core/launcher/runningappbar.cpp
parent8aff9d2f2d079e4500b6bbbd9f410c16cee3f6a1 (diff)
downloadopie-fcc9c16cbd679ebc459ff0ec6228bbdedbfdfe1d.zip
opie-fcc9c16cbd679ebc459ff0ec6228bbdedbfdfe1d.tar.gz
opie-fcc9c16cbd679ebc459ff0ec6228bbdedbfdfe1d.tar.bz2
Compile fixes
Diffstat (limited to 'core/launcher/runningappbar.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/launcher/runningappbar.cpp356
1 files changed, 111 insertions, 245 deletions
diff --git a/core/launcher/runningappbar.cpp b/core/launcher/runningappbar.cpp
index 356200b..1fda5a4 100644
--- a/core/launcher/runningappbar.cpp
+++ b/core/launcher/runningappbar.cpp
@@ -18,4 +18,3 @@
18** 18**
19********************************************************************** 19***********************************************************************/
20*/
21 20
@@ -23,39 +22,27 @@
23 22
24// For "kill" 23#include <qtopia/global.h>
25#include <sys/types.h> 24
26#include <signal.h>
27#include <stdio.h>
28#include <stdlib.h> 25#include <stdlib.h>
29 26
30#include <qdir.h>
31#include <qtimer.h> 27#include <qtimer.h>
32#include <qpopupmenu.h> 28#include <qpopupmenu.h>
33#include <qmessagebox.h>
34#include <qpainter.h> 29#include <qpainter.h>
35#include <opie/oprocess.h> 30#include <qmessagebox.h>
36#include <qpe/qpeapplication.h> 31
37#include <qpe/applnk.h> 32#include <qtopia/qpeapplication.h>
38#include <qpe/qcopenvelope_qws.h> 33#include <qtopia/applnk.h>
39#include <qpe/global.h> 34#include <qtopia/qcopenvelope_qws.h>
40#include <qwindowsystem_qws.h> 35#include <qtopia/mimetype.h>
36
41#include "runningappbar.h" 37#include "runningappbar.h"
38#include "serverinterface.h"
42 39
43RunningAppBar::RunningAppBar(QWidget* parent) 40RunningAppBar::RunningAppBar(QWidget* parent)
44 : QFrame(parent), m_AppLnkSet(0L), m_SelectedAppIndex( -1) 41 : QFrame(parent), selectedAppIndex(-1)
45{ 42{
46 setBackgroundMode( PaletteBackground ); 43 QCopChannel* channel = new QCopChannel( "QPE/System", this );
47 44 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
48 m_AppLnkSet = new AppLnkSet( QPEApplication::qpeDir() + "apps" ); 45 this, SLOT(received(const QCString&, const QByteArray&)) );
49
50#ifdef QWS
51 46
52 connect(qwsServer, SIGNAL(newChannel(const QString&)), this, SLOT(newQcopChannel(const QString&))); 47 spacing = AppLnk::smallIconSize()+3;
53 connect(qwsServer, SIGNAL(removedChannel(const QString&)), this, SLOT(removedQcopChannel(const QString&)));
54#endif
55
56 QCopChannel* channel = new QCopChannel( "QPE/System", this );
57 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)),
58 this, SLOT(received(const QCString&, const QByteArray&)) );
59
60 spacing = AppLnk::smallIconSize() + 3;
61} 48}
@@ -63,69 +50,42 @@ RunningAppBar::RunningAppBar(QWidget* parent)
63RunningAppBar::~RunningAppBar() 50RunningAppBar::~RunningAppBar()
64{}
65
66void RunningAppBar::newQcopChannel(const QString& channelName)
67{
68 QString prefix("QPE/Application/");
69 if (channelName.startsWith(prefix)) {
70 QString appName = channelName.mid(prefix.length());
71 // qDebug("App %s just connected!", appName.latin1());
72 const AppLnk* newGuy = m_AppLnkSet->findExec(appName);
73 if (newGuy && !newGuy->isPreloaded()) {
74 addTask(*newGuy);
75 }
76 }
77}
78
79void RunningAppBar::removedQcopChannel(const QString& channelName)
80{ 51{
81 QString prefix("QPE/Application/");
82 if (channelName.startsWith(prefix)) {
83 QString appName = channelName.mid(prefix.length());
84 qDebug("App %s just disconnected!", appName.latin1());
85 const AppLnk* newGuy = m_AppLnkSet->findExec(appName);
86 if (newGuy) {
87 removeTask(*newGuy);
88 }
89 }
90} 52}
91 53
92void RunningAppBar::received(const QCString& msg, const QByteArray& data) 54void RunningAppBar::received(const QCString& msg, const QByteArray& data) {
93{ 55 // Since fast apps appear and disappear without disconnecting from their
94 // Since fast apps appear and disappear without disconnecting from their 56 // channel we need to watch for the showing/hiding events and update according.
95 // channel we need to watch for the showing/hiding events and update according. 57 QDataStream stream( data, IO_ReadOnly );
96 QDataStream stream( data, IO_ReadOnly ); 58 if ( msg == "fastAppShowing(QString)") {
97 if ( msg == "fastAppShowing(QString)") { 59 QString appName;
98 QString appName; 60 stream >> appName;
99 stream >> appName; 61 // qDebug("fastAppShowing %s", appName.data() );
100 addTask(*m_AppLnkSet->findExec(appName)); 62 const AppLnk* f = ServerInterface::appLnks().findExec(appName);
101 } 63 if ( f ) addTask(*f);
102 else if ( msg == "fastAppHiding(QString)") { 64 } else if ( msg == "fastAppHiding(QString)") {
103 QString appName; 65 QString appName;
104 stream >> appName; 66 stream >> appName;
105 removeTask(*m_AppLnkSet->findExec(appName)); 67 const AppLnk* f = ServerInterface::appLnks().findExec(appName);
106 } 68 if ( f ) removeTask(*f);
69 }
107} 70}
108 71
109void RunningAppBar::addTask(const AppLnk& appLnk) 72void RunningAppBar::addTask(const AppLnk& appLnk) {
110{ 73 qDebug("Added %s to app list.", appLnk.name().latin1());
111 // qDebug("Added %s to app list.", appLnk.name().latin1()); 74 AppLnk* newApp = new AppLnk(appLnk);
112 AppLnk* newApp = new AppLnk(appLnk); 75 newApp->setExec(appLnk.exec());
113 newApp->setExec(appLnk.exec()); 76 appList.prepend(newApp);
114 m_AppList.prepend(newApp); 77 update();
115 update();
116} 78}
117 79
118void RunningAppBar::removeTask(const AppLnk& appLnk) 80void RunningAppBar::removeTask(const AppLnk& appLnk) {
119{ 81 unsigned int i = 0;
120 unsigned int i = 0; 82 for (; i < appList.count() ; i++) {
121 for (; i < m_AppList.count() ; i++) { 83 AppLnk* target = appList.at(i);
122 AppLnk* target = m_AppList.at(i); 84 if (target->exec() == appLnk.exec()) {
123 if (target->exec() == appLnk.exec()) { 85 qDebug("Removing %s from app list.", appLnk.name().latin1());
124 qDebug("Removing %s from app list.", appLnk.name().latin1()); 86 appList.remove();
125 m_AppList.remove(); 87 delete target;
126 88 }
127 delete target; 89 }
128 } 90 update();
129 }
130 update();
131} 91}
@@ -134,23 +94,22 @@ void RunningAppBar::mousePressEvent(QMouseEvent *e)
134{ 94{
135 // Find out if the user is clicking on an app icon... 95 // Find out if the user is clicking on an app icon...
136 // If so, snag the index so when we repaint we show it 96 // If so, snag the index so when we repaint we show it
137 // as highlighed. 97 // as highlighed.
138 m_SelectedAppIndex = 0; 98 selectedAppIndex = 0;
139 int x = 0; 99 int x=0;
140 QListIterator<AppLnk> it( m_AppList ); 100 QListIterator<AppLnk> it( appList );
141 for ( ; it.current(); ++it, ++m_SelectedAppIndex, x += spacing ) { 101 for ( ; it.current(); ++it,++selectedAppIndex,x+=spacing ) {
142 if ( x + spacing <= width() ) { 102 if ( x + spacing <= width() ) {
143 if ( e->x() >= x && e->x() < x + spacing ) { 103 if ( e->x() >= x && e->x() < x+spacing ) {
144 if ( m_SelectedAppIndex < (int)m_AppList.count() ) { 104 if ( selectedAppIndex < (int)appList.count() ) {
145 repaint(FALSE); 105 repaint(FALSE);
146 return ; 106 return;
147 }
148 }
149 }
150 else {
151 break;
152 }
153 } 107 }
154 m_SelectedAppIndex = -1; 108 }
155 repaint( FALSE ); 109 } else {
110 break;
111 }
112 }
113 selectedAppIndex = -1;
114 repaint( FALSE );
156} 115}
@@ -159,20 +118,11 @@ void RunningAppBar::mouseReleaseEvent(QMouseEvent *e)
159{ 118{
160 if (e->button() == QMouseEvent::RightButton) { 119 if (e->button() == QMouseEvent::RightButton)
161 return ; 120 return;
162 } 121 if ( selectedAppIndex >= 0 ) {
163 if ( m_SelectedAppIndex >= 0 ) { 122 QString app = appList.at(selectedAppIndex)->exec();
164 QString channel = QString("QPE/Application/") + m_AppList.at(m_SelectedAppIndex)->exec(); 123 QCopEnvelope e("QPE/System", "raise(QString)");
165 if (QCopChannel::isRegistered(channel.latin1())) { 124 e << app;
166 // qDebug("%s is running!", m_AppList.at(m_SelectedAppIndex)->exec().latin1()); 125 selectedAppIndex = -1;
167 QCopEnvelope e(channel.latin1(), "raise()"); 126 update();
168 // This class will delete itself after hearing from the app or the timer expiring 127 }
169 (void)new AppMonitor(*m_AppList.at(m_SelectedAppIndex), *this);
170 }
171 else {
172 removeTask(*m_AppList.at(m_SelectedAppIndex));
173 }
174
175 m_SelectedAppIndex = -1;
176 update();
177 }
178} 128}
@@ -181,23 +131,24 @@ void RunningAppBar::paintEvent( QPaintEvent * )
181{ 131{
182 QPainter p( this ); 132 QPainter p( this );
183 AppLnk *curApp; 133 AppLnk *curApp;
184 int x = 0; 134 int x = 0;
185 int y = (height() - AppLnk::smallIconSize()) / 2; 135 int y = (height() - AppLnk::smallIconSize()) / 2;
186 int i = 0; 136 int i = 0;
187 137
188 //p.fillRect( 0, 0, width(), height(), colorGroup().background() ); 138 p.fillRect( 0, 0, width(), height(), colorGroup().background() );
189 139
190 QListIterator<AppLnk> it(m_AppList); 140 QListIterator<AppLnk> it(appList);
191 141
192 for (; it.current(); i++, ++it ) { 142 for (; it.current(); i++, ++it ) {
193 if ( x + spacing <= width() ) { 143 if ( x + spacing <= width() ) {
194 curApp = it.current(); 144 curApp = it.current();
195 if ( (int)i == m_SelectedAppIndex ) 145 qWarning("Drawing %s", curApp->name().latin1() );
196 p.fillRect( x, y, spacing, curApp->pixmap().height() + 1, colorGroup().highlight() ); 146 if ( (int)i == selectedAppIndex )
197 else 147 p.fillRect( x, y, spacing, curApp->pixmap().height()+1, colorGroup().highlight() );
198 // p.eraseRect( x, y, spacing, curApp->pixmap().height()+1 ); 148 else
199 p.drawPixmap( x, y, curApp->pixmap() ); 149 p.eraseRect( x, y, spacing, curApp->pixmap().height()+1 );
200 x += spacing; 150 p.drawPixmap( x, y, curApp->pixmap() );
201 } 151 x += spacing;
202 } 152 }
153 }
203} 154}
@@ -206,108 +157,23 @@ QSize RunningAppBar::sizeHint() const
206{ 157{
207 return QSize( frameWidth(), AppLnk::smallIconSize() + frameWidth()*2 + 3 ); 158 return QSize( frameWidth(), AppLnk::smallIconSize()+frameWidth()*2+3 );
208} 159}
209 160
210const int AppMonitor::RAISE_TIMEOUT_MS = 500; 161void RunningAppBar::applicationLaunched(const QString &appName)
211
212AppMonitor::AppMonitor(const AppLnk& app, RunningAppBar& owner)
213 : QObject(0L), m_Owner(owner), m_App(app), m_AppKillerBox(0L)
214{ 162{
215 QCopChannel* channel = new QCopChannel( "QPE/System", this ); 163 qDebug("desktop:: app: %s launched with pid ", appName.data() );
216 connect( channel, SIGNAL(received(const QCString&, const QByteArray&)), 164 const AppLnk* newGuy = ServerInterface::appLnks().findExec(appName);
217 this, SLOT(received(const QCString&, const QByteArray&)) ); 165 if ( newGuy && !newGuy->isPreloaded() ) {
218 connect(&m_Timer, SIGNAL(timeout()), this, SLOT(timerExpired())); 166 addTask( *newGuy );
219 m_Timer.start(RAISE_TIMEOUT_MS, TRUE); 167 }
220} 168}
221 169
222AppMonitor::~AppMonitor() 170void RunningAppBar::applicationTerminated(const QString &app)
223{ 171{
224 if (m_AppKillerBox) { 172 const AppLnk* gone = ServerInterface::appLnks().findExec(app);
225 delete m_AppKillerBox; 173 if ( gone ) {
226 m_AppKillerBox = 0L; 174 removeTask(*gone);
227 } 175 }
228}
229
230void AppMonitor::received(const QCString& msg, const QByteArray& data)
231{
232 QDataStream stream( data, IO_ReadOnly );
233
234 if (msg == "appRaised(QString)") {
235 QString appName;
236 stream >> appName;
237 if (appName == m_App.exec()) {
238 // qDebug("Got a heartbeat from %s", appName.latin1());
239 m_Timer.stop();
240 // Check to make sure we're not waiting on user input...
241 if (m_AppKillerBox) {
242 // If we are, we kill the dialog box, and the code waiting on the result
243 // will clean us up (basically the user said "no").
244 delete m_AppKillerBox;
245 m_AppKillerBox = 0L;
246 }
247 else {
248 // Ok, we're not waiting on user input, so clean us up now.
249 // WE DELETE OURSELVES HERE! Don't do anything else!!
250 delete this;
251 }
252 }
253 }
254} 176}
255 177
256void AppMonitor::timerExpired()
257{
258 // We store this incase the application responds while we're
259 // waiting for user input so we know not to delete ourselves. This
260 // will be cleaned up in the destructor.
261 m_AppKillerBox = new QMessageBox(tr("Application Problem"),
262 tr("<p>%1 is not responding.</p>").arg(m_App.name()) +
263 tr("<p>Would you like to force the application to exit?</p>"),
264 QMessageBox::Warning, QMessageBox::Yes,
265 QMessageBox::No | QMessageBox::Default,
266 QMessageBox::NoButton);
267 if ( m_AppKillerBox-> exec ( ) == QMessageBox::Yes ) {
268 QDir proc ( "/proc/", "[0-9]*", QDir::Name | QDir::Reversed, QDir::Dirs );
269 QStringList allprocs = proc. entryList ( );
270
271 pid_t mypid = ::getpid ( );
272
273 for ( QStringList::Iterator it = allprocs. begin ( ); it != allprocs. end ( ); ++it ) {
274 if (( *it ). toInt ( ) <= mypid ) // only interested in children
275 continue;
276
277 QCString s = QString ( "/proc/" + *it + "/stat" ). local8Bit ( );
278
279 FILE *fp = ::fopen ( s. data ( ), "r" );
280 if ( fp ) {
281 pid_t pid, ppid;
282 char *execptr, *exec = 0;
283
284 if ( ::fscanf ( fp, "%d %as %*c %d ", &pid, &execptr, &ppid ) == 3 ) {
285 exec = execptr [0] ? execptr + 1 : execptr;
286 if ( exec [0] )
287 exec [::strlen ( exec ) - 1] = 0;
288
289 if (( ppid == ::getpid ( )) && ( m_App. exec ( ). local8Bit ( ) == exec )) {
290 bool success = false;
291 178
292 qDebug ( "trying to kill pid=%d, exec=%s, ppid=%d", pid, exec, ppid );
293
294
295 success |= ( ::kill ( pid, SIGTERM ) == 0 );
296 ::usleep ( 1000 * 500 );
297 success |= ( ::kill ( pid, SIGKILL ) == 0 );
298
299 if ( success )
300 m_Owner. removeTask ( m_App );
301
302 ::free ( execptr );
303 break;
304 }
305 ::free ( execptr );
306 }
307 ::fclose ( fp );
308 }
309 }
310 }
311 delete this;
312}
313 179