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 <tqpainter.h>
00017 #include <tqlabel.h>
00018 #include <tqdrawutil.h>
00019 #include <tqstyle.h>
00020 #include <kglobal.h>
00021 #include <fixx11h.h>
00022 #include <kconfig.h>
00023 #include <klocale.h>
00024 #include <tqapplication.h>
00025 #include <tqdesktopwidget.h>
00026 #include <kstringhandler.h>
00027 #include <stdarg.h>
00028 #include <kdebug.h>
00029 #include <kglobalaccel.h>
00030 #include <kkeynative.h>
00031 #include <kglobalsettings.h>
00032 #include <kiconeffect.h>
00033 #include <X11/keysym.h>
00034 #include <X11/keysymdef.h>
00035
00036
00037
00038 namespace KWinInternal
00039 {
00040
00041 extern TQPixmap* kwin_get_menu_pix_hack();
00042
00043 TabBox::TabBox( Workspace *ws, const char *name )
00044 : TQFrame( 0, name, TQt::WNoAutoErase ), current_client( NULL ), wspace(ws)
00045 {
00046 setFrameStyle(TQFrame::StyledPanel | TQFrame::Plain);
00047 setLineWidth(2);
00048 setMargin(2);
00049
00050 showMiniIcon = false;
00051
00052 no_tasks = i18n("*** No Windows ***");
00053 m = DesktopMode;
00054 reconfigure();
00055 reset();
00056 connect(&delayedShowTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(show()));
00057
00058 XSetWindowAttributes attr;
00059 attr.override_redirect = 1;
00060 outline_left = XCreateWindow( qt_xdisplay(), qt_xrootwin(), 0, 0, 1, 1, 0,
00061 CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr );
00062 outline_right = XCreateWindow( qt_xdisplay(), qt_xrootwin(), 0, 0, 1, 1, 0,
00063 CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr );
00064 outline_top = XCreateWindow( qt_xdisplay(), qt_xrootwin(), 0, 0, 1, 1, 0,
00065 CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr );
00066 outline_bottom = XCreateWindow( qt_xdisplay(), qt_xrootwin(), 0, 0, 1, 1, 0,
00067 CopyFromParent, CopyFromParent, CopyFromParent, CWOverrideRedirect, &attr );
00068 }
00069
00070 TabBox::~TabBox()
00071 {
00072 XDestroyWindow( qt_xdisplay(), outline_left );
00073 XDestroyWindow( qt_xdisplay(), outline_right );
00074 XDestroyWindow( qt_xdisplay(), outline_top );
00075 XDestroyWindow( qt_xdisplay(), outline_bottom );
00076 }
00077
00078
00084 void TabBox::setMode( Mode mode )
00085 {
00086 m = mode;
00087 }
00088
00089
00093 void TabBox::createClientList(ClientList &list, int desktop , Client *c, bool chain)
00094 {
00095 ClientList::size_type idx = 0;
00096
00097 list.clear();
00098
00099 Client* start = c;
00100
00101 if ( chain )
00102 c = workspace()->nextFocusChainClient(c);
00103 else
00104 c = workspace()->stackingOrder().first();
00105
00106 Client* stop = c;
00107
00108 while ( c )
00109 {
00110 Client* add = NULL;
00111 if ( ((desktop == -1) || c->isOnDesktop(desktop))
00112 && c->wantsTabFocus() )
00113 {
00114 Client* modal = c->findModal();
00115 if( modal == NULL || modal == c )
00116 add = c;
00117 else if( !list.contains( modal ))
00118 add = modal;
00119 else
00120 {
00121
00122 }
00123 }
00124
00125 if( options->separateScreenFocus && options->xineramaEnabled )
00126 {
00127 if( c->screen() != workspace()->activeScreen())
00128 add = NULL;
00129 }
00130
00131 if( add != NULL )
00132 {
00133 if ( start == add )
00134 {
00135 list.remove( add );
00136 list.prepend( add );
00137 }
00138 else
00139 list += add;
00140 }
00141
00142 if ( chain )
00143 c = workspace()->nextFocusChainClient( c );
00144 else
00145 {
00146 if ( idx >= (workspace()->stackingOrder().size()-1) )
00147 c = 0;
00148 else
00149 c = workspace()->stackingOrder()[++idx];
00150 }
00151
00152 if ( c == stop )
00153 break;
00154 }
00155 }
00156
00157
00162 void TabBox::reset()
00163 {
00164 int w, h, cw = 0, wmax = 0;
00165
00166 TQRect r = workspace()->screenGeometry( workspace()->activeScreen());
00167
00168
00169
00170 lineHeight = QMAX(fontMetrics().height() + 2, 32 + 4);
00171
00172 if ( mode() == WindowsMode )
00173 {
00174 setCurrentClient( workspace()->activeClient());
00175
00176
00177 createClientList(clients, options_traverse_all ? -1 : workspace()->currentDesktop(), current_client, true);
00178
00179
00180 cw = fontMetrics().width(no_tasks)+20;
00181 for (ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
00182 {
00183 cw = fontMetrics().width( (*it)->caption() );
00184 if ( cw > wmax ) wmax = cw;
00185 }
00186
00187
00188 if ( clients.count() == 0 )
00189 {
00190 TQFont f = font();
00191 f.setBold( TRUE );
00192 f.setPointSize( 14 );
00193
00194 h = TQFontMetrics(f).height()*4;
00195 }
00196 else
00197 {
00198 showMiniIcon = false;
00199 h = clients.count() * lineHeight;
00200
00201 if ( h > (r.height()-(2*frameWidth())) )
00202 {
00203 showMiniIcon = true;
00204
00205 lineHeight = QMAX(fontMetrics().height() + 2, 16 + 2);
00206
00207 h = clients.count() * lineHeight;
00208
00209 if ( h > (r.height()-(2*frameWidth())) )
00210 {
00211
00212 int howMany = (h - (r.height()-(2*frameWidth())))/lineHeight;
00213 for (; howMany; howMany--)
00214 clients.remove(clients.last());
00215
00216 h = clients.count() * lineHeight;
00217 }
00218 }
00219 }
00220 }
00221 else
00222 {
00223 showMiniIcon = false;
00224 desk = workspace()->currentDesktop();
00225
00226 for ( int i = 1; i <= workspace()->numberOfDesktops(); i++ )
00227 {
00228 cw = fontMetrics().width( workspace()->desktopName(i) );
00229 if ( cw > wmax ) wmax = cw;
00230 }
00231
00232
00233 h = workspace()->numberOfDesktops() * lineHeight;
00234 }
00235
00236
00237 h += 2 * frameWidth();
00238 w = 2*frameWidth() + 5*2 + ( showMiniIcon ? 16 : 32 ) + 8 + wmax;
00239 w = kClamp( w, r.width()/3 , r.width() * 4 / 5 );
00240
00241 setGeometry( (r.width()-w)/2 + r.x(),
00242 (r.height()-h)/2+ r.y(),
00243 w, h );
00244 }
00245
00246
00250 void TabBox::nextPrev( bool next)
00251 {
00252 if ( mode() == WindowsMode )
00253 {
00254 Client* firstClient = NULL;
00255 Client* client = current_client;
00256 do
00257 {
00258 if ( next )
00259 client = workspace()->nextFocusChainClient(client);
00260 else
00261 client = workspace()->previousFocusChainClient(client);
00262 if (!firstClient)
00263 {
00264
00265
00266 firstClient = client;
00267 }
00268 else if (client == firstClient)
00269 {
00270
00271 client = 0;
00272 break;
00273 }
00274 } while ( client && !clients.contains( client ));
00275 setCurrentClient( client );
00276 }
00277 else if( mode() == DesktopMode )
00278 {
00279 if ( next )
00280 desk = workspace()->nextDesktopFocusChain( desk );
00281 else
00282 desk = workspace()->previousDesktopFocusChain( desk );
00283 }
00284 else
00285 {
00286 if ( next )
00287 {
00288 desk++;
00289 if ( desk > workspace()->numberOfDesktops() )
00290 desk = 1;
00291 }
00292 else
00293 {
00294 desk--;
00295 if ( desk < 1 )
00296 desk = workspace()->numberOfDesktops();
00297 }
00298 }
00299
00300 update();
00301 }
00302
00303
00304
00309 Client* TabBox::currentClient()
00310 {
00311 if ( mode() != WindowsMode )
00312 return 0;
00313 if (!workspace()->hasClient( current_client ))
00314 return 0;
00315 return current_client;
00316 }
00317
00318 void TabBox::setCurrentClient( Client* c )
00319 {
00320 if( current_client != c )
00321 {
00322 current_client = c;
00323 updateOutline();
00324 }
00325 }
00326
00332 int TabBox::currentDesktop()
00333 {
00334 if ( mode() == DesktopListMode || mode() == DesktopMode )
00335 return desk;
00336 else
00337 return -1;
00338 }
00339
00340
00344 void TabBox::showEvent( TQShowEvent* )
00345 {
00346 updateOutline();
00347 XRaiseWindow( qt_xdisplay(), outline_left );
00348 XRaiseWindow( qt_xdisplay(), outline_right );
00349 XRaiseWindow( qt_xdisplay(), outline_top );
00350 XRaiseWindow( qt_xdisplay(), outline_bottom );
00351 raise();
00352 }
00353
00354
00358 void TabBox::hideEvent( TQHideEvent* )
00359 {
00360 XUnmapWindow( qt_xdisplay(), outline_left );
00361 XUnmapWindow( qt_xdisplay(), outline_right );
00362 XUnmapWindow( qt_xdisplay(), outline_top );
00363 XUnmapWindow( qt_xdisplay(), outline_bottom );
00364 }
00365
00369 void TabBox::drawContents( TQPainter * )
00370 {
00371 TQRect r(contentsRect());
00372 TQPixmap pix(r.size());
00373 pix.fill(this, 0, 0);
00374
00375 TQPainter p;
00376 p.begin(&pix, this);
00377
00378 TQPixmap* menu_pix = kwin_get_menu_pix_hack();
00379
00380 int iconWidth = showMiniIcon ? 16 : 32;
00381 int x = 0;
00382 int y = 0;
00383
00384 if ( mode () == WindowsMode )
00385 {
00386 if ( !currentClient() )
00387 {
00388 TQFont f = font();
00389 f.setBold( TRUE );
00390 f.setPointSize( 14 );
00391
00392 p.setFont(f);
00393 p.drawText( r, AlignCenter, no_tasks);
00394 }
00395 else
00396 {
00397 for (ClientList::ConstIterator it = clients.begin(); it != clients.end(); ++it)
00398 {
00399 if ( workspace()->hasClient( *it ) )
00400 {
00401
00402 if ( (*it) == current_client )
00403 p.fillRect(x, y, r.width(), lineHeight, colorGroup().highlight());
00404
00405
00406 TQPixmap icon;
00407 if ( showMiniIcon )
00408 {
00409 if ( !(*it)->miniIcon().isNull() )
00410 icon = (*it)->miniIcon();
00411 }
00412 else
00413 if ( !(*it)->icon().isNull() )
00414 icon = (*it)->icon();
00415 else if ( menu_pix )
00416 icon = *menu_pix;
00417
00418 if( !icon.isNull())
00419 {
00420 if( (*it)->isMinimized())
00421 KIconEffect::semiTransparent( icon );
00422 p.drawPixmap( x+5, y + (lineHeight - iconWidth)/2, icon );
00423 }
00424
00425
00426 TQString s;
00427
00428 if ( !(*it)->isOnDesktop(workspace()->currentDesktop()) )
00429 s = workspace()->desktopName((*it)->desktop()) + ": ";
00430
00431 if ( (*it)->isMinimized() )
00432 s += TQString("(") + (*it)->caption() + ")";
00433 else
00434 s += (*it)->caption();
00435
00436 s = KStringHandler::cPixelSqueeze(s, fontMetrics(), r.width() - 5 - iconWidth - 8);
00437
00438
00439 if ( (*it) == current_client )
00440 p.setPen(colorGroup().highlightedText());
00441 else if( (*it)->isMinimized())
00442 {
00443 TQColor c1 = colorGroup().text();
00444 TQColor c2 = colorGroup().background();
00445
00446 int r1, g1, b1;
00447 int r2, g2, b2;
00448
00449 c1.rgb( &r1, &g1, &b1 );
00450 c2.rgb( &r2, &g2, &b2 );
00451
00452 r1 += (int) ( .5 * ( r2 - r1 ) );
00453 g1 += (int) ( .5 * ( g2 - g1 ) );
00454 b1 += (int) ( .5 * ( b2 - b1 ) );
00455
00456 p.setPen(TQColor( r1, g1, b1 ));
00457 }
00458 else
00459 p.setPen(colorGroup().text());
00460
00461 p.drawText(x+5 + iconWidth + 8, y, r.width() - 5 - iconWidth - 8, lineHeight,
00462 Qt::AlignLeft | Qt::AlignVCenter | TQt::SingleLine, s);
00463
00464 y += lineHeight;
00465 }
00466 if ( y >= r.height() ) break;
00467 }
00468 }
00469 }
00470 else
00471 {
00472 int iconHeight = iconWidth;
00473
00474
00475 TQFont f(font());
00476 f.setBold(true);
00477 f.setPixelSize(iconHeight - 4);
00478 TQFontMetrics fm(f);
00479
00480 int wmax = 0;
00481 for ( int i = 1; i <= workspace()->numberOfDesktops(); i++ )
00482 {
00483 wmax = QMAX(wmax, fontMetrics().width(workspace()->desktopName(i)));
00484
00485
00486 TQString num = TQString::number(i);
00487 iconWidth = QMAX(iconWidth - 4, fm.boundingRect(num).width()) + 4;
00488 }
00489
00490
00491
00492 int iDesktop = (mode() == DesktopMode) ? workspace()->currentDesktop() : 1;
00493 for ( int i = 1; i <= workspace()->numberOfDesktops(); i++ )
00494 {
00495
00496 if ( iDesktop == desk )
00497 p.fillRect(x, y, r.width(), lineHeight, colorGroup().highlight());
00498
00499 p.save();
00500
00501
00502 p.fillRect(x+5, y+2, iconWidth, iconHeight, colorGroup().base());
00503 p.setPen(colorGroup().text());
00504 p.drawRect(x+5, y+2, iconWidth, iconHeight);
00505
00506
00507 p.setFont(f);
00508 TQString num = TQString::number(iDesktop);
00509 p.drawText(x+5, y+2, iconWidth, iconHeight, Qt::AlignCenter, num);
00510
00511 p.restore();
00512
00513
00514 if ( iDesktop == desk )
00515 p.setPen(colorGroup().highlightedText());
00516 else
00517 p.setPen(colorGroup().text());
00518
00519 p.drawText(x+5 + iconWidth + 8, y, r.width() - 5 - iconWidth - 8, lineHeight,
00520 Qt::AlignLeft | Qt::AlignVCenter | TQt::SingleLine,
00521 workspace()->desktopName(iDesktop));
00522
00523
00524 int x1 = x + 5 + iconWidth + 8 + wmax + 5;
00525
00526 ClientList list;
00527 createClientList(list, iDesktop, 0, false);
00528
00529 for (ClientList::ConstIterator it = list.fromLast(); it != list.end(); --it)
00530 {
00531 if ( !(*it)->miniIcon().isNull() )
00532 {
00533 if ( x1+18 >= x+r.width() )
00534 break;
00535
00536 p.drawPixmap( x1, y + (lineHeight - 16)/2, (*it)->miniIcon() );
00537 x1 += 18;
00538 }
00539 }
00540
00541
00542 y += lineHeight;
00543 if ( y >= r.height() ) break;
00544
00545 if( mode() == DesktopMode )
00546 iDesktop = workspace()->nextDesktopFocusChain( iDesktop );
00547 else
00548 iDesktop++;
00549 }
00550 }
00551 p.end();
00552 bitBlt(this, r.x(), r.y(), &pix);
00553 }
00554
00555 void TabBox::updateOutline()
00556 {
00557 Client* c = currentClient();
00558 if( !options->tabboxOutline || c == NULL || this->isHidden() || !c->isShown( true ) || !c->isOnCurrentDesktop())
00559 {
00560 XUnmapWindow( qt_xdisplay(), outline_left );
00561 XUnmapWindow( qt_xdisplay(), outline_right );
00562 XUnmapWindow( qt_xdisplay(), outline_top );
00563 XUnmapWindow( qt_xdisplay(), outline_bottom );
00564 return;
00565 }
00566
00567 XMoveResizeWindow( qt_xdisplay(), outline_left, c->x(), c->y() + 5, 5, c->height() - 10 );
00568 XMoveResizeWindow( qt_xdisplay(), outline_right, c->x() + c->width() - 5, c->y() + 5, 5, c->height() - 10 );
00569 XMoveResizeWindow( qt_xdisplay(), outline_top, c->x(), c->y(), c->width(), 5 );
00570 XMoveResizeWindow( qt_xdisplay(), outline_bottom, c->x(), c->y() + c->height() - 5, c->width(), 5 );
00571 {
00572 TQPixmap pix( 5, c->height() - 10 );
00573 TQPainter p( &pix );
00574 p.setPen( white );
00575 p.drawLine( 0, 0, 0, pix.height() - 1 );
00576 p.drawLine( 4, 0, 4, pix.height() - 1 );
00577 p.setPen( gray );
00578 p.drawLine( 1, 0, 1, pix.height() - 1 );
00579 p.drawLine( 3, 0, 3, pix.height() - 1 );
00580 p.setPen( black );
00581 p.drawLine( 2, 0, 2, pix.height() - 1 );
00582 p.end();
00583 XSetWindowBackgroundPixmap( qt_xdisplay(), outline_left, pix.handle());
00584 XSetWindowBackgroundPixmap( qt_xdisplay(), outline_right, pix.handle());
00585 }
00586 {
00587 TQPixmap pix( c->width(), 5 );
00588 TQPainter p( &pix );
00589 p.setPen( white );
00590 p.drawLine( 0, 0, pix.width() - 1 - 0, 0 );
00591 p.drawLine( 4, 4, pix.width() - 1 - 4, 4 );
00592 p.drawLine( 0, 0, 0, 4 );
00593 p.drawLine( pix.width() - 1 - 0, 0, pix.width() - 1 - 0, 4 );
00594 p.setPen( gray );
00595 p.drawLine( 1, 1, pix.width() - 1 - 1, 1 );
00596 p.drawLine( 3, 3, pix.width() - 1 - 3, 3 );
00597 p.drawLine( 1, 1, 1, 4 );
00598 p.drawLine( 3, 3, 3, 4 );
00599 p.drawLine( pix.width() - 1 - 1, 1, pix.width() - 1 - 1, 4 );
00600 p.drawLine( pix.width() - 1 - 3, 3, pix.width() - 1 - 3, 4 );
00601 p.setPen( black );
00602 p.drawLine( 2, 2, pix.width() - 1 - 2, 2 );
00603 p.drawLine( 2, 2, 2, 4 );
00604 p.drawLine( pix.width() - 1 - 2, 2, pix.width() - 1 - 2, 4 );
00605 p.end();
00606 XSetWindowBackgroundPixmap( qt_xdisplay(), outline_top, pix.handle());
00607 }
00608 {
00609 TQPixmap pix( c->width(), 5 );
00610 TQPainter p( &pix );
00611 p.setPen( white );
00612 p.drawLine( 4, 0, pix.width() - 1 - 4, 0 );
00613 p.drawLine( 0, 4, pix.width() - 1 - 0, 4 );
00614 p.drawLine( 0, 4, 0, 0 );
00615 p.drawLine( pix.width() - 1 - 0, 4, pix.width() - 1 - 0, 0 );
00616 p.setPen( gray );
00617 p.drawLine( 3, 1, pix.width() - 1 - 3, 1 );
00618 p.drawLine( 1, 3, pix.width() - 1 - 1, 3 );
00619 p.drawLine( 3, 1, 3, 0 );
00620 p.drawLine( 1, 3, 1, 0 );
00621 p.drawLine( pix.width() - 1 - 3, 1, pix.width() - 1 - 3, 0 );
00622 p.drawLine( pix.width() - 1 - 1, 3, pix.width() - 1 - 1, 0 );
00623 p.setPen( black );
00624 p.drawLine( 2, 2, pix.width() - 1 - 2, 2 );
00625 p.drawLine( 2, 0, 2, 2 );
00626 p.drawLine( pix.width() - 1 - 2, 0, pix.width() - 1 - 2, 2 );
00627 p.end();
00628 XSetWindowBackgroundPixmap( qt_xdisplay(), outline_bottom, pix.handle());
00629 }
00630 XClearWindow( qt_xdisplay(), outline_left );
00631 XClearWindow( qt_xdisplay(), outline_right );
00632 XClearWindow( qt_xdisplay(), outline_top );
00633 XClearWindow( qt_xdisplay(), outline_bottom );
00634 XMapWindow( qt_xdisplay(), outline_left );
00635 XMapWindow( qt_xdisplay(), outline_right );
00636 XMapWindow( qt_xdisplay(), outline_top );
00637 XMapWindow( qt_xdisplay(), outline_bottom );
00638 }
00639
00640 void TabBox::hide()
00641 {
00642 delayedShowTimer.stop();
00643 TQWidget::hide();
00644 TQApplication::syncX();
00645 XEvent otherEvent;
00646 while (XCheckTypedEvent (qt_xdisplay(), EnterNotify, &otherEvent ) )
00647 ;
00648 }
00649
00650
00651 void TabBox::reconfigure()
00652 {
00653 KConfig * c(KGlobal::config());
00654 c->setGroup("TabBox");
00655 options_traverse_all = c->readBoolEntry("TraverseAll", false );
00656 }
00657
00676 void TabBox::delayedShow()
00677 {
00678 KConfig * c(KGlobal::config());
00679 c->setGroup("TabBox");
00680 bool delay = c->readBoolEntry("ShowDelay", true);
00681
00682 if (!delay)
00683 {
00684 show();
00685 return;
00686 }
00687
00688 int delayTime = c->readNumEntry("DelayTime", 90);
00689 delayedShowTimer.start(delayTime, true);
00690 }
00691
00692
00693 void TabBox::handleMouseEvent( XEvent* e )
00694 {
00695 XAllowEvents( qt_xdisplay(), AsyncPointer, GET_QT_X_TIME() );
00696 if( e->type != ButtonPress )
00697 return;
00698 TQPoint pos( e->xbutton.x_root, e->xbutton.y_root );
00699 if( !geometry().contains( pos ))
00700 {
00701 workspace()->closeTabBox();
00702 return;
00703 }
00704 pos.rx() -= x();
00705 pos.ry() -= y();
00706 int num = (pos.y()-frameWidth()) / lineHeight;
00707
00708 if( mode() == WindowsMode )
00709 {
00710 for( ClientList::ConstIterator it = clients.begin();
00711 it != clients.end();
00712 ++it)
00713 {
00714 if( workspace()->hasClient( *it ) && (num == 0) )
00715 {
00716 setCurrentClient( *it );
00717 break;
00718 }
00719 num--;
00720 }
00721 }
00722 else
00723 {
00724 int iDesktop = (mode() == DesktopMode) ? workspace()->currentDesktop() : 1;
00725 for( int i = 1;
00726 i <= workspace()->numberOfDesktops();
00727 ++i )
00728 {
00729 if( num == 0 )
00730 {
00731 desk = iDesktop;
00732 break;
00733 }
00734 num--;
00735 if( mode() == DesktopMode )
00736 iDesktop = workspace()->nextDesktopFocusChain( iDesktop );
00737 else
00738 iDesktop++;
00739 }
00740 }
00741 update();
00742 }
00743
00744
00745
00746
00747
00748
00753 static
00754 bool areKeySymXsDepressed( bool bAll, const uint keySyms[], int nKeySyms )
00755 {
00756 char keymap[32];
00757
00758 kdDebug(125) << "areKeySymXsDepressed: " << (bAll ? "all of " : "any of ") << nKeySyms << endl;
00759
00760 XQueryKeymap( qt_xdisplay(), keymap );
00761
00762 for( int iKeySym = 0; iKeySym < nKeySyms; iKeySym++ )
00763 {
00764 uint keySymX = keySyms[ iKeySym ];
00765 uchar keyCodeX = XKeysymToKeycode( qt_xdisplay(), keySymX );
00766 int i = keyCodeX / 8;
00767 char mask = 1 << (keyCodeX - (i * 8));
00768
00769 kdDebug(125) << iKeySym << ": keySymX=0x" << TQString::number( keySymX, 16 )
00770 << " i=" << i << " mask=0x" << TQString::number( mask, 16 )
00771 << " keymap[i]=0x" << TQString::number( keymap[i], 16 ) << endl;
00772
00773
00774 if( i < 0 || i >= 32 )
00775 return false;
00776
00777
00778 if( bAll )
00779 {
00780 if( (keymap[i] & mask) == 0 )
00781 return false;
00782 }
00783 else
00784 {
00785
00786 if( keymap[i] & mask )
00787 return true;
00788 }
00789 }
00790
00791
00792
00793 return bAll;
00794 }
00795
00796 static bool areModKeysDepressed( const KKeySequence& seq )
00797 {
00798 uint rgKeySyms[10];
00799 int nKeySyms = 0;
00800 if( seq.isNull())
00801 return false;
00802 int mod = seq.key(seq.count()-1).modFlags();
00803
00804 if ( mod & KKey::SHIFT )
00805 {
00806 rgKeySyms[nKeySyms++] = XK_Shift_L;
00807 rgKeySyms[nKeySyms++] = XK_Shift_R;
00808 }
00809 if ( mod & KKey::CTRL )
00810 {
00811 rgKeySyms[nKeySyms++] = XK_Control_L;
00812 rgKeySyms[nKeySyms++] = XK_Control_R;
00813 }
00814 if( mod & KKey::ALT )
00815 {
00816 rgKeySyms[nKeySyms++] = XK_Alt_L;
00817 rgKeySyms[nKeySyms++] = XK_Alt_R;
00818 }
00819 if( mod & KKey::WIN )
00820 {
00821
00822
00823
00824 rgKeySyms[nKeySyms++] = XK_Super_L;
00825 rgKeySyms[nKeySyms++] = XK_Super_R;
00826 rgKeySyms[nKeySyms++] = XK_Meta_L;
00827 rgKeySyms[nKeySyms++] = XK_Meta_R;
00828 }
00829
00830 return areKeySymXsDepressed( false, rgKeySyms, nKeySyms );
00831 }
00832
00833 static bool areModKeysDepressed( const KShortcut& cut )
00834 {
00835 for( unsigned int i = 0;
00836 i < cut.count();
00837 ++i )
00838 {
00839 if( areModKeysDepressed( cut.seq( i )))
00840 return true;
00841 }
00842 return false;
00843 }
00844
00845 void Workspace::slotWalkThroughWindows()
00846 {
00847 if ( root != qt_xrootwin() )
00848 return;
00849 if ( tab_grab || control_grab )
00850 return;
00851 if ( options->altTabStyle == Options::CDE || !options->focusPolicyIsReasonable())
00852 {
00853
00854
00855 CDEWalkThroughWindows( true );
00856 }
00857 else
00858 {
00859 if ( areModKeysDepressed( cutWalkThroughWindows ) )
00860 {
00861 if ( startKDEWalkThroughWindows() )
00862 KDEWalkThroughWindows( true );
00863 }
00864 else
00865
00866
00867 KDEOneStepThroughWindows( true );
00868 }
00869 }
00870
00871 void Workspace::slotWalkBackThroughWindows()
00872 {
00873 if ( root != qt_xrootwin() )
00874 return;
00875 if( tab_grab || control_grab )
00876 return;
00877 if ( options->altTabStyle == Options::CDE || !options->focusPolicyIsReasonable())
00878 {
00879
00880 CDEWalkThroughWindows( false );
00881 }
00882 else
00883 {
00884 if ( areModKeysDepressed( cutWalkThroughWindowsReverse ) )
00885 {
00886 if ( startKDEWalkThroughWindows() )
00887 KDEWalkThroughWindows( false );
00888 }
00889 else
00890 {
00891 KDEOneStepThroughWindows( false );
00892 }
00893 }
00894 }
00895
00896 void Workspace::slotWalkThroughDesktops()
00897 {
00898 if ( root != qt_xrootwin() )
00899 return;
00900 if( tab_grab || control_grab )
00901 return;
00902 if ( areModKeysDepressed( cutWalkThroughDesktops ) )
00903 {
00904 if ( startWalkThroughDesktops() )
00905 walkThroughDesktops( true );
00906 }
00907 else
00908 {
00909 oneStepThroughDesktops( true );
00910 }
00911 }
00912
00913 void Workspace::slotWalkBackThroughDesktops()
00914 {
00915 if ( root != qt_xrootwin() )
00916 return;
00917 if( tab_grab || control_grab )
00918 return;
00919 if ( areModKeysDepressed( cutWalkThroughDesktopsReverse ) )
00920 {
00921 if ( startWalkThroughDesktops() )
00922 walkThroughDesktops( false );
00923 }
00924 else
00925 {
00926 oneStepThroughDesktops( false );
00927 }
00928 }
00929
00930 void Workspace::slotWalkThroughDesktopList()
00931 {
00932 if ( root != qt_xrootwin() )
00933 return;
00934 if( tab_grab || control_grab )
00935 return;
00936 if ( areModKeysDepressed( cutWalkThroughDesktopList ) )
00937 {
00938 if ( startWalkThroughDesktopList() )
00939 walkThroughDesktops( true );
00940 }
00941 else
00942 {
00943 oneStepThroughDesktopList( true );
00944 }
00945 }
00946
00947 void Workspace::slotWalkBackThroughDesktopList()
00948 {
00949 if ( root != qt_xrootwin() )
00950 return;
00951 if( tab_grab || control_grab )
00952 return;
00953 if ( areModKeysDepressed( cutWalkThroughDesktopListReverse ) )
00954 {
00955 if ( startWalkThroughDesktopList() )
00956 walkThroughDesktops( false );
00957 }
00958 else
00959 {
00960 oneStepThroughDesktopList( false );
00961 }
00962 }
00963
00964 bool Workspace::startKDEWalkThroughWindows()
00965 {
00966 if( !establishTabBoxGrab())
00967 return false;
00968 tab_grab = TRUE;
00969 keys->suspend( true );
00970 disable_shortcuts_keys->suspend( true );
00971 client_keys->suspend( true );
00972 tab_box->setMode( TabBox::WindowsMode );
00973 tab_box->reset();
00974 return TRUE;
00975 }
00976
00977 bool Workspace::startWalkThroughDesktops( int mode )
00978 {
00979 if( !establishTabBoxGrab())
00980 return false;
00981 control_grab = TRUE;
00982 keys->suspend( true );
00983 disable_shortcuts_keys->suspend( true );
00984 client_keys->suspend( true );
00985 tab_box->setMode( (TabBox::Mode) mode );
00986 tab_box->reset();
00987 return TRUE;
00988 }
00989
00990 bool Workspace::startWalkThroughDesktops()
00991 {
00992 return startWalkThroughDesktops( TabBox::DesktopMode );
00993 }
00994
00995 bool Workspace::startWalkThroughDesktopList()
00996 {
00997 return startWalkThroughDesktops( TabBox::DesktopListMode );
00998 }
00999
01000 void Workspace::KDEWalkThroughWindows( bool forward )
01001 {
01002 tab_box->nextPrev( forward );
01003 tab_box->delayedShow();
01004 }
01005
01006 void Workspace::walkThroughDesktops( bool forward )
01007 {
01008 tab_box->nextPrev( forward );
01009 tab_box->delayedShow();
01010 }
01011
01012 void Workspace::CDEWalkThroughWindows( bool forward )
01013 {
01014 Client* c = NULL;
01015
01016
01017
01018 Q_ASSERT( block_stacking_updates == 0 );
01019 for( ClientList::ConstIterator it = stacking_order.fromLast();
01020 it != stacking_order.end();
01021 --it )
01022 {
01023 if ( (*it)->isOnCurrentDesktop() && !(*it)->isSpecialWindow()
01024 && (*it)->isShown( false ) && (*it)->wantsTabFocus()
01025 && !(*it)->keepAbove() && !(*it)->keepBelow())
01026 {
01027 c = *it;
01028 break;
01029 }
01030 }
01031 Client* nc = c;
01032 bool options_traverse_all;
01033 {
01034 KConfigGroupSaver saver( KGlobal::config(), "TabBox" );
01035 options_traverse_all = KGlobal::config()->readBoolEntry("TraverseAll", false );
01036 }
01037
01038 Client* firstClient = 0;
01039 do
01040 {
01041 nc = forward ? nextStaticClient(nc) : previousStaticClient(nc);
01042 if (!firstClient)
01043 {
01044
01045
01046 firstClient = nc;
01047 }
01048 else if (nc == firstClient)
01049 {
01050
01051 nc = 0;
01052 break;
01053 }
01054 } while (nc && nc != c &&
01055 (( !options_traverse_all && !nc->isOnDesktop(currentDesktop())) ||
01056 nc->isMinimized() || !nc->wantsTabFocus() || nc->keepAbove() || nc->keepBelow() ) );
01057 if (nc)
01058 {
01059 if (c && c != nc)
01060 lowerClient( c );
01061 if ( options->focusPolicyIsReasonable() )
01062 {
01063 activateClient( nc );
01064 if( nc->isShade() && options->shadeHover )
01065 nc->setShade( ShadeActivated );
01066 }
01067 else
01068 {
01069 if( !nc->isOnDesktop( currentDesktop()))
01070 setCurrentDesktop( nc->desktop());
01071 raiseClient( nc );
01072 }
01073 }
01074 }
01075
01076 void Workspace::KDEOneStepThroughWindows( bool forward )
01077 {
01078 tab_box->setMode( TabBox::WindowsMode );
01079 tab_box->reset();
01080 tab_box->nextPrev( forward );
01081 if( Client* c = tab_box->currentClient() )
01082 {
01083 activateClient( c );
01084 if( c->isShade() && options->shadeHover )
01085 c->setShade( ShadeActivated );
01086 }
01087 }
01088
01089 void Workspace::oneStepThroughDesktops( bool forward, int mode )
01090 {
01091 tab_box->setMode( (TabBox::Mode) mode );
01092 tab_box->reset();
01093 tab_box->nextPrev( forward );
01094 if ( tab_box->currentDesktop() != -1 )
01095 setCurrentDesktop( tab_box->currentDesktop() );
01096 }
01097
01098 void Workspace::oneStepThroughDesktops( bool forward )
01099 {
01100 oneStepThroughDesktops( forward, TabBox::DesktopMode );
01101 }
01102
01103 void Workspace::oneStepThroughDesktopList( bool forward )
01104 {
01105 oneStepThroughDesktops( forward, TabBox::DesktopListMode );
01106 }
01107
01111 void Workspace::tabBoxKeyPress( const KKeyNative& keyX )
01112 {
01113 bool forward = false;
01114 bool backward = false;
01115
01116 if (tab_grab)
01117 {
01118 forward = cutWalkThroughWindows.contains( keyX );
01119 backward = cutWalkThroughWindowsReverse.contains( keyX );
01120 if (forward || backward)
01121 {
01122 kdDebug(125) << "== " << cutWalkThroughWindows.toStringInternal()
01123 << " or " << cutWalkThroughWindowsReverse.toStringInternal() << endl;
01124 KDEWalkThroughWindows( forward );
01125 }
01126 }
01127 else if (control_grab)
01128 {
01129 forward = cutWalkThroughDesktops.contains( keyX ) ||
01130 cutWalkThroughDesktopList.contains( keyX );
01131 backward = cutWalkThroughDesktopsReverse.contains( keyX ) ||
01132 cutWalkThroughDesktopListReverse.contains( keyX );
01133 if (forward || backward)
01134 walkThroughDesktops(forward);
01135 }
01136
01137 if (control_grab || tab_grab)
01138 {
01139 uint keyQt = keyX.keyCodeQt();
01140 if ( ((keyQt & 0xffff) == Qt::Key_Escape)
01141 && !(forward || backward) )
01142 {
01143 closeTabBox();
01144 }
01145 }
01146 }
01147
01148 void Workspace::closeTabBox()
01149 {
01150 removeTabBoxGrab();
01151 tab_box->hide();
01152 keys->suspend( false );
01153 disable_shortcuts_keys->suspend( false );
01154 client_keys->suspend( false );
01155 tab_grab = FALSE;
01156 control_grab = FALSE;
01157 }
01158
01162 void Workspace::tabBoxKeyRelease( const XKeyEvent& ev )
01163 {
01164 unsigned int mk = ev.state &
01165 (KKeyNative::modX(KKey::SHIFT) |
01166 KKeyNative::modX(KKey::CTRL) |
01167 KKeyNative::modX(KKey::ALT) |
01168 KKeyNative::modX(KKey::WIN));
01169
01170
01171
01172
01173 int mod_index = -1;
01174 for( int i = ShiftMapIndex;
01175 i <= Mod5MapIndex;
01176 ++i )
01177 if(( mk & ( 1 << i )) != 0 )
01178 {
01179 if( mod_index >= 0 )
01180 return;
01181 mod_index = i;
01182 }
01183 bool release = false;
01184 if( mod_index == -1 )
01185 release = true;
01186 else
01187 {
01188 XModifierKeymap* xmk = XGetModifierMapping(qt_xdisplay());
01189 for (int i=0; i<xmk->max_keypermod; i++)
01190 if (xmk->modifiermap[xmk->max_keypermod * mod_index + i]
01191 == ev.keycode)
01192 release = true;
01193 XFreeModifiermap(xmk);
01194 }
01195 if( !release )
01196 return;
01197 if (tab_grab)
01198 {
01199 removeTabBoxGrab();
01200 tab_box->hide();
01201 keys->suspend( false );
01202 disable_shortcuts_keys->suspend( false );
01203 client_keys->suspend( false );
01204 tab_grab = false;
01205 if( Client* c = tab_box->currentClient())
01206 {
01207 activateClient( c );
01208 if( c->isShade() && options->shadeHover )
01209 c->setShade( ShadeActivated );
01210 }
01211 }
01212 if (control_grab)
01213 {
01214 removeTabBoxGrab();
01215 tab_box->hide();
01216 keys->suspend( false );
01217 disable_shortcuts_keys->suspend( false );
01218 client_keys->suspend( false );
01219 control_grab = False;
01220 if ( tab_box->currentDesktop() != -1 )
01221 {
01222 setCurrentDesktop( tab_box->currentDesktop() );
01223 }
01224 }
01225 }
01226
01227
01228 int Workspace::nextDesktopFocusChain( int iDesktop ) const
01229 {
01230 int i = desktop_focus_chain.find( iDesktop );
01231 if( i >= 0 && i+1 < (int)desktop_focus_chain.size() )
01232 return desktop_focus_chain[i+1];
01233 else if( desktop_focus_chain.size() > 0 )
01234 return desktop_focus_chain[ 0 ];
01235 else
01236 return 1;
01237 }
01238
01239 int Workspace::previousDesktopFocusChain( int iDesktop ) const
01240 {
01241 int i = desktop_focus_chain.find( iDesktop );
01242 if( i-1 >= 0 )
01243 return desktop_focus_chain[i-1];
01244 else if( desktop_focus_chain.size() > 0 )
01245 return desktop_focus_chain[desktop_focus_chain.size()-1];
01246 else
01247 return numberOfDesktops();
01248 }
01249
01254 Client* Workspace::nextFocusChainClient( Client* c ) const
01255 {
01256 if ( global_focus_chain.isEmpty() )
01257 return 0;
01258 ClientList::ConstIterator it = global_focus_chain.find( c );
01259 if ( it == global_focus_chain.end() )
01260 return global_focus_chain.last();
01261 if ( it == global_focus_chain.begin() )
01262 return global_focus_chain.last();
01263 --it;
01264 return *it;
01265 }
01266
01271 Client* Workspace::previousFocusChainClient( Client* c ) const
01272 {
01273 if ( global_focus_chain.isEmpty() )
01274 return 0;
01275 ClientList::ConstIterator it = global_focus_chain.find( c );
01276 if ( it == global_focus_chain.end() )
01277 return global_focus_chain.first();
01278 ++it;
01279 if ( it == global_focus_chain.end() )
01280 return global_focus_chain.first();
01281 return *it;
01282 }
01283
01288 Client* Workspace::nextStaticClient( Client* c ) const
01289 {
01290 if ( !c || clients.isEmpty() )
01291 return 0;
01292 ClientList::ConstIterator it = clients.find( c );
01293 if ( it == clients.end() )
01294 return clients.first();
01295 ++it;
01296 if ( it == clients.end() )
01297 return clients.first();
01298 return *it;
01299 }
01304 Client* Workspace::previousStaticClient( Client* c ) const
01305 {
01306 if ( !c || clients.isEmpty() )
01307 return 0;
01308 ClientList::ConstIterator it = clients.find( c );
01309 if ( it == clients.end() )
01310 return clients.last();
01311 if ( it == clients.begin() )
01312 return clients.last();
01313 --it;
01314 return *it;
01315 }
01316
01317 bool Workspace::establishTabBoxGrab()
01318 {
01319 if( XGrabKeyboard( qt_xdisplay(), root, FALSE,
01320 GrabModeAsync, GrabModeAsync, GET_QT_X_TIME()) != GrabSuccess )
01321 return false;
01322
01323
01324
01325
01326
01327 assert( !forced_global_mouse_grab );
01328 forced_global_mouse_grab = true;
01329 if( active_client != NULL )
01330 active_client->updateMouseGrab();
01331 return true;
01332 }
01333
01334 void Workspace::removeTabBoxGrab()
01335 {
01336 XUngrabKeyboard(qt_xdisplay(), GET_QT_X_TIME());
01337 assert( forced_global_mouse_grab );
01338 forced_global_mouse_grab = false;
01339 if( active_client != NULL )
01340 active_client->updateMouseGrab();
01341 }
01342
01343 }
01344
01345 #include "tabbox.moc"