kwin Library API Documentation

tabbox.cpp

00001 /***************************************************************** 00002 KWin - the KDE window manager 00003 This file is part of the KDE project. 00004 00005 Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org> 00006 Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org> 00007 00008 You can Freely distribute this program under the GNU General Public 00009 License. See the file "COPYING" for the exact licensing terms. 00010 ******************************************************************/ 00011 00012 //#define QT_CLEAN_NAMESPACE 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 // specify externals before namespace 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; // init variables 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 { // don't add windows that have modal dialogs 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 ; // nothing 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 { // DesktopListMode 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 // When we see our first client for the second time, 00156 // it's time to stop. 00157 firstClient = client; 00158 } 00159 else if (client == firstClient) 00160 { 00161 // No candidates found. 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 { // DesktopListMode 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 { // safety 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 { // DesktopMode || DesktopListMode 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 // In DesktopMode, start at the current desktop 00345 // In DesktopListMode, start at desktop #1 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(); // pos is now inside tabbox 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 ) // safety 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 // Workspace 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 // Abort if bad index value, 00506 if( i < 0 || i >= 32 ) 00507 return false; 00508 00509 // If ALL keys passed need to be depressed, 00510 if( bAll ) 00511 { 00512 if( (keymap[i] & mask) == 0 ) 00513 return false; 00514 } 00515 else 00516 { 00517 // If we are looking for ANY key press, and this key is depressed, 00518 if( keymap[i] & mask ) 00519 return true; 00520 } 00521 } 00522 00523 // If we were looking for ANY key press, then none was found, return false, 00524 // If we were looking for ALL key presses, then all were found, return true. 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 // HACK: it would take a lot of code to determine whether the Win key 00554 // is associated with Super or Meta, so check for both 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 // Is there a better way to push all 8 integer onto the stack? 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 //XUngrabKeyboard(qt_xdisplay(), qt_x_time); // need that because of accelerator raw mode 00576 // CDE style raise / lower 00577 CDEWalkThroughWindows( true ); 00578 } 00579 else 00580 { 00581 if ( areModKeysDepressed( cutWalkThroughWindows ) ) 00582 { 00583 if ( startKDEWalkThroughWindows() ) 00584 KDEWalkThroughWindows( true ); 00585 } 00586 else 00587 // if the shortcut has no modifiers, don't show the tabbox, 00588 // don't grab, but simply go to the next window 00589 // use the CDE style, because with KDE style it would cycle 00590 // between the active and previously active window 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 // CDE style raise / lower 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 { // if Escape is part of the shortcut, don't cancel 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 // ev.state is state before the key release, so just checking mk being 0 isn't enough 00876 // using XQueryPointer() also doesn't seem to work well, so the check that all 00877 // modifiers are released: only one modifier is active and the currently released 00878 // key is this modifier - if yes, release the grab 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 // popupinfo->showInfo( desktopName(currentDesktop()) ); // AK - not sure 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 } // namespace 01022 01023 #include "tabbox.moc"
KDE Logo
This file is part of the documentation for kwin Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Sep 16 15:59:32 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003