00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "task.h"
00027
00028
00029 #include <QMimeData>
00030 #include <QTime>
00031 #include <QTimer>
00032 #include <QApplication>
00033 #include <QDesktopWidget>
00034
00035 #ifdef Q_WS_X11
00036 #include <QX11Info>
00037 #endif
00038
00039
00040 #include <KDebug>
00041 #include <KIconLoader>
00042 #include <KLocale>
00043
00044 #include "taskmanager.h"
00045
00046 namespace TaskManager
00047 {
00048
00049 static const unsigned long windowInfoFlags = NET::WMState | NET::XAWMState | NET::WMDesktop |
00050 NET::WMVisibleName | NET::WMGeometry |
00051 NET::WMWindowType | NET::WM2AllowedActions;
00052 static const unsigned long windowInfoFlags2 = NET::WM2AllowedActions;
00053
00054 class Task::Private
00055 {
00056 public:
00057 Private(WId w)
00058 : active(false),
00059 win(w),
00060 frameId(w),
00061 info(KWindowSystem::windowInfo(w, windowInfoFlags, windowInfoFlags2)),
00062 lastWidth(0),
00063 lastHeight(0),
00064 lastResize(false),
00065 lastIcon(),
00066 cachedChanges(0),
00067 cachedChangesTimerId(0)
00068 {
00069 }
00070
00071 bool active;
00072 WId win;
00073 WId frameId;
00074 QPixmap pixmap;
00075 KWindowInfo info;
00076 WindowList transients;
00077 WindowList transientsDemandingAttention;
00078
00079 int lastWidth;
00080 int lastHeight;
00081 bool lastResize;
00082 QPixmap lastIcon;
00083 QIcon icon;
00084
00085 QRect iconGeometry;
00086
00087 QTime lastUpdate;
00088 unsigned int cachedChanges;
00089 int cachedChangesTimerId;
00090 };
00091
00092 Task::Task(WId w, QObject *parent, const char *name)
00093 : QObject(parent),
00094 d(new Private(w))
00095 {
00096 setObjectName(name);
00097
00098
00099 d->pixmap = KWindowSystem::icon(d->win, 16, 16, true);
00100
00101
00102 if (d->pixmap.isNull()) {
00103 KIconLoader::global()->loadIcon(className().toLower(),
00104 KIconLoader::Small,
00105 KIconLoader::Small,
00106 KIconLoader::DefaultState,
00107 QStringList(), 0, true);
00108 }
00109
00110
00111 if (d->pixmap.isNull()) {
00112 d->pixmap = SmallIcon("xorg");
00113 }
00114 }
00115
00116 Task::~Task()
00117 {
00118 delete d;
00119 }
00120
00121 void Task::timerEvent(QTimerEvent *)
00122 {
00123 if (d->cachedChanges) {
00124 d->lastUpdate = QTime();
00125 refresh(d->cachedChanges);
00126 d->cachedChanges = 0;
00127 }
00128
00129 killTimer(d->cachedChangesTimerId);
00130 d->cachedChangesTimerId = 0;
00131 }
00132
00133 void Task::refreshIcon()
00134 {
00135
00136 d->pixmap = KWindowSystem::icon(d->win, 16, 16, true);
00137
00138
00139 if (d->pixmap.isNull()) {
00140 KIconLoader::global()->loadIcon(className().toLower(),
00141 KIconLoader::Small,
00142 KIconLoader::Small,
00143 KIconLoader::DefaultState,
00144 QStringList(), 0, true);
00145
00146
00147 if (d->pixmap.isNull()) {
00148 d->pixmap = SmallIcon("xorg");
00149 }
00150 }
00151
00152 d->lastIcon = QPixmap();
00153 d->icon = QIcon();
00154 emit changed(IconChanged);
00155 }
00156
00157 ::TaskManager::TaskChanges Task::refresh(unsigned int dirty)
00158 {
00159 if (!d->lastUpdate.isNull() && d->lastUpdate.elapsed() < 200) {
00160 d->cachedChanges |= dirty;
00161
00162 if (!d->cachedChangesTimerId) {
00163 d->cachedChangesTimerId = startTimer(200 - d->lastUpdate.elapsed());
00164 }
00165
00166 d->lastUpdate.restart();
00167 return TaskUnchanged;
00168 }
00169
00170 d->lastUpdate.restart();
00171 KWindowInfo info = KWindowSystem::windowInfo(d->win, windowInfoFlags, windowInfoFlags2);
00172 TaskChanges changes = TaskUnchanged;
00173
00174 if (d->info.visibleName() != info.visibleName() ||
00175 d->info.visibleNameWithState() != info.visibleNameWithState() ||
00176 d->info.name() != info.name()) {
00177 changes |= NameChanged;
00178 }
00179
00180 d->info = info;
00181
00182 if (dirty & NET::WMState || dirty & NET::XAWMState) {
00183 changes |= StateChanged;
00184 }
00185
00186 if (dirty & NET::WMDesktop) {
00187 changes |= DesktopChanged;
00188 }
00189
00190 if (dirty & NET::WMGeometry) {
00191 changes |= GeometryChanged;
00192 }
00193
00194 if (dirty & NET::WMWindowType) {
00195 changes |= WindowTypeChanged;
00196 }
00197
00198 if (dirty & NET::WM2AllowedActions) {
00199 changes |= ActionsChanged;
00200 }
00201
00202 if (dirty & NET::WMIcon) {
00203 refreshIcon();
00204 }
00205
00206 if (changes != TaskUnchanged) {
00207 emit changed(changes);
00208 }
00209
00210 return changes;
00211 }
00212
00213 void Task::setActive(bool a)
00214 {
00215 d->active = a;
00216 emit changed(StateChanged);
00217 if (a) {
00218 emit activated();
00219 } else {
00220 emit deactivated();
00221 }
00222 }
00223
00224 bool Task::isMaximized() const
00225 {
00226 return d->info.valid(true) && (d->info.state() & NET::Max);
00227 }
00228
00229 bool Task::isMinimized() const
00230 {
00231 return d->info.valid(true) && d->info.isMinimized();
00232 }
00233
00234 bool Task::isIconified() const
00235 {
00236 return d->info.valid(true) && d->info.isMinimized();
00237 }
00238
00239 bool Task::isAlwaysOnTop() const
00240 {
00241 return d->info.valid(true) && (d->info.state() & NET::StaysOnTop);
00242 }
00243
00244 bool Task::isKeptBelowOthers() const
00245 {
00246 return d->info.valid(true) && (d->info.state() & NET::KeepBelow);
00247 }
00248
00249 bool Task::isFullScreen() const
00250 {
00251 return d->info.valid(true) && (d->info.state() & NET::FullScreen);
00252 }
00253
00254 bool Task::isShaded() const
00255 {
00256 return d->info.valid(true) && (d->info.state() & NET::Shaded);
00257 }
00258
00259 bool Task::isOnCurrentDesktop() const
00260 {
00261 return d->info.valid(true) && d->info.isOnCurrentDesktop();
00262 }
00263
00264 bool Task::isOnAllDesktops() const
00265 {
00266 return d->info.valid(true) && d->info.onAllDesktops();
00267 }
00268
00269 bool Task::isActive() const
00270 {
00271 return d->active;
00272 }
00273
00274 bool Task::isOnTop() const
00275 {
00276 return TaskManager::self()->isOnTop(this);
00277 }
00278
00279 bool Task::isModified() const
00280 {
00281 static QString modStr = QString::fromUtf8("[") +
00282 i18nc("marks that a task has been modified", "modified") +
00283 QString::fromUtf8("]");
00284 int modStrPos = d->info.visibleName().indexOf(modStr);
00285
00286 return ( modStrPos != -1 );
00287 }
00288
00289 int Task::desktop() const
00290 {
00291 return d->info.desktop();
00292 }
00293
00294 bool Task::demandsAttention() const
00295 {
00296 return (d->info.valid() && (d->info.state() & NET::DemandsAttention)) ||
00297 !d->transientsDemandingAttention.isEmpty();
00298 }
00299
00300 bool Task::isOnScreen( int screen ) const
00301 {
00302 return TaskManager::isOnScreen( screen, d->win );
00303 }
00304
00305 bool Task::showInTaskbar() const
00306 {
00307 return d->info.state() ^ NET::SkipTaskbar;
00308 }
00309
00310 bool Task::showInPager() const
00311 {
00312 return d->info.state() ^ NET::SkipPager;
00313 }
00314
00315 QRect Task::geometry() const
00316 {
00317 return d->info.geometry();
00318 }
00319
00320 void Task::updateDemandsAttentionState( WId w )
00321 {
00322 if (window() != w) {
00323
00324 NETWinInfo i( QX11Info::display(), w, QX11Info::appRootWindow(), NET::WMState );
00325 if (i.state() & NET::DemandsAttention) {
00326 if (!d->transientsDemandingAttention.contains(w)) {
00327 d->transientsDemandingAttention.insert(w);
00328 }
00329 } else {
00330 d->transientsDemandingAttention.remove(w);
00331 }
00332 }
00333 }
00334
00335 void Task::addTransient( WId w, const NETWinInfo& info )
00336 {
00337 d->transients.insert(w);
00338 if (info.state() & NET::DemandsAttention) {
00339 d->transientsDemandingAttention.insert(w);
00340 emit changed(TransientsChanged);
00341 }
00342 }
00343
00344 void Task::removeTransient(WId w)
00345 {
00346 d->transients.remove(w);
00347 d->transientsDemandingAttention.remove(w);
00348 }
00349
00350 bool Task::hasTransient(WId w) const
00351 {
00352 return d->transients.contains(w);
00353 }
00354
00355 WId Task::window() const
00356 {
00357 return d->win;
00358 }
00359
00360 KWindowInfo Task::info() const
00361 {
00362 return d->info;
00363 }
00364
00365 QString Task::visibleName() const
00366 {
00367 return d->info.visibleName();
00368 }
00369
00370 QString Task::visibleNameWithState() const
00371 {
00372 return d->info.visibleNameWithState();
00373 }
00374
00375 QString Task::name() const
00376 {
00377 return d->info.name();
00378 }
00379
00380 QString Task::className() const
00381 {
00382 XClassHint hint;
00383 if(XGetClassHint(QX11Info::display(), d->win, &hint)) {
00384 QString nh( hint.res_name );
00385 XFree( hint.res_name );
00386 XFree( hint.res_class );
00387 return nh;
00388 }
00389 return QString();
00390 }
00391
00392 QString Task::classClass() const
00393 {
00394 XClassHint hint;
00395 if(XGetClassHint(QX11Info::display(), d->win, &hint)) {
00396 QString ch( hint.res_class );
00397 XFree( hint.res_name );
00398 XFree( hint.res_class );
00399 return ch;
00400 }
00401 return QString();
00402 }
00403
00404 QPixmap Task::icon( int width, int height, bool allowResize )
00405 {
00406 if ( (width == d->lastWidth)
00407 && (height == d->lastHeight)
00408 && (allowResize == d->lastResize )
00409 && (!d->lastIcon.isNull()) )
00410 return d->lastIcon;
00411
00412 QPixmap newIcon = KWindowSystem::icon( d->win, width, height, allowResize );
00413 if ( !newIcon.isNull() ) {
00414 d->lastIcon = newIcon;
00415 d->lastWidth = width;
00416 d->lastHeight = height;
00417 d->lastResize = allowResize;
00418 }
00419
00420 return newIcon;
00421 }
00422
00423 QIcon Task::icon()
00424 {
00425 if ( !d->icon.isNull() )
00426 return d->icon;
00427
00428 d->icon.addPixmap(KWindowSystem::icon( d->win, KIconLoader::SizeSmall, KIconLoader::SizeSmall, false));
00429 d->icon.addPixmap(KWindowSystem::icon( d->win, KIconLoader::SizeSmallMedium, KIconLoader::SizeSmallMedium, false));
00430 d->icon.addPixmap(KWindowSystem::icon( d->win, KIconLoader::SizeMedium, KIconLoader::SizeMedium, false));
00431 d->icon.addPixmap(KWindowSystem::icon( d->win, KIconLoader::SizeLarge, KIconLoader::SizeLarge, false));
00432
00433 return d->icon;
00434 }
00435
00436 WindowList Task::transients() const
00437 {
00438 return d->transients;
00439 }
00440
00441 QPixmap Task::pixmap() const
00442 {
00443 return d->pixmap;
00444 }
00445
00446 QPixmap Task::bestIcon( int size, bool &isStaticIcon )
00447 {
00448 QPixmap pixmap;
00449 isStaticIcon = false;
00450
00451 switch( size ) {
00452 case KIconLoader::SizeSmall:
00453 {
00454 pixmap = icon( 16, 16, true );
00455
00456
00457 if( pixmap.isNull() ) {
00458 pixmap = KIconLoader::global()->loadIcon( "xorg",
00459 KIconLoader::NoGroup,
00460 KIconLoader::SizeSmall );
00461 isStaticIcon = true;
00462 }
00463 }
00464 break;
00465 case KIconLoader::SizeMedium:
00466 {
00467
00468
00469
00470
00471 pixmap = icon( 34, 34, false );
00472
00473 if ( (( pixmap.width() != 34 ) || ( pixmap.height() != 34 )) &&
00474 (( pixmap.width() != 32 ) || ( pixmap.height() != 32 )) )
00475 {
00476 pixmap = icon( 32, 32, true );
00477 }
00478
00479
00480 if( pixmap.isNull() ) {
00481 pixmap = KIconLoader::global()->loadIcon( "xorg",
00482 KIconLoader::NoGroup,
00483 KIconLoader::SizeMedium );
00484 isStaticIcon = true;
00485 }
00486 }
00487 break;
00488 case KIconLoader::SizeLarge:
00489 {
00490
00491 pixmap = icon( size, size, false );
00492
00493
00494 if ( pixmap.isNull() || pixmap.width() != size || pixmap.height() != size ) {
00495 pixmap = KIconLoader::global()->loadIcon( className(),
00496 KIconLoader::NoGroup,
00497 size,
00498 KIconLoader::DefaultState,
00499 QStringList(), 0L,
00500 true );
00501 isStaticIcon = true;
00502 }
00503
00504
00505 if ( pixmap.isNull() || ( pixmap.width() != size ) || ( pixmap.height() != size ) ) {
00506 pixmap = icon( size, size, true );
00507 isStaticIcon = false;
00508 }
00509
00510
00511 if( pixmap.isNull() ) {
00512 pixmap = KIconLoader::global()->loadIcon( "xorg",
00513 KIconLoader::NoGroup,
00514 size );
00515 isStaticIcon = true;
00516 }
00517 }
00518 }
00519
00520 return pixmap;
00521 }
00522
00523 bool Task::idMatch( const QString& id1, const QString& id2 )
00524 {
00525 if ( id1.isEmpty() || id2.isEmpty() )
00526 return false;
00527
00528 if ( id1.contains( id2 ) > 0 )
00529 return true;
00530
00531 if ( id2.contains( id1 ) > 0 )
00532 return true;
00533
00534 return false;
00535 }
00536
00537 void Task::move()
00538 {
00539 bool on_current = d->info.isOnCurrentDesktop();
00540
00541 if (!on_current)
00542 {
00543 KWindowSystem::setCurrentDesktop(d->info.desktop());
00544 KWindowSystem::forceActiveWindow(d->win);
00545 }
00546
00547 if (d->info.isMinimized())
00548 {
00549 KWindowSystem::unminimizeWindow(d->win);
00550 }
00551
00552 QRect geom = d->info.geometry();
00553 QCursor::setPos(geom.center());
00554
00555 NETRootInfo ri(QX11Info::display(), NET::WMMoveResize);
00556 ri.moveResizeRequest(d->win, geom.center().x(),
00557 geom.center().y(), NET::Move);
00558 }
00559
00560 void Task::resize()
00561 {
00562 bool on_current = d->info.isOnCurrentDesktop();
00563
00564 if (!on_current)
00565 {
00566 KWindowSystem::setCurrentDesktop(d->info.desktop());
00567 KWindowSystem::forceActiveWindow(d->win);
00568 }
00569
00570 if (d->info.isMinimized())
00571 {
00572 KWindowSystem::unminimizeWindow(d->win);
00573 }
00574
00575 QRect geom = d->info.geometry();
00576 QCursor::setPos(geom.bottomRight());
00577
00578 NETRootInfo ri(QX11Info::display(), NET::WMMoveResize);
00579 ri.moveResizeRequest(d->win, geom.bottomRight().x(),
00580 geom.bottomRight().y(), NET::BottomRight);
00581 }
00582
00583 void Task::setMaximized(bool maximize)
00584 {
00585 KWindowInfo info = KWindowSystem::windowInfo(d->win, NET::WMState | NET::XAWMState | NET::WMDesktop);
00586 bool on_current = info.isOnCurrentDesktop();
00587
00588 if (!on_current)
00589 {
00590 KWindowSystem::setCurrentDesktop(info.desktop());
00591 }
00592
00593 if (info.isMinimized())
00594 {
00595 KWindowSystem::unminimizeWindow(d->win);
00596 }
00597
00598 NETWinInfo ni(QX11Info::display(), d->win, QX11Info::appRootWindow(), NET::WMState);
00599
00600 if (maximize)
00601 {
00602 ni.setState(NET::Max, NET::Max);
00603 }
00604 else
00605 {
00606 ni.setState(0, NET::Max);
00607 }
00608
00609 if (!on_current)
00610 {
00611 KWindowSystem::forceActiveWindow(d->win);
00612 }
00613 }
00614
00615 void Task::toggleMaximized()
00616 {
00617 setMaximized(!isMaximized());
00618 }
00619
00620 void Task::restore()
00621 {
00622 KWindowInfo info = KWindowSystem::windowInfo(d->win, NET::WMState | NET::XAWMState | NET::WMDesktop);
00623 bool on_current = info.isOnCurrentDesktop();
00624
00625 if (!on_current)
00626 {
00627 KWindowSystem::setCurrentDesktop(info.desktop());
00628 }
00629
00630 if( info.isMinimized())
00631 {
00632 KWindowSystem::unminimizeWindow(d->win);
00633 }
00634
00635 NETWinInfo ni(QX11Info::display(), d->win, QX11Info::appRootWindow(), NET::WMState);
00636 ni.setState(0, NET::Max);
00637
00638 if (!on_current)
00639 {
00640 KWindowSystem::forceActiveWindow( d->win );
00641 }
00642 }
00643
00644 void Task::setIconified(bool iconify)
00645 {
00646 if (iconify)
00647 {
00648 KWindowSystem::minimizeWindow(d->win);
00649 }
00650 else
00651 {
00652 KWindowInfo info = KWindowSystem::windowInfo(d->win, NET::WMState | NET::XAWMState | NET::WMDesktop);
00653 bool on_current = info.isOnCurrentDesktop();
00654
00655 if (!on_current)
00656 {
00657 KWindowSystem::setCurrentDesktop(info.desktop());
00658 }
00659
00660 KWindowSystem::unminimizeWindow(d->win);
00661
00662 if (!on_current)
00663 {
00664 KWindowSystem::forceActiveWindow(d->win);
00665 }
00666 }
00667 }
00668
00669 void Task::toggleIconified()
00670 {
00671 setIconified(!isIconified());
00672 }
00673
00674 void Task::close()
00675 {
00676 NETRootInfo ri( QX11Info::display(), NET::CloseWindow );
00677 ri.closeWindowRequest( d->win );
00678 }
00679
00680 void Task::raise()
00681 {
00682
00683 KWindowSystem::raiseWindow( d->win );
00684 }
00685
00686 void Task::lower()
00687 {
00688
00689 KWindowSystem::lowerWindow( d->win );
00690 }
00691
00692 void Task::activate()
00693 {
00694
00695 WId w = d->win;
00696 if (!d->transientsDemandingAttention.isEmpty()) {
00697 WindowList::const_iterator it = d->transientsDemandingAttention.end();
00698 --it;
00699 w = *it;
00700 }
00701
00702 KWindowSystem::forceActiveWindow(w);
00703 }
00704
00705 void Task::activateRaiseOrIconify()
00706 {
00707
00708 if (!isActive() || isIconified()) {
00709 activate();
00710 } else if (!isActive() && !isOnTop()) {
00711 raise();
00712 } else {
00713 setIconified(true);
00714 }
00715 }
00716
00717 void Task::toDesktop(int desk)
00718 {
00719 NETWinInfo ni(QX11Info::display(), d->win, QX11Info::appRootWindow(), NET::WMDesktop);
00720 if (desk == 0) {
00721 if (isOnAllDesktops()) {
00722 ni.setDesktop(KWindowSystem::currentDesktop());
00723 KWindowSystem::forceActiveWindow(d->win);
00724 } else {
00725 ni.setDesktop(NETWinInfo::OnAllDesktops);
00726 }
00727
00728 return;
00729 }
00730
00731 ni.setDesktop(desk);
00732
00733 if (desk == KWindowSystem::currentDesktop()) {
00734 KWindowSystem::forceActiveWindow(d->win);
00735 }
00736 }
00737
00738 void Task::toCurrentDesktop()
00739 {
00740 toDesktop(KWindowSystem::currentDesktop());
00741 }
00742
00743 void Task::setAlwaysOnTop(bool stay)
00744 {
00745 NETWinInfo ni( QX11Info::display(), d->win, QX11Info::appRootWindow(), NET::WMState);
00746 if(stay)
00747 ni.setState( NET::StaysOnTop, NET::StaysOnTop );
00748 else
00749 ni.setState( 0, NET::StaysOnTop );
00750 }
00751
00752 void Task::toggleAlwaysOnTop()
00753 {
00754 setAlwaysOnTop( !isAlwaysOnTop() );
00755 }
00756
00757 void Task::setKeptBelowOthers(bool below)
00758 {
00759 NETWinInfo ni(QX11Info::display(), d->win, QX11Info::appRootWindow(), NET::WMState);
00760
00761 if (below)
00762 {
00763 ni.setState(NET::KeepBelow, NET::KeepBelow);
00764 }
00765 else
00766 {
00767 ni.setState(0, NET::KeepBelow);
00768 }
00769 }
00770
00771 void Task::toggleKeptBelowOthers()
00772 {
00773 setKeptBelowOthers(!isKeptBelowOthers());
00774 }
00775
00776 void Task::setFullScreen(bool fullscreen)
00777 {
00778 NETWinInfo ni(QX11Info::display(), d->win, QX11Info::appRootWindow(), NET::WMState);
00779
00780 if (fullscreen)
00781 {
00782 ni.setState(NET::FullScreen, NET::FullScreen);
00783 }
00784 else
00785 {
00786 ni.setState(0, NET::FullScreen);
00787 }
00788 }
00789
00790 void Task::toggleFullScreen()
00791 {
00792 setFullScreen(!isFullScreen());
00793 }
00794
00795 void Task::setShaded(bool shade)
00796 {
00797 NETWinInfo ni( QX11Info::display(), d->win, QX11Info::appRootWindow(), NET::WMState);
00798 if(shade)
00799 ni.setState( NET::Shaded, NET::Shaded );
00800 else
00801 ni.setState( 0, NET::Shaded );
00802 }
00803
00804 void Task::toggleShaded()
00805 {
00806 setShaded( !isShaded() );
00807 }
00808
00809 void Task::publishIconGeometry(QRect rect)
00810 {
00811 if (rect == d->iconGeometry)
00812 {
00813 return;
00814 }
00815
00816 d->iconGeometry = rect;
00817 NETWinInfo ni(QX11Info::display(), d->win, QX11Info::appRootWindow(), 0);
00818 NETRect r;
00819
00820 if (rect.isValid())
00821 {
00822 r.pos.x = rect.x();
00823 r.pos.y = rect.y();
00824 r.size.width = rect.width();
00825 r.size.height = rect.height();
00826 }
00827 ni.setIconGeometry(r);
00828 }
00829
00830 void Task::addMimeData(QMimeData *mimeData) const
00831 {
00832 Q_ASSERT(mimeData);
00833
00834 QByteArray data;
00835 data.resize(sizeof(WId));
00836 memcpy(data.data(), &d->win, sizeof(WId));
00837 mimeData->setData(mimetype(), data);
00838 }
00839
00840 QString Task::mimetype()
00841 {
00842 return "windowsystem/winid";
00843 }
00844
00845 QString Task::groupMimetype()
00846 {
00847 return "windowsystem/multiple-winids";
00848 }
00849
00850 QList<WId> Task::idsFromMimeData(const QMimeData *mimeData, bool *ok)
00851 {
00852 Q_ASSERT(mimeData);
00853 QList<WId> ids;
00854
00855 if (ok) {
00856 *ok = false;
00857 }
00858
00859 if (!mimeData->hasFormat(groupMimetype())) {
00860
00861
00862 bool singularOk;
00863 WId id = idFromMimeData(mimeData, &singularOk);
00864
00865 if (ok) {
00866 *ok = singularOk;
00867 }
00868
00869 if (singularOk) {
00870
00871 ids << id;
00872 }
00873
00874 return ids;
00875 }
00876
00877 QByteArray data(mimeData->data(groupMimetype()));
00878 if ((unsigned int)data.size() < sizeof(int) + sizeof(WId)) {
00879
00880 return ids;
00881 }
00882
00883 int count = 0;
00884 memcpy(&count, data.data(), sizeof(int));
00885 if (count < 1 || (unsigned int)data.size() < sizeof(int) + sizeof(WId) * count) {
00886
00887 return ids;
00888 }
00889
00890 WId id;
00891 for (int i = 0; i < count; ++i) {
00892 memcpy(&id, data.data() + sizeof(int) + sizeof(WId) * i, sizeof(WId));
00893 ids << id;
00894 }
00895
00896 if (ok) {
00897 *ok = true;
00898 }
00899
00900 return ids;
00901 }
00902
00903 WId Task::idFromMimeData(const QMimeData *mimeData, bool *ok)
00904 {
00905 Q_ASSERT(mimeData);
00906
00907 if (ok) {
00908 *ok = false;
00909 }
00910
00911 if (!mimeData->hasFormat(mimetype())) {
00912 return 0;
00913 }
00914
00915 QByteArray data(mimeData->data(mimetype()));
00916 if (data.size() != sizeof(WId)) {
00917 return 0;
00918 }
00919
00920 WId id;
00921 memcpy(&id, data.data(), sizeof(WId));
00922
00923 if (ok) {
00924 *ok = true;
00925 }
00926
00927 return id;
00928 }
00929
00930 }
00931
00932 #include "task.moc"
00933