00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "client.h"
00021 #include "workspace.h"
00022
00023 #include <fixx11h.h>
00024 #include <qhbox.h>
00025 #include <qpushbutton.h>
00026 #include <qslider.h>
00027 #include <qtooltip.h>
00028 #include <qpopupmenu.h>
00029 #include <kglobalsettings.h>
00030 #include <kiconloader.h>
00031 #include <klocale.h>
00032 #include <kconfig.h>
00033 #include <kglobalaccel.h>
00034 #include <kapplication.h>
00035 #include <qregexp.h>
00036
00037 #include "killwindow.h"
00038 #include "tabbox.h"
00039
00040 namespace KWinInternal
00041 {
00042
00043
00044
00045
00046
00047 QPopupMenu* Workspace::clientPopup()
00048 {
00049 if ( !popup )
00050 {
00051 popup = new QPopupMenu;
00052 popup->setCheckable( TRUE );
00053 popup->setFont(KGlobalSettings::menuFont());
00054 connect( popup, SIGNAL( aboutToShow() ), this, SLOT( clientPopupAboutToShow() ) );
00055 connect( popup, SIGNAL( activated(int) ), this, SLOT( clientPopupActivated(int) ) );
00056
00057 advanced_popup = new QPopupMenu( popup );
00058 advanced_popup->setCheckable( TRUE );
00059 advanced_popup->setFont(KGlobalSettings::menuFont());
00060 connect( advanced_popup, SIGNAL( activated(int) ), this, SLOT( clientPopupActivated(int) ) );
00061 advanced_popup->insertItem( SmallIconSet( "up" ),
00062 i18n("Keep &Above Others")+'\t'+keys->shortcut("Window Above Other Windows").seq(0).toString(), Options::KeepAboveOp );
00063 advanced_popup->insertItem( SmallIconSet( "down" ),
00064 i18n("Keep &Below Others")+'\t'+keys->shortcut("Window Below Other Windows").seq(0).toString(), Options::KeepBelowOp );
00065 advanced_popup->insertItem( SmallIconSet( "window_fullscreen" ),
00066 i18n("&Fullscreen")+'\t'+keys->shortcut("Window Fullscreen").seq(0).toString(), Options::FullScreenOp );
00067 advanced_popup->insertItem( i18n("&No Border")+'\t'+keys->shortcut("Window No Border").seq(0).toString(), Options::NoBorderOp );
00068 advanced_popup->insertItem( SmallIconSet("key_bindings"),
00069 i18n("Window &Shortcut...")+'\t'+keys->shortcut("Setup Window Shortcut").seq(0).toString(), Options::SetupWindowShortcutOp );
00070 advanced_popup->insertItem( SmallIconSet( "wizard" ), i18n("&Special Window Settings..."), Options::WindowRulesOp );
00071 advanced_popup->insertItem( SmallIconSet( "wizard" ), i18n("&Special Application Settings..."), Options::ApplicationRulesOp );
00072
00073 popup->insertItem(i18n("Ad&vanced"), advanced_popup );
00074 desk_popup_index = popup->count();
00075
00076 if (options->useTranslucency){
00077 QPopupMenu *trans_popup = new QPopupMenu( popup );
00078 QVBox *transBox = new QVBox(trans_popup);
00079 transButton = new QPushButton(transBox, "transButton");
00080 QToolTip::add(transButton, i18n("Reset opacity to default value"));
00081 transSlider = new QSlider(0, 100, 1, 100, Qt::Vertical, transBox, "transSlider");
00082 QToolTip::add(transSlider, i18n("Slide this to set the window's opacity"));
00083 connect(transButton, SIGNAL(clicked()), SLOT(resetClientOpacity()));
00084 connect(transButton, SIGNAL(clicked()), trans_popup, SLOT(hide()));
00085 connect(transSlider, SIGNAL(valueChanged(int)), SLOT(setTransButtonText(int)));
00086 connect(transSlider, SIGNAL(valueChanged(int)), this, SLOT(setPopupClientOpacity(int)));
00087
00088 trans_popup->insertItem(transBox);
00089 popup->insertItem(i18n("&Opacity"), trans_popup );
00090 }
00091
00092 popup->insertItem( SmallIconSet( "move" ), i18n("&Move")+'\t'+keys->shortcut("Window Move").seq(0).toString(), Options::MoveOp );
00093 popup->insertItem( i18n("Re&size")+'\t'+keys->shortcut("Window Resize").seq(0).toString(), Options::ResizeOp );
00094 popup->insertItem( i18n("Mi&nimize")+'\t'+keys->shortcut("Window Minimize").seq(0).toString(), Options::MinimizeOp );
00095 popup->insertItem( i18n("Ma&ximize")+'\t'+keys->shortcut("Window Maximize").seq(0).toString(), Options::MaximizeOp );
00096 popup->insertItem( i18n("Sh&ade")+'\t'+keys->shortcut("Window Shade").seq(0).toString(), Options::ShadeOp );
00097
00098 popup->insertSeparator();
00099
00100 if (!KGlobal::config()->isImmutable() &&
00101 !kapp->authorizeControlModules(Workspace::configModules(true)).isEmpty())
00102 {
00103 popup->insertItem(SmallIconSet( "configure" ), i18n("Configur&e Window Behavior..."), this, SLOT( configureWM() ));
00104 popup->insertSeparator();
00105 }
00106
00107 popup->insertItem( SmallIconSet( "fileclose" ), i18n("&Close")+'\t'+keys->shortcut("Window Close").seq(0).toString(), Options::CloseOp );
00108 }
00109 return popup;
00110 }
00111
00112
00113 void Workspace::setPopupClientOpacity(int value)
00114 {
00115 active_popup_client->setCustomOpacityFlag(true);
00116 value = 100 - value;
00117 value<100?active_popup_client->setOpacity(true, (uint)((value/100.0)*0xffffffff)):active_popup_client->setOpacity(false,0xffffffff);
00118 }
00119
00120 void Workspace::setTransButtonText(int value)
00121 {
00122 value = 100 - value;
00123 if(value < 0)
00124 transButton->setText("000 %");
00125 else if (value >= 100 )
00126 transButton->setText("100 %");
00127 else if(value < 10)
00128 transButton->setText("00"+QString::number(value)+" %");
00129 else if(value < 100)
00130 transButton->setText("0"+QString::number(value)+" %");
00131 }
00132
00133 void Workspace::resetClientOpacity()
00134 {
00135 active_popup_client->setCustomOpacityFlag(false);
00136 active_popup_client->updateOpacity();
00137 transSlider->setValue(100-active_popup_client->opacityPercentage());
00138 setTransButtonText(100-active_popup_client->opacityPercentage());
00139 }
00140
00141
00147 void Workspace::clientPopupAboutToShow()
00148 {
00149 if ( !active_popup_client || !popup )
00150 return;
00151
00152 if ( numberOfDesktops() == 1 )
00153 {
00154 delete desk_popup;
00155 desk_popup = 0;
00156 }
00157 else
00158 {
00159 initDesktopPopup();
00160 }
00161
00162 popup->setItemEnabled( Options::ResizeOp, active_popup_client->isResizable() );
00163 popup->setItemEnabled( Options::MoveOp, active_popup_client->isMovable() );
00164 popup->setItemEnabled( Options::MaximizeOp, active_popup_client->isMaximizable() );
00165 popup->setItemChecked( Options::MaximizeOp, active_popup_client->maximizeMode() == Client::MaximizeFull );
00166
00167 popup->setItemChecked( Options::ShadeOp, active_popup_client->shadeMode() != ShadeNone );
00168 popup->setItemEnabled( Options::ShadeOp, active_popup_client->isShadeable());
00169 advanced_popup->setItemChecked( Options::KeepAboveOp, active_popup_client->keepAbove() );
00170 advanced_popup->setItemChecked( Options::KeepBelowOp, active_popup_client->keepBelow() );
00171 advanced_popup->setItemChecked( Options::FullScreenOp, active_popup_client->isFullScreen() );
00172 advanced_popup->setItemEnabled( Options::FullScreenOp, active_popup_client->userCanSetFullScreen() );
00173 advanced_popup->setItemChecked( Options::NoBorderOp, active_popup_client->noBorder() );
00174 advanced_popup->setItemEnabled( Options::NoBorderOp, active_popup_client->userCanSetNoBorder() );
00175 popup->setItemEnabled( Options::MinimizeOp, active_popup_client->isMinimizable() );
00176 popup->setItemEnabled( Options::CloseOp, active_popup_client->isCloseable() );
00177 if (options->useTranslucency)
00178 {
00179 transSlider->setValue(100-active_popup_client->opacityPercentage());
00180 setTransButtonText(100-active_popup_client->opacityPercentage());
00181 }
00182 }
00183
00184
00185 void Workspace::initDesktopPopup()
00186 {
00187 if (desk_popup)
00188 return;
00189
00190 desk_popup = new QPopupMenu( popup );
00191 desk_popup->setCheckable( TRUE );
00192 desk_popup->setFont(KGlobalSettings::menuFont());
00193 connect( desk_popup, SIGNAL( activated(int) ),
00194 this, SLOT( slotSendToDesktop(int) ) );
00195 connect( desk_popup, SIGNAL( aboutToShow() ),
00196 this, SLOT( desktopPopupAboutToShow() ) );
00197
00198 popup->insertItem(i18n("To &Desktop"), desk_popup, -1, desk_popup_index );
00199 }
00200
00205 void Workspace::desktopPopupAboutToShow()
00206 {
00207 if ( !desk_popup )
00208 return;
00209
00210 desk_popup->clear();
00211 desk_popup->insertItem( i18n("&All Desktops"), 0 );
00212 if ( active_popup_client && active_popup_client->isOnAllDesktops() )
00213 desk_popup->setItemChecked( 0, TRUE );
00214 desk_popup->insertSeparator( -1 );
00215 int id;
00216 const int BASE = 10;
00217 for ( int i = 1; i <= numberOfDesktops(); i++ )
00218 {
00219 QString basic_name("%1 %2");
00220 if (i<BASE)
00221 {
00222 basic_name.prepend('&');
00223 }
00224 id = desk_popup->insertItem(
00225 basic_name
00226 .arg(i)
00227 .arg( desktopName(i).replace( '&', "&&" )),
00228 i );
00229 if ( active_popup_client &&
00230 !active_popup_client->isOnAllDesktops() && active_popup_client->desktop() == i )
00231 desk_popup->setItemChecked( id, TRUE );
00232 }
00233 }
00234
00235 void Workspace::closeActivePopup()
00236 {
00237 if( active_popup )
00238 {
00239 active_popup->close();
00240 active_popup = NULL;
00241 active_popup_client = NULL;
00242 }
00243 }
00244
00248 void Workspace::initShortcuts()
00249 {
00250 keys = new KGlobalAccel( this );
00251
00252
00253 disable_shortcuts_keys = new KGlobalAccel( this );
00254 disable_shortcuts_keys->disableBlocking( true );
00255 #define IN_KWIN
00256 #include "kwinbindings.cpp"
00257 readShortcuts();
00258 }
00259
00260 void Workspace::readShortcuts()
00261 {
00262 keys->readSettings();
00263 disable_shortcuts_keys->readSettings();
00264
00265 cutWalkThroughDesktops = keys->shortcut("Walk Through Desktops");
00266 cutWalkThroughDesktopsReverse = keys->shortcut("Walk Through Desktops (Reverse)");
00267 cutWalkThroughDesktopList = keys->shortcut("Walk Through Desktop List");
00268 cutWalkThroughDesktopListReverse = keys->shortcut("Walk Through Desktop List (Reverse)");
00269 cutWalkThroughWindows = keys->shortcut("Walk Through Windows");
00270 cutWalkThroughWindowsReverse = keys->shortcut("Walk Through Windows (Reverse)");
00271
00272 keys->updateConnections();
00273 disable_shortcuts_keys->updateConnections();
00274
00275 delete popup;
00276 popup = NULL;
00277 desk_popup = NULL;
00278 }
00279
00280
00281 void Workspace::setupWindowShortcut( Client* c )
00282 {
00283 assert( client_keys_dialog == NULL );
00284 keys->suspend( true );
00285 disable_shortcuts_keys->suspend( true );
00286 client_keys->suspend( true );
00287 client_keys_dialog = new ShortcutDialog( c->shortcut());
00288 client_keys_client = c;
00289 connect( client_keys_dialog, SIGNAL( dialogDone( bool )), SLOT( setupWindowShortcutDone( bool )));
00290 QRect r = clientArea( ScreenArea, c );
00291 QSize size = client_keys_dialog->sizeHint();
00292 QPoint pos = c->pos() + c->clientPos();
00293 if( pos.x() + size.width() >= r.right())
00294 pos.setX( r.right() - size.width());
00295 if( pos.y() + size.height() >= r.bottom())
00296 pos.setY( r.bottom() - size.height());
00297 client_keys_dialog->move( pos );
00298 client_keys_dialog->show();
00299 active_popup = client_keys_dialog;
00300 active_popup_client = c;
00301 }
00302
00303 void Workspace::setupWindowShortcutDone( bool ok )
00304 {
00305 keys->suspend( false );
00306 disable_shortcuts_keys->suspend( false );
00307 client_keys->suspend( false );
00308 if( ok )
00309 {
00310 client_keys_client->setShortcut( KShortcut( client_keys_dialog->shortcut()).toString());
00311 }
00312 closeActivePopup();
00313 delete client_keys_dialog;
00314 client_keys_dialog = NULL;
00315 client_keys_client = NULL;
00316 }
00317
00318 void Workspace::clientShortcutUpdated( Client* c )
00319 {
00320 QString key = QString::number( c->window());
00321 client_keys->remove( key );
00322 if( !c->shortcut().isNull())
00323 {
00324 client_keys->insert( key, key );
00325 client_keys->setShortcut( key, c->shortcut());
00326 client_keys->setSlot( key, c, SLOT( shortcutActivated()));
00327 client_keys->setActionEnabled( key, true );
00328 }
00329 client_keys->updateConnections();
00330 }
00331
00332 void Workspace::clientPopupActivated( int id )
00333 {
00334 WindowOperation op = static_cast< WindowOperation >( id );
00335 Client* c = active_popup_client ? active_popup_client : active_client;
00336 QString type;
00337 switch( op )
00338 {
00339 case FullScreenOp:
00340 if( !c->isFullScreen() && c->userCanSetFullScreen())
00341 type = "fullscreenaltf3";
00342 break;
00343 case NoBorderOp:
00344 if( !c->noBorder() && c->userCanSetNoBorder())
00345 type = "noborderaltf3";
00346 break;
00347 default:
00348 break;
00349 };
00350 if( !type.isEmpty())
00351 helperDialog( type, c );
00352 performWindowOperation( c, op );
00353 }
00354
00355
00356 void Workspace::performWindowOperation( Client* c, Options::WindowOperation op )
00357 {
00358 if ( !c )
00359 return;
00360
00361 if (op == Options::MoveOp || op == Options::UnrestrictedMoveOp )
00362 QCursor::setPos( c->geometry().center() );
00363 if (op == Options::ResizeOp || op == Options::UnrestrictedResizeOp )
00364 QCursor::setPos( c->geometry().bottomRight());
00365 switch ( op )
00366 {
00367 case Options::MoveOp:
00368 c->performMouseCommand( Options::MouseMove, QCursor::pos() );
00369 break;
00370 case Options::UnrestrictedMoveOp:
00371 c->performMouseCommand( Options::MouseUnrestrictedMove, QCursor::pos() );
00372 break;
00373 case Options::ResizeOp:
00374 c->performMouseCommand( Options::MouseResize, QCursor::pos() );
00375 break;
00376 case Options::UnrestrictedResizeOp:
00377 c->performMouseCommand( Options::MouseUnrestrictedResize, QCursor::pos() );
00378 break;
00379 case Options::CloseOp:
00380 c->closeWindow();
00381 break;
00382 case Options::MaximizeOp:
00383 c->maximize( c->maximizeMode() == Client::MaximizeFull
00384 ? Client::MaximizeRestore : Client::MaximizeFull );
00385 break;
00386 case Options::HMaximizeOp:
00387 c->maximize( c->maximizeMode() ^ Client::MaximizeHorizontal );
00388 break;
00389 case Options::VMaximizeOp:
00390 c->maximize( c->maximizeMode() ^ Client::MaximizeVertical );
00391 break;
00392 case Options::RestoreOp:
00393 c->maximize( Client::MaximizeRestore );
00394 break;
00395 case Options::MinimizeOp:
00396 c->minimize();
00397 break;
00398 case Options::ShadeOp:
00399 c->performMouseCommand( Options::MouseShade, QCursor::pos());
00400 break;
00401 case Options::OnAllDesktopsOp:
00402 c->setOnAllDesktops( !c->isOnAllDesktops() );
00403 break;
00404 case Options::FullScreenOp:
00405 c->setFullScreen( !c->isFullScreen(), true );
00406 break;
00407 case Options::NoBorderOp:
00408 c->setUserNoBorder( !c->isUserNoBorder());
00409 break;
00410 case Options::KeepAboveOp:
00411 {
00412 StackingUpdatesBlocker blocker( this );
00413 bool was = c->keepAbove();
00414 c->setKeepAbove( !c->keepAbove() );
00415 if( was && !c->keepAbove())
00416 raiseClient( c );
00417 break;
00418 }
00419 case Options::KeepBelowOp:
00420 {
00421 StackingUpdatesBlocker blocker( this );
00422 bool was = c->keepBelow();
00423 c->setKeepBelow( !c->keepBelow() );
00424 if( was && !c->keepBelow())
00425 lowerClient( c );
00426 break;
00427 }
00428 case Options::OperationsOp:
00429 c->performMouseCommand( Options::MouseShade, QCursor::pos());
00430 break;
00431 case Options::WindowRulesOp:
00432 editWindowRules( c, false );
00433 break;
00434 case Options::ApplicationRulesOp:
00435 editWindowRules( c, true );
00436 break;
00437 case Options::SetupWindowShortcutOp:
00438 setupWindowShortcut( c );
00439 break;
00440 case Options::LowerOp:
00441 lowerClient(c);
00442 break;
00443 case Options::NoOp:
00444 break;
00445 }
00446 }
00447
00451 bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPos, bool handled )
00452 {
00453 bool replay = FALSE;
00454 switch (command)
00455 {
00456 case Options::MouseRaise:
00457 workspace()->raiseClient( this );
00458 break;
00459 case Options::MouseLower:
00460 workspace()->lowerClient( this );
00461 break;
00462 case Options::MouseShade :
00463 toggleShade();
00464 cancelShadeHover();
00465 break;
00466 case Options::MouseSetShade:
00467 setShade( ShadeNormal );
00468 cancelShadeHover();
00469 break;
00470 case Options::MouseUnsetShade:
00471 setShade( ShadeNone );
00472 cancelShadeHover();
00473 break;
00474 case Options::MouseOperationsMenu:
00475 if ( isActive() && options->clickRaise )
00476 autoRaise();
00477 workspace()->showWindowMenu( globalPos, this );
00478 break;
00479 case Options::MouseToggleRaiseAndLower:
00480 workspace()->raiseOrLowerClient( this );
00481 break;
00482 case Options::MouseActivateAndRaise:
00483 replay = isActive();
00484 workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled && replay );
00485 break;
00486 case Options::MouseActivateAndLower:
00487 workspace()->requestFocus( this );
00488 workspace()->lowerClient( this );
00489 break;
00490 case Options::MouseActivate:
00491 replay = isActive();
00492 workspace()->takeActivity( this, ActivityFocus, handled && replay );
00493 break;
00494 case Options::MouseActivateRaiseAndPassClick:
00495 workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled );
00496 replay = TRUE;
00497 break;
00498 case Options::MouseActivateAndPassClick:
00499 workspace()->takeActivity( this, ActivityFocus, handled );
00500 replay = TRUE;
00501 break;
00502 case Options::MouseActivateRaiseAndMove:
00503 case Options::MouseActivateRaiseAndUnrestrictedMove:
00504 workspace()->raiseClient( this );
00505 workspace()->requestFocus( this );
00506 if( options->moveMode == Options::Transparent && isMovable())
00507 move_faked_activity = workspace()->fakeRequestedActivity( this );
00508
00509 case Options::MouseMove:
00510 case Options::MouseUnrestrictedMove:
00511 {
00512 if (!isMovable())
00513 break;
00514 if( moveResizeMode )
00515 finishMoveResize( false );
00516 mode = PositionCenter;
00517 buttonDown = TRUE;
00518 moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y());
00519 invertedMoveOffset = rect().bottomRight() - moveOffset;
00520 unrestrictedMoveResize = ( command == Options::MouseActivateRaiseAndUnrestrictedMove
00521 || command == Options::MouseUnrestrictedMove );
00522 setCursor( mode );
00523 if( !startMoveResize())
00524 {
00525 buttonDown = false;
00526 setCursor( mode );
00527 }
00528 break;
00529 }
00530 case Options::MouseResize:
00531 case Options::MouseUnrestrictedResize:
00532 {
00533 if (!isResizable() || isShade())
00534 break;
00535 if( moveResizeMode )
00536 finishMoveResize( false );
00537 buttonDown = TRUE;
00538 moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y());
00539 int x = moveOffset.x(), y = moveOffset.y();
00540 bool left = x < width() / 3;
00541 bool right = x >= 2 * width() / 3;
00542 bool top = y < height() / 3;
00543 bool bot = y >= 2 * height() / 3;
00544 if (top)
00545 mode = left ? PositionTopLeft : (right ? PositionTopRight : PositionTop);
00546 else if (bot)
00547 mode = left ? PositionBottomLeft : (right ? PositionBottomRight : PositionBottom);
00548 else
00549 mode = (x < width() / 2) ? PositionLeft : PositionRight;
00550 invertedMoveOffset = rect().bottomRight() - moveOffset;
00551 unrestrictedMoveResize = ( command == Options::MouseUnrestrictedResize );
00552 setCursor( mode );
00553 if( !startMoveResize())
00554 {
00555 buttonDown = false;
00556 setCursor( mode );
00557 }
00558 break;
00559 }
00560 case Options::MouseMaximize:
00561 maximize( Client::MaximizeFull );
00562 break;
00563 case Options::MouseRestore:
00564 maximize( Client::MaximizeRestore );
00565 break;
00566 case Options::MouseMinimize:
00567 minimize();
00568 break;
00569 case Options::MouseAbove:
00570 {
00571 StackingUpdatesBlocker blocker( workspace());
00572 if( keepBelow())
00573 setKeepBelow( false );
00574 else
00575 setKeepAbove( true );
00576 break;
00577 }
00578 case Options::MouseBelow:
00579 {
00580 StackingUpdatesBlocker blocker( workspace());
00581 if( keepAbove())
00582 setKeepAbove( false );
00583 else
00584 setKeepBelow( true );
00585 break;
00586 }
00587 case Options::MousePreviousDesktop:
00588 workspace()->windowToPreviousDesktop( this );
00589 break;
00590 case Options::MouseNextDesktop:
00591 workspace()->windowToNextDesktop( this );
00592 break;
00593 case Options::MouseOpacityMore:
00594 if (opacity_ < 0xFFFFFFFF)
00595 {
00596 if (opacity_ < 0xF3333333)
00597 {
00598 setOpacity(TRUE, opacity_ + 0xCCCCCCC);
00599 custom_opacity = true;
00600 }
00601 else
00602 {
00603 setOpacity(FALSE, 0xFFFFFFFF);
00604 custom_opacity = false;
00605 }
00606 }
00607 break;
00608 case Options::MouseOpacityLess:
00609 if (opacity_ > 0)
00610 {
00611 setOpacity(TRUE, (opacity_ > 0xCCCCCCC) ? opacity_ - 0xCCCCCCC : 0);
00612 custom_opacity = true;
00613 }
00614 break;
00615 case Options::MouseNothing:
00616 replay = TRUE;
00617 break;
00618 }
00619 return replay;
00620 }
00621
00622
00623 void Workspace::showWindowMenuAt( unsigned long, int, int )
00624 {
00625 slotWindowOperations();
00626 }
00627
00628 void Workspace::slotActivateAttentionWindow()
00629 {
00630 if( attention_chain.count() > 0 )
00631 activateClient( attention_chain.first());
00632 }
00633
00634 void Workspace::slotSwitchDesktopNext()
00635 {
00636 int d = currentDesktop() + 1;
00637 if ( d > numberOfDesktops() )
00638 {
00639 if ( options->rollOverDesktops )
00640 {
00641 d = 1;
00642 }
00643 else
00644 {
00645 return;
00646 }
00647 }
00648 setCurrentDesktop(d);
00649 }
00650
00651 void Workspace::slotSwitchDesktopPrevious()
00652 {
00653 int d = currentDesktop() - 1;
00654 if ( d <= 0 )
00655 {
00656 if ( options->rollOverDesktops )
00657 d = numberOfDesktops();
00658 else
00659 return;
00660 }
00661 setCurrentDesktop(d);
00662 }
00663
00664 void Workspace::slotSwitchDesktopRight()
00665 {
00666 int desktop = desktopToRight( currentDesktop());
00667 if( desktop == currentDesktop())
00668 return;
00669 setCurrentDesktop( desktop );
00670 }
00671
00672 void Workspace::slotSwitchDesktopLeft()
00673 {
00674 int desktop = desktopToLeft( currentDesktop());
00675 if( desktop == currentDesktop())
00676 return;
00677 setCurrentDesktop( desktop );
00678 }
00679
00680 void Workspace::slotSwitchDesktopUp()
00681 {
00682 int desktop = desktopUp( currentDesktop());
00683 if( desktop == currentDesktop())
00684 return;
00685 setCurrentDesktop( desktop );
00686 }
00687
00688 void Workspace::slotSwitchDesktopDown()
00689 {
00690 int desktop = desktopDown( currentDesktop());
00691 if( desktop == currentDesktop())
00692 return;
00693 setCurrentDesktop( desktop );
00694 }
00695
00696 void Workspace::slotSwitchToDesktop( int i )
00697 {
00698 setCurrentDesktop( i );
00699 }
00700
00701
00702 void Workspace::slotWindowToDesktop( int i )
00703 {
00704 Client* c = active_popup_client ? active_popup_client : active_client;
00705 if( i >= 1 && i <= numberOfDesktops() && c
00706 && !c->isDesktop()
00707 && !c->isDock()
00708 && !c->isTopMenu())
00709 sendClientToDesktop( c, i, true );
00710 }
00711
00715 void Workspace::slotWindowMaximize()
00716 {
00717 Client* c = active_popup_client ? active_popup_client : active_client;
00718 if ( c )
00719 performWindowOperation( c, Options::MaximizeOp );
00720 }
00721
00725 void Workspace::slotWindowMaximizeVertical()
00726 {
00727 Client* c = active_popup_client ? active_popup_client : active_client;
00728 if ( c )
00729 performWindowOperation( c, Options::VMaximizeOp );
00730 }
00731
00735 void Workspace::slotWindowMaximizeHorizontal()
00736 {
00737 Client* c = active_popup_client ? active_popup_client : active_client;
00738 if ( c )
00739 performWindowOperation( c, Options::HMaximizeOp );
00740 }
00741
00742
00746 void Workspace::slotWindowMinimize()
00747 {
00748 Client* c = active_popup_client ? active_popup_client : active_client;
00749 performWindowOperation( c, Options::MinimizeOp );
00750 }
00751
00755 void Workspace::slotWindowShade()
00756 {
00757 Client* c = active_popup_client ? active_popup_client : active_client;
00758 performWindowOperation( c, Options::ShadeOp );
00759 }
00760
00764 void Workspace::slotWindowRaise()
00765 {
00766 Client* c = active_popup_client ? active_popup_client : active_client;
00767 if ( c )
00768 raiseClient( c );
00769 }
00770
00774 void Workspace::slotWindowLower()
00775 {
00776 Client* c = active_popup_client ? active_popup_client : active_client;
00777 if ( c )
00778 lowerClient( c );
00779 }
00780
00784 void Workspace::slotWindowRaiseOrLower()
00785 {
00786 Client* c = active_popup_client ? active_popup_client : active_client;
00787 if ( c )
00788 raiseOrLowerClient( c );
00789 }
00790
00791 void Workspace::slotWindowOnAllDesktops()
00792 {
00793 Client* c = active_popup_client ? active_popup_client : active_client;
00794 if( c )
00795 c->setOnAllDesktops( !c->isOnAllDesktops());
00796 }
00797
00798 void Workspace::slotWindowFullScreen()
00799 {
00800 Client* c = active_popup_client ? active_popup_client : active_client;
00801 if( c )
00802 performWindowOperation( c, Options::FullScreenOp );
00803 }
00804
00805 void Workspace::slotWindowNoBorder()
00806 {
00807 Client* c = active_popup_client ? active_popup_client : active_client;
00808 if( c )
00809 performWindowOperation( c, Options::NoBorderOp );
00810 }
00811
00812 void Workspace::slotWindowAbove()
00813 {
00814 Client* c = active_popup_client ? active_popup_client : active_client;
00815 if( c )
00816 performWindowOperation( c, Options::KeepAboveOp );
00817 }
00818
00819 void Workspace::slotWindowBelow()
00820 {
00821 Client* c = active_popup_client ? active_popup_client : active_client;
00822 if( c )
00823 performWindowOperation( c, Options::KeepBelowOp );
00824 }
00825 void Workspace::slotSetupWindowShortcut()
00826 {
00827 Client* c = active_popup_client ? active_popup_client : active_client;
00828 if( c )
00829 performWindowOperation( c, Options::SetupWindowShortcutOp );
00830 }
00831
00835 void Workspace::slotWindowToNextDesktop()
00836 {
00837 windowToNextDesktop( active_popup_client ? active_popup_client : active_client );
00838 }
00839
00840 void Workspace::windowToNextDesktop( Client* c )
00841 {
00842 int d = currentDesktop() + 1;
00843 if ( d > numberOfDesktops() )
00844 d = 1;
00845 if (c && !c->isDesktop()
00846 && !c->isDock() && !c->isTopMenu())
00847 {
00848 setClientIsMoving( c );
00849 setCurrentDesktop( d );
00850 setClientIsMoving( NULL );
00851 }
00852 }
00853
00857 void Workspace::slotWindowToPreviousDesktop()
00858 {
00859 windowToPreviousDesktop( active_popup_client ? active_popup_client : active_client );
00860 }
00861
00862 void Workspace::windowToPreviousDesktop( Client* c )
00863 {
00864 int d = currentDesktop() - 1;
00865 if ( d <= 0 )
00866 d = numberOfDesktops();
00867 if (c && !c->isDesktop()
00868 && !c->isDock() && !c->isTopMenu())
00869 {
00870 setClientIsMoving( c );
00871 setCurrentDesktop( d );
00872 setClientIsMoving( NULL );
00873 }
00874 }
00875
00876 void Workspace::slotWindowToDesktopRight()
00877 {
00878 int d = desktopToRight( currentDesktop());
00879 if( d == currentDesktop())
00880 return;
00881 Client* c = active_popup_client ? active_popup_client : active_client;
00882 if (c && !c->isDesktop()
00883 && !c->isDock() && !c->isTopMenu())
00884 {
00885 setClientIsMoving( c );
00886 setCurrentDesktop( d );
00887 setClientIsMoving( NULL );
00888 }
00889 }
00890
00891 void Workspace::slotWindowToDesktopLeft()
00892 {
00893 int d = desktopToLeft( currentDesktop());
00894 if( d == currentDesktop())
00895 return;
00896 Client* c = active_popup_client ? active_popup_client : active_client;
00897 if (c && !c->isDesktop()
00898 && !c->isDock() && !c->isTopMenu())
00899 {
00900 setClientIsMoving( c );
00901 setCurrentDesktop( d );
00902 setClientIsMoving( NULL );
00903 }
00904 }
00905
00906 void Workspace::slotWindowToDesktopUp()
00907 {
00908 int d = desktopUp( currentDesktop());
00909 if( d == currentDesktop())
00910 return;
00911 Client* c = active_popup_client ? active_popup_client : active_client;
00912 if (c && !c->isDesktop()
00913 && !c->isDock() && !c->isTopMenu())
00914 {
00915 setClientIsMoving( c );
00916 setCurrentDesktop( d );
00917 setClientIsMoving( NULL );
00918 }
00919 }
00920
00921 void Workspace::slotWindowToDesktopDown()
00922 {
00923 int d = desktopDown( currentDesktop());
00924 if( d == currentDesktop())
00925 return;
00926 Client* c = active_popup_client ? active_popup_client : active_client;
00927 if (c && !c->isDesktop()
00928 && !c->isDock() && !c->isTopMenu())
00929 {
00930 setClientIsMoving( c );
00931 setCurrentDesktop( d );
00932 setClientIsMoving( NULL );
00933 }
00934 }
00935
00936
00940 void Workspace::slotKillWindow()
00941 {
00942 KillWindow kill( this );
00943 kill.start();
00944 }
00945
00951 void Workspace::slotSendToDesktop( int desk )
00952 {
00953 if ( !active_popup_client )
00954 return;
00955 if ( desk == 0 )
00956 {
00957 active_popup_client->setOnAllDesktops( !active_popup_client->isOnAllDesktops());
00958 return;
00959 }
00960
00961 sendClientToDesktop( active_popup_client, desk, false );
00962
00963 }
00964
00968 void Workspace::slotWindowOperations()
00969 {
00970 if ( !active_client )
00971 return;
00972 QPoint pos = active_client->pos() + active_client->clientPos();
00973 showWindowMenu( pos.x(), pos.y(), active_client );
00974 }
00975
00976 void Workspace::showWindowMenu( const QRect &pos, Client* cl )
00977 {
00978 if (!kapp->authorizeKAction("kwin_rmb"))
00979 return;
00980 if( !cl )
00981 return;
00982 if( active_popup_client != NULL )
00983 return;
00984 if ( cl->isDesktop()
00985 || cl->isDock()
00986 || cl->isTopMenu())
00987 return;
00988
00989 active_popup_client = cl;
00990 QPopupMenu* p = clientPopup();
00991 active_popup = p;
00992 int x = pos.left();
00993 int y = pos.bottom();
00994 if (y == pos.top())
00995 p->exec( QPoint( x, y ) );
00996 else
00997 {
00998 QRect area = clientArea(ScreenArea, QPoint(x, y), currentDesktop());
00999 clientPopupAboutToShow();
01000 int popupHeight = p->sizeHint().height();
01001 if (y + popupHeight < area.height())
01002 p->exec( QPoint( x, y ) );
01003 else
01004 p->exec( QPoint( x, pos.top() - popupHeight ) );
01005 }
01006
01007 if( active_popup == p )
01008 closeActivePopup();
01009 }
01010
01014 void Workspace::slotWindowClose()
01015 {
01016 if ( tab_box->isVisible())
01017 return;
01018 Client* c = active_popup_client ? active_popup_client : active_client;
01019 performWindowOperation( c, Options::CloseOp );
01020 }
01021
01025 void Workspace::slotWindowMove()
01026 {
01027 Client* c = active_popup_client ? active_popup_client : active_client;
01028 performWindowOperation( c, Options::UnrestrictedMoveOp );
01029 }
01030
01034 void Workspace::slotWindowResize()
01035 {
01036 Client* c = active_popup_client ? active_popup_client : active_client;
01037 performWindowOperation( c, Options::UnrestrictedResizeOp );
01038 }
01039
01040 void Client::setShortcut( const QString& _cut )
01041 {
01042 QString cut = rules()->checkShortcut( _cut );
01043 if( cut.isEmpty())
01044 return setShortcutInternal( KShortcut());
01045
01046
01047
01048 if( !cut.contains( '(' ) && !cut.contains( ')' ) && !cut.contains( ' ' ))
01049 {
01050 if( workspace()->shortcutAvailable( KShortcut( cut ), this ))
01051 setShortcutInternal( KShortcut( cut ));
01052 else
01053 setShortcutInternal( KShortcut());
01054 return;
01055 }
01056 QValueList< KShortcut > keys;
01057 QStringList groups = QStringList::split( ' ', cut );
01058 for( QStringList::ConstIterator it = groups.begin();
01059 it != groups.end();
01060 ++it )
01061 {
01062 QRegExp reg( "(.*\\+)\\((.*)\\)" );
01063 if( reg.search( *it ) > -1 )
01064 {
01065 QString base = reg.cap( 1 );
01066 QString list = reg.cap( 2 );
01067 for( unsigned int i = 0;
01068 i < list.length();
01069 ++i )
01070 {
01071 KShortcut c( base + list[ i ] );
01072 if( !c.isNull())
01073 keys.append( c );
01074 }
01075 }
01076 }
01077 for( QValueList< KShortcut >::ConstIterator it = keys.begin();
01078 it != keys.end();
01079 ++it )
01080 {
01081 if( _shortcut == *it )
01082 return;
01083 }
01084 for( QValueList< KShortcut >::ConstIterator it = keys.begin();
01085 it != keys.end();
01086 ++it )
01087 {
01088 if( workspace()->shortcutAvailable( *it, this ))
01089 {
01090 setShortcutInternal( *it );
01091 return;
01092 }
01093 }
01094 setShortcutInternal( KShortcut());
01095 }
01096
01097 void Client::setShortcutInternal( const KShortcut& cut )
01098 {
01099 if( _shortcut == cut )
01100 return;
01101 _shortcut = cut;
01102 updateCaption();
01103 workspace()->clientShortcutUpdated( this );
01104 }
01105
01106 bool Workspace::shortcutAvailable( const KShortcut& cut, Client* ignore ) const
01107 {
01108
01109 for( ClientList::ConstIterator it = clients.begin();
01110 it != clients.end();
01111 ++it )
01112 {
01113 if( (*it) != ignore && (*it)->shortcut() == cut )
01114 return false;
01115 }
01116 return true;
01117 }
01118
01119 }