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 : QWidget( 0, name )
00047 {
00048 no_tasks = i18n("*** No Tasks ***");
00049 m = DesktopMode;
00050 wspace = ws;
00051 reconfigure();
00052 reset();
00053 connect(&delayedShowTimer, SIGNAL(timeout()), this, SLOT(show()));
00054 }
00055
00056 TabBox::~TabBox()
00057 {
00058 }
00059
00060
00066 void TabBox::setMode( Mode mode )
00067 {
00068 m = mode;
00069 }
00070
00071
00076 void TabBox::reset()
00077 {
00078 QFont f = font();
00079 f.setBold( TRUE );
00080 f.setPointSize( 14 );
00081 setFont( f );
00082
00083 wmax = 0;
00084
00085 if ( mode() == WindowsMode )
00086 {
00087 client = workspace()->activeClient();
00088 clients.clear();
00089 Client* c = workspace()->nextFocusChainClient( client );
00090 Client* stop = c;
00091 QFontMetrics fm( fontMetrics() );
00092 int cw = fm.width(no_tasks)+20;
00093 while ( c )
00094 {
00095 if ( (options_traverse_all ||c->isOnDesktop(workspace()->currentDesktop()))
00096 && (!c->isMinimized() || !c->isTransient() || c->isUtility()) )
00097 {
00098 if ( client == c )
00099 {
00100 clients.remove( c );
00101 clients.prepend( c );
00102 }
00103 else
00104 {
00105 Client* modal = c->findModal();
00106 if( modal == NULL || modal == c )
00107 clients += c;
00108 else if( !clients.contains( modal ))
00109 clients += modal;
00110 else
00111 ;
00112 }
00113 cw = fm.width( c->caption() ) + 40;
00114 if ( cw > wmax )
00115 wmax = cw;
00116 }
00117 c = workspace()->nextFocusChainClient( c );
00118 if ( c == stop )
00119 break;
00120 }
00121 wmax = QMAX( wmax, int(clients.count())*20 );
00122 }
00123 else
00124 {
00125 desk = workspace()->currentDesktop();
00126 }
00127
00128 QRect r = KGlobalSettings::desktopGeometry(QCursor::pos());
00129
00130 int w = QMIN( QMAX( wmax + 20, r.width()/3 ), r.width() );
00131 setGeometry( (r.width()-w)/2 + r.x(),
00132 r.height()/2-fontMetrics().height()*2-10 + r.y(),
00133 w, fontMetrics().height()*4 + 20 );
00134
00135 wmax = QMIN( wmax, width() - 12 );
00136 }
00137
00138
00142 void TabBox::nextPrev( bool next)
00143 {
00144 if ( mode() == WindowsMode )
00145 {
00146 Client* firstClient = 0;
00147 do
00148 {
00149 if ( next )
00150 client = workspace()->nextFocusChainClient(client);
00151 else
00152 client = workspace()->previousFocusChainClient(client);
00153 if (!firstClient)
00154 {
00155
00156
00157 firstClient = client;
00158 }
00159 else if (client == firstClient)
00160 {
00161
00162 client = 0;
00163 break;
00164 }
00165 } while ( client && !clients.contains( client ));
00166 }
00167 else if( mode() == DesktopMode )
00168 {
00169 if ( next )
00170 desk = workspace()->nextDesktopFocusChain( desk );
00171 else
00172 desk = workspace()->previousDesktopFocusChain( desk );
00173 }
00174 else
00175 {
00176 if ( next )
00177 {
00178 desk++;
00179 if ( desk > workspace()->numberOfDesktops() )
00180 desk = 1;
00181 }
00182 else
00183 {
00184 desk--;
00185 if ( desk < 1 )
00186 desk = workspace()->numberOfDesktops();
00187 }
00188 }
00189
00190 paintContents();
00191 }
00192
00193
00194
00199 Client* TabBox::currentClient()
00200 {
00201 if ( mode() != WindowsMode )
00202 return 0;
00203 if (!workspace()->hasClient( client ))
00204 return 0;
00205 return client;
00206 }
00207
00213 int TabBox::currentDesktop()
00214 {
00215 if ( mode() == DesktopListMode || mode() == DesktopMode )
00216 return desk;
00217 else
00218 return -1;
00219 }
00220
00221
00225 void TabBox::showEvent( QShowEvent* )
00226 {
00227 raise();
00228 }
00229
00230
00234 void TabBox::hideEvent( QHideEvent* )
00235 {
00236 }
00237
00238
00242 void TabBox::paintEvent( QPaintEvent* )
00243 {
00244 {
00245 QPainter p( this );
00246 style().drawPrimitive( QStyle::PE_Panel, &p, QRect( 0, 0, width(), height() ),
00247 colorGroup(), QStyle::Style_Default );
00248 style().drawPrimitive( QStyle::PE_Panel, &p, QRect( 4, 4, width()-8, height()-8 ),
00249 colorGroup(), QStyle::Style_Sunken );
00250 }
00251 paintContents();
00252 }
00253
00254
00259 void TabBox::paintContents()
00260 {
00261 QPixmap* menu_pix = kwin_get_menu_pix_hack();
00262 QPainter p( this );
00263 QRect r( 6, 6, width()-12, height()-32 );
00264 p.fillRect( r, colorGroup().brush( QColorGroup::Background ) );
00265 if ( mode () == WindowsMode )
00266 {
00267 if ( currentClient() )
00268 {
00269 int textw, maxlen = client->caption().length();
00270 int icon = client->icon().isNull() ? 0 : 42;
00271 QString s;
00272 do
00273 {
00274 s = QString();
00275 if (!client->isOnDesktop(workspace()->currentDesktop()))
00276 {
00277 s.append(": ");
00278 }
00279
00280 if (client->isMinimized())
00281 s += QString("(")+KStringHandler::csqueeze(client->caption(), maxlen)+")";
00282 else
00283 s += KStringHandler::csqueeze(client->caption(), maxlen);
00284 textw = fontMetrics().width( s );
00285 maxlen--;
00286 } while (textw > r.width() - icon);
00287 r.setLeft( r.left() + (r.width() - textw)/2);
00288
00289 if ( icon )
00290 {
00291 int py = r.center().y() - 16;
00292 r.setLeft( r.left() + 20 );
00293 if( client->icon().mask() != NULL )
00294 p.fillRect( r.left()-42, py, client->icon().width(), client->icon().height(),
00295 colorGroup().brush( QColorGroup::Background ));
00296 p.drawPixmap( r.left()-42, py, client->icon() );
00297 }
00298
00299 p.drawText( r, AlignVCenter, s );
00300
00301 }
00302 else
00303 {
00304 r.setBottom( r.bottom() + 20 );
00305 p.drawText( r, AlignCenter, no_tasks);
00306 }
00307
00308 int x = (width() - clients.count() * 20 )/2;
00309 int y = height() - 26;
00310 for ( ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
00311 {
00312 if ( workspace()->hasClient( *it ) )
00313 {
00314 if ( !(*it)->miniIcon().isNull() )
00315 {
00316 if( (*it)->miniIcon().mask() != NULL )
00317 p.fillRect( x, y, 16, 16, colorGroup().brush( QColorGroup::Background ));
00318 p.drawPixmap( x, y, (*it)->miniIcon() );
00319 }
00320 else if ( menu_pix )
00321 {
00322 if( menu_pix->mask() != NULL )
00323 p.fillRect( x, y, 16, 16, colorGroup().brush( QColorGroup::Background ));
00324 p.drawPixmap( x, y, *menu_pix );
00325 }
00326 p.setPen( (*it)==currentClient()?
00327 colorGroup().highlight():colorGroup().background() );
00328 p.drawRect( x-2, y-2, 20, 20 );
00329 p.setPen( colorGroup().foreground() );
00330 x += 20;
00331 }
00332 }
00333 }
00334 else
00335 {
00336 p.drawText( r, AlignCenter, workspace()->desktopName(desk) );
00337 int x = (width() - workspace()->numberOfDesktops() * 20 )/2;
00338 int y = height() - 26;
00339 QFont f( font() );
00340 f.setPointSize( 12 );
00341 f.setBold( FALSE );
00342 p.setFont(f );
00343
00344
00345
00346 int iDesktop = (mode() == DesktopMode) ? workspace()->currentDesktop() : 1;
00347 for ( int i = 1; i <= workspace()->numberOfDesktops(); i++ )
00348 {
00349 p.setPen( iDesktop == desk?
00350 colorGroup().highlight():colorGroup().background() );
00351 p.drawRect( x-2, y-2, 20, 20 );
00352 qDrawWinPanel( &p, QRect( x, y, 16, 16), colorGroup(), FALSE,
00353 &colorGroup().brush(QColorGroup::Base ) );
00354 p.setPen( colorGroup().text() );
00355 p.drawText( x, y, 16, 16, AlignCenter, QString::number(iDesktop) );
00356 x += 20;
00357
00358 if( mode() == DesktopMode )
00359 iDesktop = workspace()->nextDesktopFocusChain( iDesktop );
00360 else
00361 iDesktop++;
00362 }
00363 }
00364 }
00365
00366 void TabBox::hide()
00367 {
00368 delayedShowTimer.stop();
00369 QWidget::hide();
00370 QApplication::syncX();
00371 XEvent otherEvent;
00372 while (XCheckTypedEvent (qt_xdisplay(), EnterNotify, &otherEvent ) )
00373 ;
00374 }
00375
00376
00377 void TabBox::reconfigure()
00378 {
00379 KConfig * c(KGlobal::config());
00380 c->setGroup("TabBox");
00381 options_traverse_all = c->readNumEntry("TraverseAll", false );
00382 }
00383
00402 void TabBox::delayedShow()
00403 {
00404 KConfig * c(KGlobal::config());
00405 c->setGroup("TabBox");
00406 bool delay = c->readNumEntry("ShowDelay", true);
00407
00408 if (!delay)
00409 {
00410 show();
00411 return;
00412 }
00413
00414 int delayTime = c->readNumEntry("DelayTime", 90);
00415 delayedShowTimer.start(delayTime, true);
00416 }
00417
00418
00419 void TabBox::handleMouseEvent( XEvent* e )
00420 {
00421 XAllowEvents( qt_xdisplay(), AsyncPointer, qt_x_time );
00422 if( e->type != ButtonPress )
00423 return;
00424 QPoint pos( e->xbutton.x_root, e->xbutton.y_root );
00425 if( !geometry().contains( pos ))
00426 return;
00427 pos.rx() -= x();
00428 pos.ry() -= y();
00429 if( mode() == WindowsMode )
00430 {
00431 int x = (width() - clients.count() * 20 )/2;
00432 int y = height() - 26;
00433 if( pos.x() < x || pos.y() < y - 2 || pos.y() > y - 2 + 20 )
00434 return;
00435 for( ClientList::ConstIterator it = clients.begin();
00436 it != clients.end();
00437 ++it)
00438 {
00439 if( workspace()->hasClient( *it )
00440 && pos.x() < x + 20 )
00441 {
00442 client = *it;
00443 break;
00444 }
00445 x += 20;
00446 }
00447 }
00448 else
00449 {
00450 int x = (width() - workspace()->numberOfDesktops() * 20 )/2;
00451 int y = height() - 26;
00452 if( pos.x() < x || pos.y() < y - 2 || pos.y() > y - 2 + 20 )
00453 return;
00454 int iDesktop = (mode() == DesktopMode) ? workspace()->currentDesktop() : 1;
00455 for( int i = 1;
00456 i <= workspace()->numberOfDesktops();
00457 ++i )
00458 {
00459 if( pos.x() < x + 20 )
00460 {
00461 desk = iDesktop;
00462 break;
00463 }
00464 x += 20;
00465 if( mode() == DesktopMode )
00466 iDesktop = workspace()->nextDesktopFocusChain( iDesktop );
00467 else
00468 iDesktop++;
00469 }
00470 }
00471 paintContents();
00472 }
00473
00474
00475
00476
00477
00478
00483 static
00484 bool areKeySymXsDepressed( bool bAll, int nKeySyms, ... )
00485 {
00486 va_list args;
00487 char keymap[32];
00488
00489 kdDebug(125) << "areKeySymXsDepressed: " << (bAll ? "all of " : "any of ") << nKeySyms << endl;
00490
00491 va_start( args, nKeySyms );
00492 XQueryKeymap( qt_xdisplay(), keymap );
00493
00494 for( int iKeySym = 0; iKeySym < nKeySyms; iKeySym++ )
00495 {
00496 uint keySymX = va_arg( args, uint );
00497 uchar keyCodeX = XKeysymToKeycode( qt_xdisplay(), keySymX );
00498 int i = keyCodeX / 8;
00499 char mask = 1 << (keyCodeX - (i * 8));
00500
00501 kdDebug(125) << iKeySym << ": keySymX=0x" << QString::number( keySymX, 16 )
00502 << " i=" << i << " mask=0x" << QString::number( mask, 16 )
00503 << " keymap[i]=0x" << QString::number( keymap[i], 16 ) << endl;
00504
00505
00506 if( i < 0 || i >= 32 )
00507 return false;
00508
00509
00510 if( bAll )
00511 {
00512 if( (keymap[i] & mask) == 0 )
00513 return false;
00514 }
00515 else
00516 {
00517
00518 if( keymap[i] & mask )
00519 return true;
00520 }
00521 }
00522
00523
00524
00525 return bAll;
00526 }
00527
00528 static
00529 bool areModKeysDepressed( const KShortcut& cut )
00530 {
00531
00532 uint rgKeySyms[10];
00533 int nKeySyms = 0;
00534 int mod = cut.seq(0).key(0).modFlags();
00535
00536 if ( mod & KKey::SHIFT )
00537 {
00538 rgKeySyms[nKeySyms++] = XK_Shift_L;
00539 rgKeySyms[nKeySyms++] = XK_Shift_R;
00540 }
00541 if ( mod & KKey::CTRL )
00542 {
00543 rgKeySyms[nKeySyms++] = XK_Control_L;
00544 rgKeySyms[nKeySyms++] = XK_Control_R;
00545 }
00546 if( mod & KKey::ALT )
00547 {
00548 rgKeySyms[nKeySyms++] = XK_Alt_L;
00549 rgKeySyms[nKeySyms++] = XK_Alt_R;
00550 }
00551 if( mod & KKey::WIN )
00552 {
00553
00554
00555 rgKeySyms[nKeySyms++] = XK_Super_L;
00556 rgKeySyms[nKeySyms++] = XK_Super_R;
00557 rgKeySyms[nKeySyms++] = XK_Meta_L;
00558 rgKeySyms[nKeySyms++] = XK_Meta_R;
00559 }
00560
00561
00562 return areKeySymXsDepressed( false, nKeySyms,
00563 rgKeySyms[0], rgKeySyms[1], rgKeySyms[2], rgKeySyms[3],
00564 rgKeySyms[4], rgKeySyms[5], rgKeySyms[6], rgKeySyms[7] );
00565 }
00566
00567 void Workspace::slotWalkThroughWindows()
00568 {
00569 if ( root != qt_xrootwin() )
00570 return;
00571 if ( tab_grab || control_grab )
00572 return;
00573 if ( options->altTabStyle == Options::CDE || !options->focusPolicyIsReasonable() )
00574 {
00575
00576
00577 CDEWalkThroughWindows( true );
00578 }
00579 else
00580 {
00581 if ( areModKeysDepressed( cutWalkThroughWindows ) )
00582 {
00583 if ( startKDEWalkThroughWindows() )
00584 KDEWalkThroughWindows( true );
00585 }
00586 else
00587
00588
00589
00590
00591 CDEWalkThroughWindows( true );
00592 }
00593 }
00594
00595 void Workspace::slotWalkBackThroughWindows()
00596 {
00597 if ( root != qt_xrootwin() )
00598 return;
00599 if( tab_grab || control_grab )
00600 return;
00601 if ( options->altTabStyle == Options::CDE || !options->focusPolicyIsReasonable() )
00602 {
00603
00604 CDEWalkThroughWindows( false );
00605 }
00606 else
00607 {
00608 if ( areModKeysDepressed( cutWalkThroughWindowsReverse ) )
00609 {
00610 if ( startKDEWalkThroughWindows() )
00611 KDEWalkThroughWindows( false );
00612 }
00613 else
00614 {
00615 CDEWalkThroughWindows( false );
00616 }
00617 }
00618 }
00619
00620 void Workspace::slotWalkThroughDesktops()
00621 {
00622 if ( root != qt_xrootwin() )
00623 return;
00624 if( tab_grab || control_grab )
00625 return;
00626 if ( areModKeysDepressed( cutWalkThroughDesktops ) )
00627 {
00628 if ( startWalkThroughDesktops() )
00629 walkThroughDesktops( true );
00630 }
00631 else
00632 {
00633 oneStepThroughDesktops( true );
00634 }
00635 }
00636
00637 void Workspace::slotWalkBackThroughDesktops()
00638 {
00639 if ( root != qt_xrootwin() )
00640 return;
00641 if( tab_grab || control_grab )
00642 return;
00643 if ( areModKeysDepressed( cutWalkThroughDesktopsReverse ) )
00644 {
00645 if ( startWalkThroughDesktops() )
00646 walkThroughDesktops( false );
00647 }
00648 else
00649 {
00650 oneStepThroughDesktops( false );
00651 }
00652 }
00653
00654 void Workspace::slotWalkThroughDesktopList()
00655 {
00656 if ( root != qt_xrootwin() )
00657 return;
00658 if( tab_grab || control_grab )
00659 return;
00660 if ( areModKeysDepressed( cutWalkThroughDesktopList ) )
00661 {
00662 if ( startWalkThroughDesktopList() )
00663 walkThroughDesktops( true );
00664 }
00665 else
00666 {
00667 oneStepThroughDesktopList( true );
00668 }
00669 }
00670
00671 void Workspace::slotWalkBackThroughDesktopList()
00672 {
00673 if ( root != qt_xrootwin() )
00674 return;
00675 if( tab_grab || control_grab )
00676 return;
00677 if ( areModKeysDepressed( cutWalkThroughDesktopListReverse ) )
00678 {
00679 if ( startWalkThroughDesktopList() )
00680 walkThroughDesktops( false );
00681 }
00682 else
00683 {
00684 oneStepThroughDesktopList( false );
00685 }
00686 }
00687
00688 bool Workspace::startKDEWalkThroughWindows()
00689 {
00690 if ( XGrabKeyboard(qt_xdisplay(),
00691 root, FALSE,
00692 GrabModeAsync, GrabModeAsync,
00693 qt_x_time) != GrabSuccess )
00694 {
00695 return FALSE;
00696 }
00697 tab_grab = TRUE;
00698 keys->setEnabled( false );
00699 tab_box->setMode( TabBox::WindowsMode );
00700 tab_box->reset();
00701 return TRUE;
00702 }
00703
00704 bool Workspace::startWalkThroughDesktops( int mode )
00705 {
00706 if ( XGrabKeyboard(qt_xdisplay(),
00707 root, FALSE,
00708 GrabModeAsync, GrabModeAsync,
00709 qt_x_time) != GrabSuccess )
00710 {
00711 return FALSE;
00712 }
00713 control_grab = TRUE;
00714 keys->setEnabled( false );
00715 tab_box->setMode( (TabBox::Mode) mode );
00716 tab_box->reset();
00717 return TRUE;
00718 }
00719
00720 bool Workspace::startWalkThroughDesktops()
00721 {
00722 return startWalkThroughDesktops( TabBox::DesktopMode );
00723 }
00724
00725 bool Workspace::startWalkThroughDesktopList()
00726 {
00727 return startWalkThroughDesktops( TabBox::DesktopListMode );
00728 }
00729
00730 void Workspace::KDEWalkThroughWindows( bool forward )
00731 {
00732 tab_box->nextPrev( forward );
00733 tab_box->delayedShow();
00734 }
00735
00736 void Workspace::walkThroughDesktops( bool forward )
00737 {
00738 tab_box->nextPrev( forward );
00739 tab_box->delayedShow();
00740 }
00741
00742 void Workspace::CDEWalkThroughWindows( bool forward )
00743 {
00744 Client* c = topClientOnDesktop( currentDesktop());
00745 Client* nc = c;
00746 bool options_traverse_all;
00747 {
00748 KConfigGroupSaver saver( KGlobal::config(), "TabBox" );
00749 options_traverse_all = KGlobal::config()->readNumEntry("TraverseAll", false );
00750 }
00751
00752 if ( !forward )
00753 {
00754 do
00755 {
00756 nc = previousStaticClient(nc);
00757 } while (nc && nc != c &&
00758 (( !options_traverse_all && !nc->isOnDesktop(currentDesktop())) ||
00759 nc->isMinimized() || !nc->wantsTabFocus() ) );
00760 }
00761 else
00762 {
00763 do
00764 {
00765 nc = nextStaticClient(nc);
00766 } while (nc && nc != c &&
00767 (( !options_traverse_all && !nc->isOnDesktop(currentDesktop())) ||
00768 nc->isMinimized() || !nc->wantsTabFocus() ) );
00769 }
00770 if (c && c != nc)
00771 lowerClient( c );
00772 if (nc)
00773 {
00774 if ( options->focusPolicyIsReasonable() )
00775 {
00776 activateClient( nc );
00777 if( nc->isShade())
00778 nc->setShade( Client::ShadeActivated );
00779 }
00780 else
00781 {
00782 if( !nc->isOnDesktop( currentDesktop()))
00783 setCurrentDesktop( nc->desktop());
00784 raiseClient( nc );
00785 }
00786 }
00787 }
00788
00789 void Workspace::KDEOneStepThroughWindows( bool forward )
00790 {
00791 tab_box->setMode( TabBox::WindowsMode );
00792 tab_box->reset();
00793 tab_box->nextPrev( forward );
00794 if( Client* c = tab_box->currentClient() )
00795 {
00796 activateClient( c );
00797 if( c->isShade())
00798 c->setShade( Client::ShadeActivated );
00799 }
00800 }
00801
00802 void Workspace::oneStepThroughDesktops( bool forward, int mode )
00803 {
00804 tab_box->setMode( (TabBox::Mode) mode );
00805 tab_box->reset();
00806 tab_box->nextPrev( forward );
00807 if ( tab_box->currentDesktop() != -1 )
00808 setCurrentDesktop( tab_box->currentDesktop() );
00809 }
00810
00811 void Workspace::oneStepThroughDesktops( bool forward )
00812 {
00813 oneStepThroughDesktops( forward, TabBox::DesktopMode );
00814 }
00815
00816 void Workspace::oneStepThroughDesktopList( bool forward )
00817 {
00818 oneStepThroughDesktops( forward, TabBox::DesktopListMode );
00819 }
00820
00824 void Workspace::tabBoxKeyPress( const KKeyNative& keyX )
00825 {
00826 bool forward = false;
00827 bool backward = false;
00828
00829 if (tab_grab)
00830 {
00831 forward = cutWalkThroughWindows.contains( keyX );
00832 backward = cutWalkThroughWindowsReverse.contains( keyX );
00833 if (forward || backward)
00834 {
00835 kdDebug(125) << "== " << cutWalkThroughWindows.toStringInternal()
00836 << " or " << cutWalkThroughWindowsReverse.toStringInternal() << endl;
00837 KDEWalkThroughWindows( forward );
00838 }
00839 }
00840 else if (control_grab)
00841 {
00842 forward = cutWalkThroughDesktops.contains( keyX ) ||
00843 cutWalkThroughDesktopList.contains( keyX );
00844 backward = cutWalkThroughDesktopsReverse.contains( keyX ) ||
00845 cutWalkThroughDesktopListReverse.contains( keyX );
00846 if (forward || backward)
00847 walkThroughDesktops(forward);
00848 }
00849
00850 if (control_grab || tab_grab)
00851 {
00852 uint keyQt = keyX.keyCodeQt();
00853 if ( ((keyQt & 0xffff) == Qt::Key_Escape)
00854 && !(forward || backward) )
00855 {
00856 XUngrabKeyboard(qt_xdisplay(), qt_x_time);
00857 tab_box->hide();
00858 keys->setEnabled( true );
00859 tab_grab = FALSE;
00860 control_grab = FALSE;
00861 }
00862 }
00863 }
00864
00868 void Workspace::tabBoxKeyRelease( const XKeyEvent& ev )
00869 {
00870 unsigned int mk = ev.state &
00871 (KKeyNative::modX(KKey::SHIFT) |
00872 KKeyNative::modX(KKey::CTRL) |
00873 KKeyNative::modX(KKey::ALT) |
00874 KKeyNative::modX(KKey::WIN));
00875
00876
00877
00878
00879 int mod_index = -1;
00880 for( int i = ShiftMapIndex;
00881 i <= Mod5MapIndex;
00882 ++i )
00883 if(( mk & ( 1 << i )) != 0 )
00884 {
00885 if( mod_index >= 0 )
00886 return;
00887 mod_index = i;
00888 }
00889 bool release = false;
00890 if( mod_index == -1 )
00891 release = true;
00892 else
00893 {
00894 XModifierKeymap* xmk = XGetModifierMapping(qt_xdisplay());
00895 for (int i=0; i<xmk->max_keypermod; i++)
00896 if (xmk->modifiermap[xmk->max_keypermod * mod_index + i]
00897 == ev.keycode)
00898 release = true;
00899 XFreeModifiermap(xmk);
00900 }
00901 if( !release )
00902 return;
00903 if (tab_grab)
00904 {
00905 XUngrabKeyboard(qt_xdisplay(), qt_x_time);
00906 tab_box->hide();
00907 keys->setEnabled( true );
00908 tab_grab = false;
00909 if( Client* c = tab_box->currentClient())
00910 {
00911 activateClient( c );
00912 if( c->isShade())
00913 c->setShade( Client::ShadeActivated );
00914 }
00915 }
00916 if (control_grab)
00917 {
00918 XUngrabKeyboard(qt_xdisplay(), qt_x_time);
00919 tab_box->hide();
00920 keys->setEnabled( true );
00921 control_grab = False;
00922 if ( tab_box->currentDesktop() != -1 )
00923 {
00924 setCurrentDesktop( tab_box->currentDesktop() );
00925
00926 }
00927 }
00928 }
00929
00930
00931 int Workspace::nextDesktopFocusChain( int iDesktop ) const
00932 {
00933 int i = desktop_focus_chain.find( iDesktop );
00934 if( i >= 0 && i+1 < (int)desktop_focus_chain.size() )
00935 return desktop_focus_chain[i+1];
00936 else if( desktop_focus_chain.size() > 0 )
00937 return desktop_focus_chain[ 0 ];
00938 else
00939 return 1;
00940 }
00941
00942 int Workspace::previousDesktopFocusChain( int iDesktop ) const
00943 {
00944 int i = desktop_focus_chain.find( iDesktop );
00945 if( i-1 >= 0 )
00946 return desktop_focus_chain[i-1];
00947 else if( desktop_focus_chain.size() > 0 )
00948 return desktop_focus_chain[desktop_focus_chain.size()-1];
00949 else
00950 return numberOfDesktops();
00951 }
00952
00957 Client* Workspace::nextFocusChainClient( Client* c ) const
00958 {
00959 if ( focus_chain.isEmpty() )
00960 return 0;
00961 ClientList::ConstIterator it = focus_chain.find( c );
00962 if ( it == focus_chain.end() )
00963 return focus_chain.last();
00964 if ( it == focus_chain.begin() )
00965 return focus_chain.last();
00966 --it;
00967 return *it;
00968 }
00969
00974 Client* Workspace::previousFocusChainClient( Client* c ) const
00975 {
00976 if ( focus_chain.isEmpty() )
00977 return 0;
00978 ClientList::ConstIterator it = focus_chain.find( c );
00979 if ( it == focus_chain.end() )
00980 return focus_chain.first();
00981 ++it;
00982 if ( it == focus_chain.end() )
00983 return focus_chain.first();
00984 return *it;
00985 }
00986
00991 Client* Workspace::nextStaticClient( Client* c ) const
00992 {
00993 if ( !c || clients.isEmpty() )
00994 return 0;
00995 ClientList::ConstIterator it = clients.find( c );
00996 if ( it == clients.end() )
00997 return clients.first();
00998 ++it;
00999 if ( it == clients.end() )
01000 return clients.first();
01001 return *it;
01002 }
01007 Client* Workspace::previousStaticClient( Client* c ) const
01008 {
01009 if ( !c || clients.isEmpty() )
01010 return 0;
01011 ClientList::ConstIterator it = clients.find( c );
01012 if ( it == clients.end() )
01013 return clients.last();
01014 if ( it == clients.begin() )
01015 return clients.last();
01016 --it;
01017 return *it;
01018 }
01019
01020
01021 }
01022
01023 #include "tabbox.moc"