00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "tabbox.h"
00014 #include "workspace.h"
00015 #include "client.h"
00016 #include <qpainter.h>
00017 #include <qlabel.h>
00018 #include <qdrawutil.h>
00019 #include <qstyle.h>
00020 #include <kglobal.h>
00021 #include <fixx11h.h>
00022 #include <kconfig.h>
00023 #include <klocale.h>
00024 #include <qapplication.h>
00025 #include <qdesktopwidget.h>
00026 #include <qcursor.h>
00027 #include <kstringhandler.h>
00028 #include <stdarg.h>
00029 #include <kdebug.h>
00030 #include <kglobalaccel.h>
00031 #include <kkeynative.h>
00032 #include <kglobalsettings.h>
00033 #include <X11/keysym.h>
00034 #include <X11/keysymdef.h>
00035
00036
00037
00038 extern Time qt_x_time;
00039
00040 namespace KWinInternal
00041 {
00042
00043 extern QPixmap* kwin_get_menu_pix_hack();
00044
00045 TabBox::TabBox( Workspace *ws, const char *name )
00046 : QFrame( 0, name, Qt::WNoAutoErase ), client(0), wspace(ws)
00047 {
00048 setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
00049 setLineWidth(2);
00050 setMargin(2);
00051
00052 showMiniIcon = false;
00053
00054 no_tasks = i18n("*** No Windows ***");
00055 m = DesktopMode;
00056 reconfigure();
00057 reset();
00058 connect(&delayedShowTimer, SIGNAL(timeout()), this, SLOT(show()));
00059 }
00060
00061 TabBox::~TabBox()
00062 {
00063 }
00064
00065
00071 void TabBox::setMode( Mode mode )
00072 {
00073 m = mode;
00074 }
00075
00076
00080 void TabBox::createClientList(ClientList &list, int desktop , Client *c, bool chain)
00081 {
00082 ClientList::size_type idx = 0;
00083
00084 list.clear();
00085
00086 Client* start = c;
00087
00088 if ( chain )
00089 c = workspace()->nextFocusChainClient(c);
00090 else
00091 c = workspace()->stackingOrder().first();
00092
00093 Client* stop = c;
00094
00095 while ( c )
00096 {
00097 if ( ((desktop == -1) || c->isOnDesktop(desktop))
00098 && c->wantsTabFocus() )
00099 {
00100 if ( start == c )
00101 {
00102 list.remove( c );
00103 list.prepend( c );
00104 }
00105 else
00106 {
00107 Client* modal = c->findModal();
00108 if( modal == NULL || modal == c )
00109 list += c;
00110 else if( !list.contains( modal ))
00111 list += modal;
00112 else
00113 ;
00114 }
00115 }
00116
00117 if ( chain )
00118 c = workspace()->nextFocusChainClient( c );
00119 else
00120 {
00121 if ( idx >= (workspace()->stackingOrder().size()-1) )
00122 c = 0;
00123 else
00124 c = workspace()->stackingOrder()[++idx];
00125 }
00126
00127 if ( c == stop )
00128 break;
00129 }
00130 }
00131
00132
00137 void TabBox::reset()
00138 {
00139 int w, h, cw = 0, wmax = 0;
00140
00141 QRect r = KGlobalSettings::desktopGeometry(QCursor::pos());
00142
00143
00144
00145 lineHeight = QMAX(fontMetrics().height() + 2, 32 + 4);
00146
00147 if ( mode() == WindowsMode )
00148 {
00149 client = workspace()->activeClient();
00150
00151
00152 createClientList(clients, options_traverse_all ? -1 : workspace()->currentDesktop(), client, true);
00153
00154
00155 cw = fontMetrics().width(no_tasks)+20;
00156 for (ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
00157 {
00158 cw = fontMetrics().width( (*it)->caption() );
00159 if ( cw > wmax ) wmax = cw;
00160 }
00161
00162
00163 if ( clients.count() == 0 )
00164 {
00165 QFont f = font();
00166 f.setBold( TRUE );
00167 f.setPointSize( 14 );
00168
00169 h = QFontMetrics(f).height()*4;
00170 }
00171 else
00172 {
00173 showMiniIcon = false;
00174 h = clients.count() * lineHeight;
00175
00176 if ( h > (r.height()-(2*frameWidth())) )
00177 {
00178 showMiniIcon = true;
00179
00180 lineHeight = QMAX(fontMetrics().height() + 2, 16 + 2);
00181
00182 h = clients.count() * lineHeight;
00183
00184 if ( h > (r.height()-(2*frameWidth())) )
00185 {
00186
00187 int howMany = (h - (r.height()-(2*frameWidth())))/lineHeight;
00188 for (; howMany; howMany--)
00189 clients.remove(clients.last());
00190
00191 h = clients.count() * lineHeight;
00192 }
00193 }
00194 }
00195 }
00196 else
00197 {
00198 showMiniIcon = false;
00199 desk = workspace()->currentDesktop();
00200
00201 for ( int i = 1; i <= workspace()->numberOfDesktops(); i++ )
00202 {
00203 cw = fontMetrics().width( workspace()->desktopName(i) );
00204 if ( cw > wmax ) wmax = cw;
00205 }
00206
00207
00208 h = workspace()->numberOfDesktops() * lineHeight;
00209 }
00210
00211
00212 h += 2 * frameWidth();
00213 w = 2*frameWidth() + 5*2 + ( showMiniIcon ? 16 : 32 ) + 8 + wmax;
00214 w = kClamp( w, r.width()/3 , r.width() );
00215
00216 setGeometry( (r.width()-w)/2 + r.x(),
00217 (r.height()-h)/2+ r.y(),
00218 w, h );
00219 }
00220
00221
00225 void TabBox::nextPrev( bool next)
00226 {
00227 if ( mode() == WindowsMode )
00228 {
00229 Client* firstClient = 0;
00230 do
00231 {
00232 if ( next )
00233 client = workspace()->nextFocusChainClient(client);
00234 else
00235 client = workspace()->previousFocusChainClient(client);
00236 if (!firstClient)
00237 {
00238
00239
00240 firstClient = client;
00241 }
00242 else if (client == firstClient)
00243 {
00244
00245 client = 0;
00246 break;
00247 }
00248 } while ( client && !clients.contains( client ));
00249 }
00250 else if( mode() == DesktopMode )
00251 {
00252 if ( next )
00253 desk = workspace()->nextDesktopFocusChain( desk );
00254 else
00255 desk = workspace()->previousDesktopFocusChain( desk );
00256 }
00257 else
00258 {
00259 if ( next )
00260 {
00261 desk++;
00262 if ( desk > workspace()->numberOfDesktops() )
00263 desk = 1;
00264 }
00265 else
00266 {
00267 desk--;
00268 if ( desk < 1 )
00269 desk = workspace()->numberOfDesktops();
00270 }
00271 }
00272
00273 update();
00274 }
00275
00276
00277
00282 Client* TabBox::currentClient()
00283 {
00284 if ( mode() != WindowsMode )
00285 return 0;
00286 if (!workspace()->hasClient( client ))
00287 return 0;
00288 return client;
00289 }
00290
00296 int TabBox::currentDesktop()
00297 {
00298 if ( mode() == DesktopListMode || mode() == DesktopMode )
00299 return desk;
00300 else
00301 return -1;
00302 }
00303
00304
00308 void TabBox::showEvent( QShowEvent* )
00309 {
00310 raise();
00311 }
00312
00313
00317 void TabBox::hideEvent( QHideEvent* )
00318 {
00319 }
00320
00324 void TabBox::drawContents( QPainter * )
00325 {
00326 QRect r(contentsRect());
00327 QPixmap pix(r.size());
00328 pix.fill(this, 0, 0);
00329
00330 QPainter p;
00331 p.begin(&pix, this);
00332
00333 QPixmap* menu_pix = kwin_get_menu_pix_hack();
00334
00335 int iconWidth = showMiniIcon ? 16 : 32;
00336 int x = 0;
00337 int y = 0;
00338
00339 if ( mode () == WindowsMode )
00340 {
00341 if ( !currentClient() )
00342 {
00343 QFont f = font();
00344 f.setBold( TRUE );
00345 f.setPointSize( 14 );
00346
00347 p.setFont(f);
00348 p.drawText( r, AlignCenter, no_tasks);
00349 }
00350 else
00351 {
00352 for (ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
00353 {
00354 if ( workspace()->hasClient( *it ) )
00355 {
00356
00357 if ( (*it) == currentClient() )
00358 p.fillRect(x, y, r.width(), lineHeight, colorGroup().highlight());
00359
00360
00361 if ( showMiniIcon )
00362 {
00363 if ( !(*it)->miniIcon().isNull() )
00364 p.drawPixmap( x+5, y + (lineHeight - iconWidth)/2, (*it)->miniIcon() );
00365 }
00366 else
00367 if ( !(*it)->icon().isNull() )
00368 p.drawPixmap( x+5, y + (lineHeight - iconWidth)/2, (*it)->icon() );
00369 else if ( menu_pix )
00370 p.drawPixmap( x, y + (lineHeight - iconWidth)/2, *menu_pix );
00371
00372
00373 QString s;
00374
00375 if ( !(*it)->isOnDesktop(workspace()->currentDesktop()) )
00376 s = workspace()->desktopName((*it)->desktop()) + ": ";
00377
00378 if ( (*it)->isMinimized() )
00379 s += QString("(") + (*it)->caption() + ")";
00380 else
00381 s += (*it)->caption();
00382
00383 s = KStringHandler::cPixelSqueeze(s, fontMetrics(), r.width() - 5 - iconWidth - 8);
00384
00385
00386 if ( (*it) == currentClient() )
00387 p.setPen(colorGroup().highlightedText());
00388 else
00389 p.setPen(colorGroup().text());
00390
00391 p.drawText(x+5 + iconWidth + 8, y, r.width() - 5 - iconWidth - 8, lineHeight,
00392 Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine, s);
00393
00394 y += lineHeight;
00395 }
00396 if ( y >= r.height() ) break;
00397 }
00398 }
00399 }
00400 else
00401 {
00402 int iconHeight = iconWidth;
00403
00404
00405 QFont f(font());
00406 f.setBold(true);
00407 f.setPixelSize(iconHeight - 4);
00408 QFontMetrics fm(f);
00409
00410 int wmax = 0;
00411 for ( int i = 1; i <= workspace()->numberOfDesktops(); i++ )
00412 {
00413 wmax = QMAX(wmax, fontMetrics().width(workspace()->desktopName(i)));
00414
00415
00416 QString num = QString::number(i);
00417 iconWidth = QMAX(iconWidth - 4, fm.boundingRect(num).width()) + 4;
00418 }
00419
00420
00421
00422 int iDesktop = (mode() == DesktopMode) ? workspace()->currentDesktop() : 1;
00423 for ( int i = 1; i <= workspace()->numberOfDesktops(); i++ )
00424 {
00425
00426 if ( iDesktop == desk )
00427 p.fillRect(x, y, r.width(), lineHeight, colorGroup().highlight());
00428
00429 p.save();
00430
00431
00432 p.fillRect(x+5, y+2, iconWidth, iconHeight, colorGroup().base());
00433 p.setPen(colorGroup().text());
00434 p.drawRect(x+5, y+2, iconWidth, iconHeight);
00435
00436
00437 p.setFont(f);
00438 QString num = QString::number(iDesktop);
00439 p.drawText(x+5, y+2, iconWidth, iconHeight, Qt::AlignCenter, num);
00440
00441 p.restore();
00442
00443
00444 if ( iDesktop == desk )
00445 p.setPen(colorGroup().highlightedText());
00446 else
00447 p.setPen(colorGroup().text());
00448
00449 p.drawText(x+5 + iconWidth + 8, y, r.width() - 5 - iconWidth - 8, lineHeight,
00450 Qt::AlignLeft | Qt::AlignVCenter | Qt::SingleLine,
00451 workspace()->desktopName(iDesktop));
00452
00453
00454 int x1 = x + 5 + iconWidth + 8 + wmax + 5;
00455
00456 ClientList list;
00457 createClientList(list, iDesktop, 0, false);
00458
00459 for (ClientList::ConstIterator it = list.fromLast(); it != list.end(); --it)
00460 {
00461 if ( !(*it)->miniIcon().isNull() )
00462 {
00463 if ( x1+18 >= x+r.width() )
00464 break;
00465
00466 p.drawPixmap( x1, y + (lineHeight - 16)/2, (*it)->miniIcon() );
00467 x1 += 18;
00468 }
00469 }
00470
00471
00472 y += lineHeight;
00473 if ( y >= r.height() ) break;
00474
00475 if( mode() == DesktopMode )
00476 iDesktop = workspace()->nextDesktopFocusChain( iDesktop );
00477 else
00478 iDesktop++;
00479 }
00480 }
00481 p.end();
00482 bitBlt(this, r.x(), r.y(), &pix);
00483 }
00484
00485 void TabBox::hide()
00486 {
00487 delayedShowTimer.stop();
00488 QWidget::hide();
00489 QApplication::syncX();
00490 XEvent otherEvent;
00491 while (XCheckTypedEvent (qt_xdisplay(), EnterNotify, &otherEvent ) )
00492 ;
00493 }
00494
00495
00496 void TabBox::reconfigure()
00497 {
00498 KConfig * c(KGlobal::config());
00499 c->setGroup("TabBox");
00500 options_traverse_all = c->readNumEntry("TraverseAll", false );
00501 }
00502
00521 void TabBox::delayedShow()
00522 {
00523 KConfig * c(KGlobal::config());
00524 c->setGroup("TabBox");
00525 bool delay = c->readNumEntry("ShowDelay", true);
00526
00527 if (!delay)
00528 {
00529 show();
00530 return;
00531 }
00532
00533 int delayTime = c->readNumEntry("DelayTime", 90);
00534 delayedShowTimer.start(delayTime, true);
00535 }
00536
00537
00538 void TabBox::handleMouseEvent( XEvent* e )
00539 {
00540 XAllowEvents( qt_xdisplay(), AsyncPointer, qt_x_time );
00541 if( e->type != ButtonPress )
00542 return;
00543 QPoint pos( e->xbutton.x_root, e->xbutton.y_root );
00544 if( !geometry().contains( pos ))
00545 {
00546 workspace()->closeTabBox();
00547 return;
00548 }
00549 pos.rx() -= x();
00550 pos.ry() -= y();
00551 int num = (pos.y()-frameWidth()) / lineHeight;
00552
00553 if( mode() == WindowsMode )
00554 {
00555 for( ClientList::ConstIterator it = clients.begin();
00556 it != clients.end();
00557 ++it)
00558 {
00559 if( workspace()->hasClient( *it ) && (num == 0) )
00560 {
00561 client = *it;
00562 break;
00563 }
00564 num--;
00565 }
00566 }
00567 else
00568 {
00569 int iDesktop = (mode() == DesktopMode) ? workspace()->currentDesktop() : 1;
00570 for( int i = 1;
00571 i <= workspace()->numberOfDesktops();
00572 ++i )
00573 {
00574 if( num == 0 )
00575 {
00576 desk = iDesktop;
00577 break;
00578 }
00579 num--;
00580 if( mode() == DesktopMode )
00581 iDesktop = workspace()->nextDesktopFocusChain( iDesktop );
00582 else
00583 iDesktop++;
00584 }
00585 }
00586 update();
00587 }
00588
00589
00590
00591
00592
00593
00598 static
00599 bool areKeySymXsDepressed( bool bAll, int nKeySyms, ... )
00600 {
00601 va_list args;
00602 char keymap[32];
00603
00604 kdDebug(125) << "areKeySymXsDepressed: " << (bAll ? "all of " : "any of ") << nKeySyms << endl;
00605
00606 va_start( args, nKeySyms );
00607 XQueryKeymap( qt_xdisplay(), keymap );
00608
00609 for( int iKeySym = 0; iKeySym < nKeySyms; iKeySym++ )
00610 {
00611 uint keySymX = va_arg( args, uint );
00612 uchar keyCodeX = XKeysymToKeycode( qt_xdisplay(), keySymX );
00613 int i = keyCodeX / 8;
00614 char mask = 1 << (keyCodeX - (i * 8));
00615
00616 kdDebug(125) << iKeySym << ": keySymX=0x" << QString::number( keySymX, 16 )
00617 << " i=" << i << " mask=0x" << QString::number( mask, 16 )
00618 << " keymap[i]=0x" << QString::number( keymap[i], 16 ) << endl;
00619
00620
00621 if( i < 0 || i >= 32 )
00622 return false;
00623
00624
00625 if( bAll )
00626 {
00627 if( (keymap[i] & mask) == 0 )
00628 return false;
00629 }
00630 else
00631 {
00632
00633 if( keymap[i] & mask )
00634 return true;
00635 }
00636 }
00637
00638
00639
00640 return bAll;
00641 }
00642
00643 static bool areModKeysDepressed( const KKeySequence& seq )
00644 {
00645 uint rgKeySyms[10];
00646 int nKeySyms = 0;
00647 if( seq.isNull())
00648 return false;
00649 int mod = seq.key(seq.count()-1).modFlags();
00650
00651 if ( mod & KKey::SHIFT )
00652 {
00653 rgKeySyms[nKeySyms++] = XK_Shift_L;
00654 rgKeySyms[nKeySyms++] = XK_Shift_R;
00655 }
00656 if ( mod & KKey::CTRL )
00657 {
00658 rgKeySyms[nKeySyms++] = XK_Control_L;
00659 rgKeySyms[nKeySyms++] = XK_Control_R;
00660 }
00661 if( mod & KKey::ALT )
00662 {
00663 rgKeySyms[nKeySyms++] = XK_Alt_L;
00664 rgKeySyms[nKeySyms++] = XK_Alt_R;
00665 }
00666 if( mod & KKey::WIN )
00667 {
00668
00669
00670 rgKeySyms[nKeySyms++] = XK_Super_L;
00671 rgKeySyms[nKeySyms++] = XK_Super_R;
00672 rgKeySyms[nKeySyms++] = XK_Meta_L;
00673 rgKeySyms[nKeySyms++] = XK_Meta_R;
00674 }
00675
00676
00677 return areKeySymXsDepressed( false, nKeySyms,
00678 rgKeySyms[0], rgKeySyms[1], rgKeySyms[2], rgKeySyms[3],
00679 rgKeySyms[4], rgKeySyms[5], rgKeySyms[6], rgKeySyms[7] );
00680 }
00681
00682 static bool areModKeysDepressed( const KShortcut& cut )
00683 {
00684 for( unsigned int i = 0;
00685 i < cut.count();
00686 ++i )
00687 {
00688 if( areModKeysDepressed( cut.seq( i )))
00689 return true;
00690 }
00691 return false;
00692 }
00693
00694 void Workspace::slotWalkThroughWindows()
00695 {
00696 if ( root != qt_xrootwin() )
00697 return;
00698 if ( tab_grab || control_grab )
00699 return;
00700 if ( options->altTabStyle == Options::CDE || !options->focusPolicyIsReasonable() )
00701 {
00702
00703
00704 CDEWalkThroughWindows( true );
00705 }
00706 else
00707 {
00708 if ( areModKeysDepressed( cutWalkThroughWindows ) )
00709 {
00710 if ( startKDEWalkThroughWindows() )
00711 KDEWalkThroughWindows( true );
00712 }
00713 else
00714
00715
00716
00717
00718 CDEWalkThroughWindows( true );
00719 }
00720 }
00721
00722 void Workspace::slotWalkBackThroughWindows()
00723 {
00724 if ( root != qt_xrootwin() )
00725 return;
00726 if( tab_grab || control_grab )
00727 return;
00728 if ( options->altTabStyle == Options::CDE || !options->focusPolicyIsReasonable() )
00729 {
00730
00731 CDEWalkThroughWindows( false );
00732 }
00733 else
00734 {
00735 if ( areModKeysDepressed( cutWalkThroughWindowsReverse ) )
00736 {
00737 if ( startKDEWalkThroughWindows() )
00738 KDEWalkThroughWindows( false );
00739 }
00740 else
00741 {
00742 CDEWalkThroughWindows( false );
00743 }
00744 }
00745 }
00746
00747 void Workspace::slotWalkThroughDesktops()
00748 {
00749 if ( root != qt_xrootwin() )
00750 return;
00751 if( tab_grab || control_grab )
00752 return;
00753 if ( areModKeysDepressed( cutWalkThroughDesktops ) )
00754 {
00755 if ( startWalkThroughDesktops() )
00756 walkThroughDesktops( true );
00757 }
00758 else
00759 {
00760 oneStepThroughDesktops( true );
00761 }
00762 }
00763
00764 void Workspace::slotWalkBackThroughDesktops()
00765 {
00766 if ( root != qt_xrootwin() )
00767 return;
00768 if( tab_grab || control_grab )
00769 return;
00770 if ( areModKeysDepressed( cutWalkThroughDesktopsReverse ) )
00771 {
00772 if ( startWalkThroughDesktops() )
00773 walkThroughDesktops( false );
00774 }
00775 else
00776 {
00777 oneStepThroughDesktops( false );
00778 }
00779 }
00780
00781 void Workspace::slotWalkThroughDesktopList()
00782 {
00783 if ( root != qt_xrootwin() )
00784 return;
00785 if( tab_grab || control_grab )
00786 return;
00787 if ( areModKeysDepressed( cutWalkThroughDesktopList ) )
00788 {
00789 if ( startWalkThroughDesktopList() )
00790 walkThroughDesktops( true );
00791 }
00792 else
00793 {
00794 oneStepThroughDesktopList( true );
00795 }
00796 }
00797
00798 void Workspace::slotWalkBackThroughDesktopList()
00799 {
00800 if ( root != qt_xrootwin() )
00801 return;
00802 if( tab_grab || control_grab )
00803 return;
00804 if ( areModKeysDepressed( cutWalkThroughDesktopListReverse ) )
00805 {
00806 if ( startWalkThroughDesktopList() )
00807 walkThroughDesktops( false );
00808 }
00809 else
00810 {
00811 oneStepThroughDesktopList( false );
00812 }
00813 }
00814
00815 bool Workspace::startKDEWalkThroughWindows()
00816 {
00817 if( !establishTabBoxGrab())
00818 return false;
00819 tab_grab = TRUE;
00820 keys->setEnabled( false );
00821 tab_box->setMode( TabBox::WindowsMode );
00822 tab_box->reset();
00823 return TRUE;
00824 }
00825
00826 bool Workspace::startWalkThroughDesktops( int mode )
00827 {
00828 if( !establishTabBoxGrab())
00829 return false;
00830 control_grab = TRUE;
00831 keys->setEnabled( false );
00832 tab_box->setMode( (TabBox::Mode) mode );
00833 tab_box->reset();
00834 return TRUE;
00835 }
00836
00837 bool Workspace::startWalkThroughDesktops()
00838 {
00839 return startWalkThroughDesktops( TabBox::DesktopMode );
00840 }
00841
00842 bool Workspace::startWalkThroughDesktopList()
00843 {
00844 return startWalkThroughDesktops( TabBox::DesktopListMode );
00845 }
00846
00847 void Workspace::KDEWalkThroughWindows( bool forward )
00848 {
00849 tab_box->nextPrev( forward );
00850 tab_box->delayedShow();
00851 }
00852
00853 void Workspace::walkThroughDesktops( bool forward )
00854 {
00855 tab_box->nextPrev( forward );
00856 tab_box->delayedShow();
00857 }
00858
00859 void Workspace::CDEWalkThroughWindows( bool forward )
00860 {
00861 Client* c = topClientOnDesktop( currentDesktop());
00862 Client* nc = c;
00863 bool options_traverse_all;
00864 {
00865 KConfigGroupSaver saver( KGlobal::config(), "TabBox" );
00866 options_traverse_all = KGlobal::config()->readNumEntry("TraverseAll", false );
00867 }
00868
00869 if ( !forward )
00870 {
00871 do
00872 {
00873 nc = previousStaticClient(nc);
00874 } while (nc && nc != c &&
00875 (( !options_traverse_all && !nc->isOnDesktop(currentDesktop())) ||
00876 nc->isMinimized() || !nc->wantsTabFocus() ) );
00877 }
00878 else
00879 {
00880 do
00881 {
00882 nc = nextStaticClient(nc);
00883 } while (nc && nc != c &&
00884 (( !options_traverse_all && !nc->isOnDesktop(currentDesktop())) ||
00885 nc->isMinimized() || !nc->wantsTabFocus() ) );
00886 }
00887 if (c && c != nc)
00888 lowerClient( c );
00889 if (nc)
00890 {
00891 if ( options->focusPolicyIsReasonable() )
00892 {
00893 activateClient( nc );
00894 if( nc->isShade())
00895 nc->setShade( ShadeActivated );
00896 }
00897 else
00898 {
00899 if( !nc->isOnDesktop( currentDesktop()))
00900 setCurrentDesktop( nc->desktop());
00901 raiseClient( nc );
00902 }
00903 }
00904 }
00905
00906 void Workspace::KDEOneStepThroughWindows( bool forward )
00907 {
00908 tab_box->setMode( TabBox::WindowsMode );
00909 tab_box->reset();
00910 tab_box->nextPrev( forward );
00911 if( Client* c = tab_box->currentClient() )
00912 {
00913 activateClient( c );
00914 if( c->isShade())
00915 c->setShade( ShadeActivated );
00916 }
00917 }
00918
00919 void Workspace::oneStepThroughDesktops( bool forward, int mode )
00920 {
00921 tab_box->setMode( (TabBox::Mode) mode );
00922 tab_box->reset();
00923 tab_box->nextPrev( forward );
00924 if ( tab_box->currentDesktop() != -1 )
00925 setCurrentDesktop( tab_box->currentDesktop() );
00926 }
00927
00928 void Workspace::oneStepThroughDesktops( bool forward )
00929 {
00930 oneStepThroughDesktops( forward, TabBox::DesktopMode );
00931 }
00932
00933 void Workspace::oneStepThroughDesktopList( bool forward )
00934 {
00935 oneStepThroughDesktops( forward, TabBox::DesktopListMode );
00936 }
00937
00941 void Workspace::tabBoxKeyPress( const KKeyNative& keyX )
00942 {
00943 bool forward = false;
00944 bool backward = false;
00945
00946 if (tab_grab)
00947 {
00948 forward = cutWalkThroughWindows.contains( keyX );
00949 backward = cutWalkThroughWindowsReverse.contains( keyX );
00950 if (forward || backward)
00951 {
00952 kdDebug(125) << "== " << cutWalkThroughWindows.toStringInternal()
00953 << " or " << cutWalkThroughWindowsReverse.toStringInternal() << endl;
00954 KDEWalkThroughWindows( forward );
00955 }
00956 }
00957 else if (control_grab)
00958 {
00959 forward = cutWalkThroughDesktops.contains( keyX ) ||
00960 cutWalkThroughDesktopList.contains( keyX );
00961 backward = cutWalkThroughDesktopsReverse.contains( keyX ) ||
00962 cutWalkThroughDesktopListReverse.contains( keyX );
00963 if (forward || backward)
00964 walkThroughDesktops(forward);
00965 }
00966
00967 if (control_grab || tab_grab)
00968 {
00969 uint keyQt = keyX.keyCodeQt();
00970 if ( ((keyQt & 0xffff) == Qt::Key_Escape)
00971 && !(forward || backward) )
00972 {
00973 closeTabBox();
00974 }
00975 }
00976 }
00977
00978 void Workspace::closeTabBox()
00979 {
00980 removeTabBoxGrab();
00981 tab_box->hide();
00982 keys->setEnabled( true );
00983 tab_grab = FALSE;
00984 control_grab = FALSE;
00985 }
00986
00990 void Workspace::tabBoxKeyRelease( const XKeyEvent& ev )
00991 {
00992 unsigned int mk = ev.state &
00993 (KKeyNative::modX(KKey::SHIFT) |
00994 KKeyNative::modX(KKey::CTRL) |
00995 KKeyNative::modX(KKey::ALT) |
00996 KKeyNative::modX(KKey::WIN));
00997
00998
00999
01000
01001 int mod_index = -1;
01002 for( int i = ShiftMapIndex;
01003 i <= Mod5MapIndex;
01004 ++i )
01005 if(( mk & ( 1 << i )) != 0 )
01006 {
01007 if( mod_index >= 0 )
01008 return;
01009 mod_index = i;
01010 }
01011 bool release = false;
01012 if( mod_index == -1 )
01013 release = true;
01014 else
01015 {
01016 XModifierKeymap* xmk = XGetModifierMapping(qt_xdisplay());
01017 for (int i=0; i<xmk->max_keypermod; i++)
01018 if (xmk->modifiermap[xmk->max_keypermod * mod_index + i]
01019 == ev.keycode)
01020 release = true;
01021 XFreeModifiermap(xmk);
01022 }
01023 if( !release )
01024 return;
01025 if (tab_grab)
01026 {
01027 removeTabBoxGrab();
01028 tab_box->hide();
01029 keys->setEnabled( true );
01030 tab_grab = false;
01031 if( Client* c = tab_box->currentClient())
01032 {
01033 activateClient( c );
01034 if( c->isShade())
01035 c->setShade( ShadeActivated );
01036 }
01037 }
01038 if (control_grab)
01039 {
01040 removeTabBoxGrab();
01041 tab_box->hide();
01042 keys->setEnabled( true );
01043 control_grab = False;
01044 if ( tab_box->currentDesktop() != -1 )
01045 {
01046 setCurrentDesktop( tab_box->currentDesktop() );
01047
01048 }
01049 }
01050 }
01051
01052
01053 int Workspace::nextDesktopFocusChain( int iDesktop ) const
01054 {
01055 int i = desktop_focus_chain.find( iDesktop );
01056 if( i >= 0 && i+1 < (int)desktop_focus_chain.size() )
01057 return desktop_focus_chain[i+1];
01058 else if( desktop_focus_chain.size() > 0 )
01059 return desktop_focus_chain[ 0 ];
01060 else
01061 return 1;
01062 }
01063
01064 int Workspace::previousDesktopFocusChain( int iDesktop ) const
01065 {
01066 int i = desktop_focus_chain.find( iDesktop );
01067 if( i-1 >= 0 )
01068 return desktop_focus_chain[i-1];
01069 else if( desktop_focus_chain.size() > 0 )
01070 return desktop_focus_chain[desktop_focus_chain.size()-1];
01071 else
01072 return numberOfDesktops();
01073 }
01074
01079 Client* Workspace::nextFocusChainClient( Client* c ) const
01080 {
01081 if ( focus_chain.isEmpty() )
01082 return 0;
01083 ClientList::ConstIterator it = focus_chain.find( c );
01084 if ( it == focus_chain.end() )
01085 return focus_chain.last();
01086 if ( it == focus_chain.begin() )
01087 return focus_chain.last();
01088 --it;
01089 return *it;
01090 }
01091
01096 Client* Workspace::previousFocusChainClient( Client* c ) const
01097 {
01098 if ( focus_chain.isEmpty() )
01099 return 0;
01100 ClientList::ConstIterator it = focus_chain.find( c );
01101 if ( it == focus_chain.end() )
01102 return focus_chain.first();
01103 ++it;
01104 if ( it == focus_chain.end() )
01105 return focus_chain.first();
01106 return *it;
01107 }
01108
01113 Client* Workspace::nextStaticClient( Client* c ) const
01114 {
01115 if ( !c || clients.isEmpty() )
01116 return 0;
01117 ClientList::ConstIterator it = clients.find( c );
01118 if ( it == clients.end() )
01119 return clients.first();
01120 ++it;
01121 if ( it == clients.end() )
01122 return clients.first();
01123 return *it;
01124 }
01129 Client* Workspace::previousStaticClient( Client* c ) const
01130 {
01131 if ( !c || clients.isEmpty() )
01132 return 0;
01133 ClientList::ConstIterator it = clients.find( c );
01134 if ( it == clients.end() )
01135 return clients.last();
01136 if ( it == clients.begin() )
01137 return clients.last();
01138 --it;
01139 return *it;
01140 }
01141
01142 bool Workspace::establishTabBoxGrab()
01143 {
01144 if( XGrabKeyboard( qt_xdisplay(), root, FALSE,
01145 GrabModeAsync, GrabModeAsync, qt_x_time) != GrabSuccess )
01146 return false;
01147
01148
01149
01150
01151
01152 assert( !forced_global_mouse_grab );
01153 forced_global_mouse_grab = true;
01154 if( active_client != NULL )
01155 active_client->updateMouseGrab();
01156 return true;
01157 }
01158
01159 void Workspace::removeTabBoxGrab()
01160 {
01161 XUngrabKeyboard(qt_xdisplay(), qt_x_time);
01162 assert( forced_global_mouse_grab );
01163 forced_global_mouse_grab = false;
01164 if( active_client != NULL )
01165 active_client->updateMouseGrab();
01166 }
01167
01168 }
01169
01170 #include "tabbox.moc"