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->isMinimized() || !c->isTransient() || c->isUtility()) && 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
00644
bool areModKeysDepressed(
const KShortcut& cut )
00645 {
00646
00647 uint rgKeySyms[10];
00648
int nKeySyms = 0;
00649
int mod = cut.seq(0).key(0).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
void Workspace::slotWalkThroughWindows()
00683 {
00684
if ( root != qt_xrootwin() )
00685
return;
00686
if ( tab_grab || control_grab )
00687
return;
00688
if ( options->altTabStyle == Options::CDE || !options->focusPolicyIsReasonable() )
00689 {
00690
00691
00692 CDEWalkThroughWindows(
true );
00693 }
00694
else
00695 {
00696
if ( areModKeysDepressed( cutWalkThroughWindows ) )
00697 {
00698
if ( startKDEWalkThroughWindows() )
00699 KDEWalkThroughWindows(
true );
00700 }
00701
else
00702
00703
00704
00705
00706 CDEWalkThroughWindows(
true );
00707 }
00708 }
00709
00710
void Workspace::slotWalkBackThroughWindows()
00711 {
00712
if ( root != qt_xrootwin() )
00713
return;
00714
if( tab_grab || control_grab )
00715
return;
00716
if ( options->altTabStyle == Options::CDE || !options->focusPolicyIsReasonable() )
00717 {
00718
00719 CDEWalkThroughWindows(
false );
00720 }
00721
else
00722 {
00723
if ( areModKeysDepressed( cutWalkThroughWindowsReverse ) )
00724 {
00725
if ( startKDEWalkThroughWindows() )
00726 KDEWalkThroughWindows(
false );
00727 }
00728
else
00729 {
00730 CDEWalkThroughWindows(
false );
00731 }
00732 }
00733 }
00734
00735
void Workspace::slotWalkThroughDesktops()
00736 {
00737
if ( root != qt_xrootwin() )
00738
return;
00739
if( tab_grab || control_grab )
00740
return;
00741
if ( areModKeysDepressed( cutWalkThroughDesktops ) )
00742 {
00743
if ( startWalkThroughDesktops() )
00744 walkThroughDesktops(
true );
00745 }
00746
else
00747 {
00748 oneStepThroughDesktops(
true );
00749 }
00750 }
00751
00752
void Workspace::slotWalkBackThroughDesktops()
00753 {
00754
if ( root != qt_xrootwin() )
00755
return;
00756
if( tab_grab || control_grab )
00757
return;
00758
if ( areModKeysDepressed( cutWalkThroughDesktopsReverse ) )
00759 {
00760
if ( startWalkThroughDesktops() )
00761 walkThroughDesktops(
false );
00762 }
00763
else
00764 {
00765 oneStepThroughDesktops(
false );
00766 }
00767 }
00768
00769
void Workspace::slotWalkThroughDesktopList()
00770 {
00771
if ( root != qt_xrootwin() )
00772
return;
00773
if( tab_grab || control_grab )
00774
return;
00775
if ( areModKeysDepressed( cutWalkThroughDesktopList ) )
00776 {
00777
if ( startWalkThroughDesktopList() )
00778 walkThroughDesktops(
true );
00779 }
00780
else
00781 {
00782 oneStepThroughDesktopList(
true );
00783 }
00784 }
00785
00786
void Workspace::slotWalkBackThroughDesktopList()
00787 {
00788
if ( root != qt_xrootwin() )
00789
return;
00790
if( tab_grab || control_grab )
00791
return;
00792
if ( areModKeysDepressed( cutWalkThroughDesktopListReverse ) )
00793 {
00794
if ( startWalkThroughDesktopList() )
00795 walkThroughDesktops(
false );
00796 }
00797
else
00798 {
00799 oneStepThroughDesktopList(
false );
00800 }
00801 }
00802
00803
bool Workspace::startKDEWalkThroughWindows()
00804 {
00805
if( !establishTabBoxGrab())
00806
return false;
00807 tab_grab = TRUE;
00808 keys->setEnabled(
false );
00809 tab_box->setMode( TabBox::WindowsMode );
00810 tab_box->reset();
00811
return TRUE;
00812 }
00813
00814
bool Workspace::startWalkThroughDesktops(
int mode )
00815 {
00816
if( !establishTabBoxGrab())
00817
return false;
00818 control_grab = TRUE;
00819 keys->setEnabled(
false );
00820 tab_box->setMode( (TabBox::Mode) mode );
00821 tab_box->reset();
00822
return TRUE;
00823 }
00824
00825
bool Workspace::startWalkThroughDesktops()
00826 {
00827
return startWalkThroughDesktops( TabBox::DesktopMode );
00828 }
00829
00830
bool Workspace::startWalkThroughDesktopList()
00831 {
00832
return startWalkThroughDesktops( TabBox::DesktopListMode );
00833 }
00834
00835
void Workspace::KDEWalkThroughWindows(
bool forward )
00836 {
00837 tab_box->nextPrev( forward );
00838 tab_box->delayedShow();
00839 }
00840
00841
void Workspace::walkThroughDesktops(
bool forward )
00842 {
00843 tab_box->nextPrev( forward );
00844 tab_box->delayedShow();
00845 }
00846
00847
void Workspace::CDEWalkThroughWindows(
bool forward )
00848 {
00849
Client* c = topClientOnDesktop( currentDesktop());
00850
Client* nc = c;
00851
bool options_traverse_all;
00852 {
00853 KConfigGroupSaver saver( KGlobal::config(),
"TabBox" );
00854 options_traverse_all = KGlobal::config()->readNumEntry(
"TraverseAll",
false );
00855 }
00856
00857
if ( !forward )
00858 {
00859
do
00860 {
00861 nc = previousStaticClient(nc);
00862 }
while (nc && nc != c &&
00863 (( !options_traverse_all && !nc->isOnDesktop(currentDesktop())) ||
00864 nc->isMinimized() || !nc->wantsTabFocus() ) );
00865 }
00866
else
00867 {
00868
do
00869 {
00870 nc = nextStaticClient(nc);
00871 }
while (nc && nc != c &&
00872 (( !options_traverse_all && !nc->isOnDesktop(currentDesktop())) ||
00873 nc->isMinimized() || !nc->wantsTabFocus() ) );
00874 }
00875
if (c && c != nc)
00876 lowerClient( c );
00877
if (nc)
00878 {
00879
if ( options->focusPolicyIsReasonable() )
00880 {
00881 activateClient( nc );
00882
if( nc->isShade())
00883 nc->setShade( ShadeActivated );
00884 }
00885
else
00886 {
00887
if( !nc->isOnDesktop( currentDesktop()))
00888 setCurrentDesktop( nc->desktop());
00889 raiseClient( nc );
00890 }
00891 }
00892 }
00893
00894
void Workspace::KDEOneStepThroughWindows(
bool forward )
00895 {
00896 tab_box->setMode( TabBox::WindowsMode );
00897 tab_box->reset();
00898 tab_box->nextPrev( forward );
00899
if(
Client* c = tab_box->currentClient() )
00900 {
00901 activateClient( c );
00902
if( c->isShade())
00903 c->setShade( ShadeActivated );
00904 }
00905 }
00906
00907
void Workspace::oneStepThroughDesktops(
bool forward,
int mode )
00908 {
00909 tab_box->setMode( (TabBox::Mode) mode );
00910 tab_box->reset();
00911 tab_box->nextPrev( forward );
00912
if ( tab_box->currentDesktop() != -1 )
00913 setCurrentDesktop( tab_box->currentDesktop() );
00914 }
00915
00916
void Workspace::oneStepThroughDesktops(
bool forward )
00917 {
00918 oneStepThroughDesktops( forward, TabBox::DesktopMode );
00919 }
00920
00921
void Workspace::oneStepThroughDesktopList(
bool forward )
00922 {
00923 oneStepThroughDesktops( forward, TabBox::DesktopListMode );
00924 }
00925
00929
void Workspace::tabBoxKeyPress(
const KKeyNative& keyX )
00930 {
00931
bool forward =
false;
00932
bool backward =
false;
00933
00934
if (tab_grab)
00935 {
00936 forward = cutWalkThroughWindows.contains( keyX );
00937 backward = cutWalkThroughWindowsReverse.contains( keyX );
00938
if (forward || backward)
00939 {
00940 kdDebug(125) <<
"== " << cutWalkThroughWindows.toStringInternal()
00941 <<
" or " << cutWalkThroughWindowsReverse.toStringInternal() << endl;
00942 KDEWalkThroughWindows( forward );
00943 }
00944 }
00945
else if (control_grab)
00946 {
00947 forward = cutWalkThroughDesktops.contains( keyX ) ||
00948 cutWalkThroughDesktopList.contains( keyX );
00949 backward = cutWalkThroughDesktopsReverse.contains( keyX ) ||
00950 cutWalkThroughDesktopListReverse.contains( keyX );
00951
if (forward || backward)
00952 walkThroughDesktops(forward);
00953 }
00954
00955
if (control_grab || tab_grab)
00956 {
00957 uint keyQt = keyX.keyCodeQt();
00958
if ( ((keyQt & 0xffff) == Qt::Key_Escape)
00959 && !(forward || backward) )
00960 {
00961 closeTabBox();
00962 }
00963 }
00964 }
00965
00966
void Workspace::closeTabBox()
00967 {
00968 removeTabBoxGrab();
00969 tab_box->hide();
00970 keys->setEnabled(
true );
00971 tab_grab = FALSE;
00972 control_grab = FALSE;
00973 }
00974
00978
void Workspace::tabBoxKeyRelease(
const XKeyEvent& ev )
00979 {
00980
unsigned int mk = ev.state &
00981 (KKeyNative::modX(KKey::SHIFT) |
00982 KKeyNative::modX(KKey::CTRL) |
00983 KKeyNative::modX(KKey::ALT) |
00984 KKeyNative::modX(KKey::WIN));
00985
00986
00987
00988
00989
int mod_index = -1;
00990
for(
int i = ShiftMapIndex;
00991 i <= Mod5MapIndex;
00992 ++i )
00993
if(( mk & ( 1 << i )) != 0 )
00994 {
00995
if( mod_index >= 0 )
00996
return;
00997 mod_index = i;
00998 }
00999
bool release =
false;
01000
if( mod_index == -1 )
01001 release =
true;
01002
else
01003 {
01004 XModifierKeymap* xmk = XGetModifierMapping(qt_xdisplay());
01005
for (
int i=0; i<xmk->max_keypermod; i++)
01006
if (xmk->modifiermap[xmk->max_keypermod * mod_index + i]
01007 == ev.keycode)
01008 release =
true;
01009 XFreeModifiermap(xmk);
01010 }
01011
if( !release )
01012
return;
01013
if (tab_grab)
01014 {
01015 removeTabBoxGrab();
01016 tab_box->hide();
01017 keys->setEnabled(
true );
01018 tab_grab =
false;
01019
if(
Client* c = tab_box->currentClient())
01020 {
01021 activateClient( c );
01022
if( c->isShade())
01023 c->setShade( ShadeActivated );
01024 }
01025 }
01026
if (control_grab)
01027 {
01028 removeTabBoxGrab();
01029 tab_box->hide();
01030 keys->setEnabled(
true );
01031 control_grab = False;
01032
if ( tab_box->currentDesktop() != -1 )
01033 {
01034 setCurrentDesktop( tab_box->currentDesktop() );
01035
01036 }
01037 }
01038 }
01039
01040
01041
int Workspace::nextDesktopFocusChain(
int iDesktop )
const
01042
{
01043
int i = desktop_focus_chain.find( iDesktop );
01044
if( i >= 0 && i+1 < (
int)desktop_focus_chain.size() )
01045
return desktop_focus_chain[i+1];
01046
else if( desktop_focus_chain.size() > 0 )
01047
return desktop_focus_chain[ 0 ];
01048
else
01049
return 1;
01050 }
01051
01052
int Workspace::previousDesktopFocusChain(
int iDesktop )
const
01053
{
01054
int i = desktop_focus_chain.find( iDesktop );
01055
if( i-1 >= 0 )
01056
return desktop_focus_chain[i-1];
01057
else if( desktop_focus_chain.size() > 0 )
01058
return desktop_focus_chain[desktop_focus_chain.size()-1];
01059
else
01060
return numberOfDesktops();
01061 }
01062
01067 Client* Workspace::nextFocusChainClient( Client* c )
const
01068
{
01069
if ( focus_chain.isEmpty() )
01070
return 0;
01071 ClientList::ConstIterator it = focus_chain.find( c );
01072
if ( it == focus_chain.end() )
01073
return focus_chain.last();
01074
if ( it == focus_chain.begin() )
01075
return focus_chain.last();
01076 --it;
01077
return *it;
01078 }
01079
01084 Client* Workspace::previousFocusChainClient( Client* c )
const
01085
{
01086
if ( focus_chain.isEmpty() )
01087
return 0;
01088 ClientList::ConstIterator it = focus_chain.find( c );
01089
if ( it == focus_chain.end() )
01090
return focus_chain.first();
01091 ++it;
01092
if ( it == focus_chain.end() )
01093
return focus_chain.first();
01094
return *it;
01095 }
01096
01101 Client* Workspace::nextStaticClient( Client* c )
const
01102
{
01103
if ( !c || clients.isEmpty() )
01104
return 0;
01105 ClientList::ConstIterator it = clients.find( c );
01106
if ( it == clients.end() )
01107
return clients.first();
01108 ++it;
01109
if ( it == clients.end() )
01110
return clients.first();
01111
return *it;
01112 }
01117 Client* Workspace::previousStaticClient( Client* c )
const
01118
{
01119
if ( !c || clients.isEmpty() )
01120
return 0;
01121 ClientList::ConstIterator it = clients.find( c );
01122
if ( it == clients.end() )
01123
return clients.last();
01124
if ( it == clients.begin() )
01125
return clients.last();
01126 --it;
01127
return *it;
01128 }
01129
01130
bool Workspace::establishTabBoxGrab()
01131 {
01132
if( XGrabKeyboard( qt_xdisplay(), root, FALSE,
01133 GrabModeAsync, GrabModeAsync, qt_x_time) != GrabSuccess )
01134
return false;
01135
01136
01137
01138
01139
01140 assert( !forced_global_mouse_grab );
01141 forced_global_mouse_grab =
true;
01142
if( active_client != NULL )
01143 active_client->updateMouseGrab();
01144
return true;
01145 }
01146
01147
void Workspace::removeTabBoxGrab()
01148 {
01149 XUngrabKeyboard(qt_xdisplay(), qt_x_time);
01150 assert( forced_global_mouse_grab );
01151 forced_global_mouse_grab =
false;
01152
if( active_client != NULL )
01153 active_client->updateMouseGrab();
01154 }
01155
01156 }
01157
01158
#include "tabbox.moc"