taskmanager.cpp
00001 /***************************************************************** 00002 00003 Copyright (c) 2000 Matthias Elter <elter@kde.org> 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 00019 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 00020 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00021 00022 ******************************************************************/ 00023 00024 #include <tdeglobal.h> 00025 #include <tdelocale.h> 00026 #include <kdebug.h> 00027 #include <tdeconfig.h> 00028 #include <kiconloader.h> 00029 #include <twinmodule.h> 00030 #include <netwm.h> 00031 #include <tqtimer.h> 00032 #include <tqimage.h> 00033 00034 #include <X11/X.h> 00035 #include <X11/Xlib.h> 00036 #include <X11/Xutil.h> 00037 00038 #include "taskmanager.h" 00039 #include "taskmanager.moc" 00040 00041 template class TQPtrList<Task>; 00042 00043 // Hack: create a global KWinModule without a parent. We 00044 // can't make it a child of TaskManager because more than one 00045 // TaskManager might be created. We can't make it a class 00046 // variable without changing Task, which also uses it. 00047 // So, we'll leak a little memory, but it's better than crashing. 00048 // The real problem is that KWinModule should be a singleton. 00049 KWinModule* twin_module = 0; 00050 00051 TaskManager::TaskManager(TQObject *parent, const char *name) 00052 : TQObject(parent, name), _active(0), _startup_info( NULL ) 00053 { 00054 00055 twin_module = new KWinModule(); 00056 00057 // TDEGlobal::locale()->insertCatalogue("libtaskmanager"); 00058 connect(twin_module, TQT_SIGNAL(windowAdded(WId)), TQT_SLOT(windowAdded(WId))); 00059 connect(twin_module, TQT_SIGNAL(windowRemoved(WId)), TQT_SLOT(windowRemoved(WId))); 00060 connect(twin_module, TQT_SIGNAL(activeWindowChanged(WId)), TQT_SLOT(activeWindowChanged(WId))); 00061 connect(twin_module, TQT_SIGNAL(currentDesktopChanged(int)), TQT_SLOT(currentDesktopChanged(int))); 00062 connect(twin_module, TQT_SIGNAL(windowChanged(WId,unsigned int)), TQT_SLOT(windowChanged(WId,unsigned int))); 00063 00064 // register existing windows 00065 const TQValueList<WId> windows = twin_module->windows(); 00066 TQValueList<WId>::ConstIterator end( windows.end() ); 00067 for (TQValueList<WId>::ConstIterator it = windows.begin(); it != end; ++it ) 00068 windowAdded(*it); 00069 00070 // set active window 00071 WId win = twin_module->activeWindow(); 00072 activeWindowChanged(win); 00073 00074 configure_startup(); 00075 } 00076 00077 TaskManager::~TaskManager() 00078 { 00079 } 00080 00081 void TaskManager::configure_startup() 00082 { 00083 TDEConfig c("tdelaunchrc", true); 00084 c.setGroup("FeedbackStyle"); 00085 if (!c.readBoolEntry("TaskbarButton", true)) 00086 return; 00087 _startup_info = new TDEStartupInfo( true, this ); 00088 connect( _startup_info, 00089 TQT_SIGNAL( gotNewStartup( const TDEStartupInfoId&, const TDEStartupInfoData& )), 00090 TQT_SLOT( gotNewStartup( const TDEStartupInfoId&, const TDEStartupInfoData& ))); 00091 connect( _startup_info, 00092 TQT_SIGNAL( gotStartupChange( const TDEStartupInfoId&, const TDEStartupInfoData& )), 00093 TQT_SLOT( gotStartupChange( const TDEStartupInfoId&, const TDEStartupInfoData& ))); 00094 connect( _startup_info, 00095 TQT_SIGNAL( gotRemoveStartup( const TDEStartupInfoId&, const TDEStartupInfoData& )), 00096 TQT_SLOT( gotRemoveStartup( const TDEStartupInfoId& ))); 00097 c.setGroup( "TaskbarButtonSettings" ); 00098 _startup_info->setTimeout( c.readUnsignedNumEntry( "Timeout", 30 )); 00099 } 00100 00101 Task* TaskManager::findTask(WId w) 00102 { 00103 for (Task* t = _tasks.first(); t != 0; t = _tasks.next()) 00104 if (t->window() == w || t->hasTransient(w)) 00105 return t; 00106 return 0; 00107 } 00108 00109 #ifdef KDE_3_3 00110 #define NET_ALL_TYPES_MASK (NET::AllTypesMask) 00111 #else 00112 #define NET_ALL_TYPES_MASK (-1LU) 00113 #endif 00114 00115 void TaskManager::windowAdded(WId w ) 00116 { 00117 NETWinInfo info(tqt_xdisplay(), w, tqt_xrootwin(), 00118 NET::WMWindowType | NET::WMPid | NET::WMState ); 00119 #ifdef KDE_3_2 00120 NET::WindowType windowType = info.windowType(NET_ALL_TYPES_MASK); 00121 #else 00122 NET::WindowType windowType = info.windowType(); 00123 #endif 00124 // ignore NET::Tool and other special window types 00125 if (windowType != NET::Normal && windowType != NET::Override 00126 && windowType != NET::Unknown && windowType != NET::Dialog) 00127 return; 00128 // ignore windows that want to be ignored by the taskbar 00129 if ((info.state() & NET::SkipTaskbar) != 0) 00130 { 00131 _skiptaskbar_windows.push_front( w ); // remember them though 00132 return; 00133 } 00134 00135 Window transient_for_tmp; 00136 if (XGetTransientForHint(tqt_xdisplay(), (Window) w, &transient_for_tmp)) 00137 { 00138 WId transient_for = (WId) transient_for_tmp; 00139 00140 // check if it's transient for a skiptaskbar window 00141 if (_skiptaskbar_windows.contains(transient_for)) 00142 return; 00143 00144 // lets see if this is a transient for an existing task 00145 if (transient_for != tqt_xrootwin() && transient_for != 0 ) 00146 { 00147 Task* t = findTask(transient_for); 00148 if (t) 00149 { 00150 if (t->window() != w) 00151 { 00152 t->addTransient(w); 00153 // kdDebug() << "TM: Transient " << w << " added for Task: " << t->window() << endl; 00154 } 00155 return; 00156 } 00157 } 00158 } 00159 Task* t = new Task(w, this); 00160 _tasks.append(t); 00161 00162 // kdDebug() << "TM: Task added for WId: " << w << endl; 00163 emit taskAdded(t); 00164 } 00165 00166 void TaskManager::windowRemoved(WId w ) 00167 { 00168 _skiptaskbar_windows.remove( w ); 00169 // find task 00170 Task* t = findTask(w); 00171 if (!t) return; 00172 00173 if (t->window() == w) { 00174 _tasks.removeRef(t); 00175 00176 emit taskRemoved(t); 00177 00178 if(t == _active) _active = 0; 00179 delete t; 00180 //kdDebug() << "TM: Task for WId " << w << " removed." << endl; 00181 } 00182 else { 00183 t->removeTransient( w ); 00184 //kdDebug() << "TM: Transient " << w << " for Task " << t->window() << " removed." << endl; 00185 } 00186 } 00187 00188 void TaskManager::windowChanged(WId w, unsigned int dirty) 00189 { 00190 if( dirty & NET::WMState ) { 00191 NETWinInfo info ( tqt_xdisplay(), w, tqt_xrootwin(), NET::WMState ); 00192 if ( (info.state() & NET::SkipTaskbar) != 0 ) { 00193 windowRemoved( w ); 00194 _skiptaskbar_windows.push_front( w ); 00195 return; 00196 } 00197 else { 00198 _skiptaskbar_windows.remove( w ); 00199 if( !findTask( w )) 00200 windowAdded( w ); // skipTaskBar state was removed, so add this window 00201 } 00202 } 00203 00204 // check if any state we are interested in is marked dirty 00205 if(!(dirty & (NET::WMVisibleName|NET::WMName|NET::WMState|NET::WMIcon|NET::XAWMState|NET::WMDesktop)) ) 00206 return; 00207 00208 // find task 00209 Task* t = findTask( w ); 00210 if (!t) return; 00211 00212 //kdDebug() << "TaskManager::windowChanged " << w << " " << dirty << endl; 00213 00214 00215 // refresh icon pixmap if necessary 00216 if (dirty & NET::WMIcon) 00217 t->refresh(true); 00218 else 00219 t->refresh(); 00220 00221 if(dirty & (NET::WMDesktop|NET::WMState|NET::XAWMState)) 00222 emit windowChanged(w); // moved to different desktop or is on all or change in iconification/withdrawnnes 00223 } 00224 00225 void TaskManager::activeWindowChanged(WId w ) 00226 { 00227 //kdDebug() << "TaskManager::activeWindowChanged" << endl; 00228 00229 Task* t = findTask( w ); 00230 if (!t) { 00231 if (_active) { 00232 _active->setActive(false); 00233 _active = 0; 00234 00235 // there is no active window at the moment 00236 emit activeTaskChanged(0); 00237 } 00238 } 00239 else { 00240 if (_active) 00241 _active->setActive(false); 00242 00243 _active = t; 00244 _active->setActive(true); 00245 00246 emit activeTaskChanged(_active); 00247 } 00248 } 00249 00250 void TaskManager::currentDesktopChanged(int desktop) 00251 { 00252 emit desktopChanged(desktop); 00253 } 00254 00255 void TaskManager::gotNewStartup( const TDEStartupInfoId& id, const TDEStartupInfoData& data ) 00256 { 00257 Startup* s = new Startup( id, data, this ); 00258 _startups.append(s); 00259 00260 emit startupAdded(s); 00261 } 00262 00263 void TaskManager::gotStartupChange( const TDEStartupInfoId& id, const TDEStartupInfoData& data ) 00264 { 00265 for( Startup* s = _startups.first(); s != 0; s = _startups.next()) { 00266 if ( s->id() == id ) { 00267 s->update( data ); 00268 return; 00269 } 00270 } 00271 } 00272 00273 void TaskManager::gotRemoveStartup( const TDEStartupInfoId& id ) 00274 { 00275 killStartup( id ); 00276 } 00277 00278 void TaskManager::killStartup( const TDEStartupInfoId& id ) 00279 { 00280 Startup* s = 0; 00281 for(s = _startups.first(); s != 0; s = _startups.next()) { 00282 if (s->id() == id) 00283 break; 00284 } 00285 if (s == 0) return; 00286 00287 _startups.removeRef(s); 00288 emit startupRemoved(s); 00289 delete s; 00290 } 00291 00292 void TaskManager::killStartup(Startup* s) 00293 { 00294 if (s == 0) return; 00295 00296 _startups.removeRef(s); 00297 emit startupRemoved(s); 00298 delete s; 00299 } 00300 00301 TQString TaskManager::desktopName(int desk) const 00302 { 00303 return twin_module->desktopName(desk); 00304 } 00305 00306 int TaskManager::numberOfDesktops() const 00307 { 00308 return twin_module->numberOfDesktops(); 00309 } 00310 00311 bool TaskManager::isOnTop(const Task* task) 00312 { 00313 if(!task) return false; 00314 00315 for (TQValueList<WId>::ConstIterator it = twin_module->stackingOrder().fromLast(); 00316 it != twin_module->stackingOrder().end(); --it ) { 00317 for (Task* t = _tasks.first(); t != 0; t = _tasks.next() ) { 00318 if ( (*it) == t->window() ) { 00319 if ( t == task ) 00320 return true; 00321 if ( !t->isIconified() && (t->isAlwaysOnTop() == task->isAlwaysOnTop()) ) 00322 return false; 00323 break; 00324 } 00325 } 00326 } 00327 return false; 00328 } 00329 00330 00331 Task::Task(WId win, TaskManager * parent, const char *name) : 00332 TQObject(parent, name), 00333 _active(false), _win(win), 00334 _lastWidth(0), _lastHeight(0), _lastResize(false), _lastIcon(), 00335 _thumbSize(0.2), _thumb(), _grab() 00336 { 00337 #ifdef KDE_3_2 00338 _info = KWin::windowInfo(_win, 0, 0); 00339 #else 00340 _info = KWin::info(_win); 00341 #endif 00342 // try to load icon via net_wm 00343 _pixmap = KWin::icon(_win, 16, 16, true); 00344 00345 // try to guess the icon from the classhint 00346 if(_pixmap.isNull()) 00347 TDEGlobal::instance()->iconLoader()->loadIcon(className().lower(), 00348 TDEIcon::Small,TDEIcon::Small, 00349 TDEIcon::DefaultState, 0, true); 00350 00351 // load xapp icon 00352 if (_pixmap.isNull()) 00353 _pixmap = SmallIcon("kcmx"); 00354 } 00355 00356 Task::~Task() 00357 { 00358 } 00359 00360 void Task::refresh(bool icon) 00361 { 00362 #ifdef KDE_3_2 00363 _info = KWin::windowInfo(_win, 0, 0); 00364 #else 00365 _info = KWin::info(_win); 00366 #endif 00367 if (icon) 00368 { 00369 // try to load icon via net_wm 00370 _pixmap = KWin::icon(_win, 16, 16, true); 00371 00372 // try to guess the icon from the classhint 00373 if(_pixmap.isNull()) 00374 { 00375 TDEGlobal::instance()->iconLoader()->loadIcon(className().lower(), 00376 TDEIcon::Small, TDEIcon::Small, TDEIcon::DefaultState, 0, true); 00377 } 00378 00379 // load xapp icon 00380 if (_pixmap.isNull()) 00381 _pixmap = SmallIcon("kcmx"); 00382 00383 _lastIcon.resize(0,0); 00384 emit iconChanged(); 00385 } 00386 emit changed(); 00387 } 00388 00389 void Task::setActive(bool a) 00390 { 00391 _active = a; 00392 emit changed(); 00393 if ( a ) 00394 emit activated(); 00395 else 00396 emit deactivated(); 00397 } 00398 00399 bool Task::isMaximized() const 00400 { 00401 #ifdef KDE_3_2 00402 return(_info.state() & NET::Max); 00403 #else 00404 return(_info.state & NET::Max); 00405 #endif 00406 } 00407 00408 bool Task::isIconified() const 00409 { 00410 #ifdef KDE_3_2 00411 return (_info.mappingState() == NET::Iconic); 00412 #else 00413 return (_info.mappingState == NET::Iconic); 00414 #endif 00415 } 00416 00417 bool Task::isAlwaysOnTop() const 00418 { 00419 #ifdef KDE_3_2 00420 return (_info.state() & NET::StaysOnTop); 00421 #else 00422 return (_info.state & NET::StaysOnTop); 00423 #endif 00424 } 00425 00426 bool Task::isShaded() const 00427 { 00428 #ifdef KDE_3_2 00429 return (_info.state() & NET::Shaded); 00430 #else 00431 return (_info.state & NET::Shaded); 00432 #endif 00433 } 00434 00435 bool Task::isOnCurrentDesktop() const 00436 { 00437 #ifdef KDE_3_2 00438 return (_info.onAllDesktops() || _info.desktop() == twin_module->currentDesktop()); 00439 #else 00440 return (_info.onAllDesktops || _info.desktop == twin_module->currentDesktop()); 00441 #endif 00442 } 00443 00444 bool Task::isOnAllDesktops() const 00445 { 00446 #ifdef KDE_3_2 00447 return _info.onAllDesktops(); 00448 #else 00449 return _info.onAllDesktops; 00450 #endif 00451 } 00452 00453 bool Task::isActive() const 00454 { 00455 return _active; 00456 } 00457 00458 bool Task::isOnTop() const 00459 { 00460 return taskManager()->isOnTop( this ); 00461 } 00462 00463 bool Task::isModified() const 00464 { 00465 static TQString modStr = TQString::fromUtf8("[") + i18n("modified") + TQString::fromUtf8("]"); 00466 #ifdef KDE_3_2 00467 int modStrPos = _info.visibleName().find(modStr); 00468 #else 00469 int modStrPos = _info.visibleName.find(modStr); 00470 #endif 00471 00472 return ( modStrPos != -1 ); 00473 } 00474 00475 TQString Task::iconName() const 00476 { 00477 NETWinInfo ni( tqt_xdisplay(), _win, tqt_xrootwin(), NET::WMIconName); 00478 return TQString::fromUtf8(ni.iconName()); 00479 } 00480 TQString Task::visibleIconName() const 00481 { 00482 NETWinInfo ni( tqt_xdisplay(), _win, tqt_xrootwin(), NET::WMVisibleIconName); 00483 return TQString::fromUtf8(ni.visibleIconName()); 00484 } 00485 00486 TQString Task::className() 00487 { 00488 XClassHint hint; 00489 if(XGetClassHint(tqt_xdisplay(), _win, &hint)) { 00490 TQString nh( hint.res_name ); 00491 XFree( hint.res_name ); 00492 XFree( hint.res_class ); 00493 return nh; 00494 } 00495 return TQString(); 00496 } 00497 00498 TQString Task::classClass() 00499 { 00500 XClassHint hint; 00501 if(XGetClassHint(tqt_xdisplay(), _win, &hint)) { 00502 TQString ch( hint.res_class ); 00503 XFree( hint.res_name ); 00504 XFree( hint.res_class ); 00505 return ch; 00506 } 00507 return TQString(); 00508 } 00509 00510 TQPixmap Task::icon( int width, int height, bool allowResize ) 00511 { 00512 if ( (width == _lastWidth) 00513 && (height == _lastHeight) 00514 && (allowResize == _lastResize ) 00515 && (!_lastIcon.isNull()) ) 00516 return _lastIcon; 00517 00518 TQPixmap newIcon = KWin::icon( _win, width, height, allowResize ); 00519 if ( !newIcon.isNull() ) { 00520 _lastIcon = newIcon; 00521 _lastWidth = width; 00522 _lastHeight = height; 00523 _lastResize = allowResize; 00524 } 00525 00526 return newIcon; 00527 } 00528 00529 TQPixmap Task::bestIcon( int size, bool &isStaticIcon ) 00530 { 00531 TQPixmap pixmap; 00532 isStaticIcon = false; 00533 00534 switch( size ) { 00535 case TDEIcon::SizeSmall: 00536 { 00537 pixmap = icon( 16, 16, true ); 00538 00539 // Icon of last resort 00540 if( pixmap.isNull() ) { 00541 pixmap = TDEGlobal::iconLoader()->loadIcon( "go", 00542 TDEIcon::NoGroup, 00543 TDEIcon::SizeSmall ); 00544 isStaticIcon = true; 00545 } 00546 } 00547 break; 00548 case TDEIcon::SizeMedium: 00549 { 00550 // 00551 // Try 34x34 first for KDE 2.1 icons with shadows, if we don't 00552 // get one then try 32x32. 00553 // 00554 pixmap = icon( 34, 34, false ); 00555 00556 if ( ( pixmap.width() != 34 ) || ( pixmap.height() != 34 ) ) { 00557 if ( ( pixmap.width() != 32 ) || ( pixmap.height() != 32 ) ) { 00558 pixmap = icon( 32, 32, true ); 00559 } 00560 } 00561 00562 // Icon of last resort 00563 if( pixmap.isNull() ) { 00564 pixmap = TDEGlobal::iconLoader()->loadIcon( "go", 00565 TDEIcon::NoGroup, 00566 TDEIcon::SizeMedium ); 00567 isStaticIcon = true; 00568 } 00569 } 00570 break; 00571 case TDEIcon::SizeLarge: 00572 { 00573 // If there's a 48x48 icon in the hints then use it 00574 pixmap = icon( size, size, false ); 00575 00576 // If not, try to get one from the classname 00577 if ( pixmap.isNull() || pixmap.width() != size || pixmap.height() != size ) { 00578 pixmap = TDEGlobal::iconLoader()->loadIcon( className(), 00579 TDEIcon::NoGroup, 00580 size, 00581 TDEIcon::DefaultState, 00582 0L, 00583 true ); 00584 isStaticIcon = true; 00585 } 00586 00587 // If we still don't have an icon then scale the one in the hints 00588 if ( pixmap.isNull() || ( pixmap.width() != size ) || ( pixmap.height() != size ) ) { 00589 pixmap = icon( size, size, true ); 00590 isStaticIcon = false; 00591 } 00592 00593 // Icon of last resort 00594 if( pixmap.isNull() ) { 00595 pixmap = TDEGlobal::iconLoader()->loadIcon( "go", 00596 TDEIcon::NoGroup, 00597 size ); 00598 isStaticIcon = true; 00599 } 00600 } 00601 } 00602 00603 return pixmap; 00604 } 00605 00606 bool Task::idMatch( const TQString& id1, const TQString& id2 ) 00607 { 00608 if ( id1.isEmpty() || id2.isEmpty() ) 00609 return false; 00610 00611 if ( id1.contains( id2 ) > 0 ) 00612 return true; 00613 00614 if ( id2.contains( id1 ) > 0 ) 00615 return true; 00616 00617 return false; 00618 } 00619 00620 00621 void Task::maximize() 00622 { 00623 NETWinInfo ni( tqt_xdisplay(), _win, tqt_xrootwin(), NET::WMState); 00624 ni.setState( NET::Max, NET::Max ); 00625 00626 #ifdef KDE_3_2 00627 if (_info.mappingState() == NET::Iconic) 00628 #else 00629 if (_info.mappingState == NET::Iconic) 00630 #endif 00631 activate(); 00632 } 00633 00634 void Task::restore() 00635 { 00636 NETWinInfo ni( tqt_xdisplay(), _win, tqt_xrootwin(), NET::WMState); 00637 ni.setState( 0, NET::Max ); 00638 #ifdef KDE_3_2 00639 if (_info.mappingState() == NET::Iconic) 00640 #else 00641 if (_info.mappingState == NET::Iconic) 00642 #endif 00643 activate(); 00644 } 00645 00646 void Task::iconify() 00647 { 00648 XIconifyWindow( tqt_xdisplay(), _win, tqt_xscreen() ); 00649 } 00650 00651 void Task::close() 00652 { 00653 NETRootInfo ri( tqt_xdisplay(), NET::CloseWindow ); 00654 ri.closeWindowRequest( _win ); 00655 } 00656 00657 void Task::raise() 00658 { 00659 // kdDebug(1210) << "Task::raise(): " << name() << endl; 00660 XRaiseWindow( tqt_xdisplay(), _win ); 00661 } 00662 00663 void Task::lower() 00664 { 00665 // kdDebug(1210) << "Task::lower(): " << name() << endl; 00666 XLowerWindow( tqt_xdisplay(), _win ); 00667 } 00668 00669 void Task::activate() 00670 { 00671 // kdDebug(1210) << "Task::activate():" << name() << endl; 00672 NETRootInfo ri( tqt_xdisplay(), 0 ); 00673 ri.setActiveWindow( _win ); 00674 } 00675 00676 void Task::activateRaiseOrIconify() 00677 { 00678 if ( !isActive() || isIconified() ) { 00679 activate(); 00680 } else if ( !isOnTop() ) { 00681 raise(); 00682 } else { 00683 iconify(); 00684 } 00685 } 00686 00687 void Task::toDesktop(int desk) 00688 { 00689 NETWinInfo ni(tqt_xdisplay(), _win, tqt_xrootwin(), NET::WMDesktop); 00690 if (desk == 0) 00691 { 00692 #ifdef KDE_3_2 00693 if (_info.onAllDesktops()) 00694 { 00695 ni.setDesktop(twin_module->currentDesktop()); 00696 KWin::forceActiveWindow(_win); 00697 } 00698 #else 00699 if (_info.onAllDesktops) 00700 { 00701 ni.setDesktop(twin_module->currentDesktop()); 00702 KWin::setActiveWindow(_win); 00703 } 00704 #endif 00705 else 00706 ni.setDesktop(NETWinInfo::OnAllDesktops); 00707 return; 00708 } 00709 ni.setDesktop(desk); 00710 if (desk == twin_module->currentDesktop()) 00711 #ifdef KDE_3_2 00712 KWin::forceActiveWindow(_win); 00713 #else 00714 KWin::setActiveWindow(_win); 00715 #endif 00716 } 00717 00718 void Task::toCurrentDesktop() 00719 { 00720 toDesktop(twin_module->currentDesktop()); 00721 } 00722 00723 void Task::setAlwaysOnTop(bool stay) 00724 { 00725 NETWinInfo ni( tqt_xdisplay(), _win, tqt_xrootwin(), NET::WMState); 00726 if(stay) 00727 ni.setState( NET::StaysOnTop, NET::StaysOnTop ); 00728 else 00729 ni.setState( 0, NET::StaysOnTop ); 00730 } 00731 00732 void Task::toggleAlwaysOnTop() 00733 { 00734 setAlwaysOnTop( !isAlwaysOnTop() ); 00735 } 00736 00737 void Task::setShaded(bool shade) 00738 { 00739 NETWinInfo ni( tqt_xdisplay(), _win, tqt_xrootwin(), NET::WMState); 00740 if(shade) 00741 ni.setState( NET::Shaded, NET::Shaded ); 00742 else 00743 ni.setState( 0, NET::Shaded ); 00744 } 00745 00746 void Task::toggleShaded() 00747 { 00748 setShaded( !isShaded() ); 00749 } 00750 00751 void Task::publishIconGeometry(TQRect rect) 00752 { 00753 NETWinInfo ni( tqt_xdisplay(), _win, tqt_xrootwin(), NET::WMIconGeometry); 00754 NETRect r; 00755 r.pos.x = rect.x(); 00756 r.pos.y = rect.y(); 00757 r.size.width = rect.width(); 00758 r.size.height = rect.height(); 00759 ni.setIconGeometry(r); 00760 } 00761 00762 void Task::updateThumbnail() 00763 { 00764 if ( !isOnCurrentDesktop() ) 00765 return; 00766 if ( !isActive() ) 00767 return; 00768 if ( !_grab.isNull() ) // We're already processing one... 00769 return; 00770 00771 // 00772 // We do this as a two stage process to remove the delay caused 00773 // by the thumbnail generation. This makes things much smoother 00774 // on slower machines. 00775 // 00776 TQWidget *rootWin = TQT_TQWIDGET(tqApp->desktop()); 00777 TQRect geom = _info.geometry(); 00778 _grab = TQPixmap::grabWindow( rootWin->winId(), 00779 geom.x(), geom.y(), 00780 geom.width(), geom.height() ); 00781 00782 if ( !_grab.isNull() ) 00783 TQTimer::singleShot( 200, this, TQT_SLOT( generateThumbnail() ) ); 00784 } 00785 00786 void Task::generateThumbnail() 00787 { 00788 if ( _grab.isNull() ) 00789 return; 00790 00791 TQImage img = _grab.convertToImage(); 00792 00793 double width = img.width(); 00794 double height = img.height(); 00795 width = width * _thumbSize; 00796 height = height * _thumbSize; 00797 00798 img = img.smoothScale( (int) width, (int) height ); 00799 _thumb = img; 00800 _grab.resize( 0, 0 ); // Makes grab a null image. 00801 00802 emit thumbnailChanged(); 00803 } 00804 00805 Startup::Startup( const TDEStartupInfoId& id, const TDEStartupInfoData& data, 00806 TQObject * parent, const char *name) 00807 : TQObject(parent, name), _id( id ), _data( data ) 00808 { 00809 } 00810 00811 Startup::~Startup() 00812 { 00813 00814 } 00815 00816 void Startup::update( const TDEStartupInfoData& data ) 00817 { 00818 _data.update( data ); 00819 emit changed(); 00820 } 00821 00822 int TaskManager::currentDesktop() const 00823 { 00824 return twin_module->currentDesktop(); 00825 }