00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "client.h"
00031 #include "workspace.h"
00032 #include "effects.h"
00033
00034 #include <fixx11h.h>
00035 #include <QPushButton>
00036 #include <QSlider>
00037
00038 #include <kglobalsettings.h>
00039 #include <kiconloader.h>
00040 #include <klocale.h>
00041 #include <kconfig.h>
00042 #include <kglobalaccel.h>
00043 #include <kapplication.h>
00044 #include <QRegExp>
00045 #include <QMenu>
00046 #include <QVBoxLayout>
00047 #include <kauthorized.h>
00048 #include <kactioncollection.h>
00049 #include <kaction.h>
00050
00051 #include "killwindow.h"
00052 #include "tabbox.h"
00053
00054 namespace KWin
00055 {
00056
00057
00058
00059
00060
00061 QMenu* Workspace::clientPopup()
00062 {
00063 if ( !popup )
00064 {
00065 popup = new QMenu;
00066 popup->setFont(KGlobalSettings::menuFont());
00067 connect( popup, SIGNAL( aboutToShow() ), this, SLOT( clientPopupAboutToShow() ) );
00068 connect( popup, SIGNAL( triggered(QAction*) ), this, SLOT( clientPopupActivated(QAction*) ) );
00069
00070 advanced_popup = new QMenu( popup );
00071 advanced_popup->setFont(KGlobalSettings::menuFont());
00072
00073 mKeepAboveOpAction = advanced_popup->addAction( i18n("Keep &Above Others") );
00074 mKeepAboveOpAction->setIcon( KIcon( "go-up" ) );
00075 KAction *kaction = qobject_cast<KAction*>( keys->action("Window Above Other Windows") );
00076 if ( kaction!=0 )
00077 mKeepAboveOpAction->setShortcut( kaction->globalShortcut().primary() );
00078 mKeepAboveOpAction->setCheckable( true );
00079 mKeepAboveOpAction->setData( Options::KeepAboveOp );
00080
00081 mKeepBelowOpAction = advanced_popup->addAction( i18n("Keep &Below Others") );
00082 mKeepBelowOpAction->setIcon( KIcon( "go-down" ) );
00083 kaction = qobject_cast<KAction*>( keys->action("Window Below Other Windows") );
00084 if ( kaction!=0 )
00085 mKeepBelowOpAction->setShortcut( kaction->globalShortcut().primary() );
00086 mKeepBelowOpAction->setCheckable( true );
00087 mKeepBelowOpAction->setData( Options::KeepBelowOp );
00088
00089 mFullScreenOpAction = advanced_popup->addAction( i18n("&Fullscreen") );
00090 mFullScreenOpAction->setIcon( KIcon( "view-fullscreen" ) );
00091 kaction = qobject_cast<KAction*>( keys->action("Window Fullscreen") );
00092 if ( kaction!=0 )
00093 mFullScreenOpAction->setShortcut( kaction->globalShortcut().primary() );
00094 mFullScreenOpAction->setCheckable( true );
00095 mFullScreenOpAction->setData( Options::FullScreenOp );
00096
00097 mNoBorderOpAction = advanced_popup->addAction( i18n("&No Border") );
00098 kaction = qobject_cast<KAction*>( keys->action("Window No Border") );
00099 if ( kaction!=0 )
00100 mNoBorderOpAction->setShortcut( kaction->globalShortcut().primary() );
00101 mNoBorderOpAction->setCheckable( true );
00102 mNoBorderOpAction->setData( Options::NoBorderOp );
00103
00104 QAction *action = advanced_popup->addAction( i18n("Window &Shortcut...") );
00105 action->setIcon( KIcon("configure-shortcuts") );
00106 kaction = qobject_cast<KAction*>( keys->action("Setup Window Shortcut") );
00107 if ( kaction!=0 )
00108 action->setShortcut( kaction->globalShortcut().primary() );
00109 action->setData( Options::SetupWindowShortcutOp );
00110
00111 action = advanced_popup->addAction( i18n("&Special Window Settings...") );
00112 action->setIcon( KIcon( "wizard" ) );
00113 action->setData( Options::WindowRulesOp );
00114
00115 action = advanced_popup->addAction( i18n("&Special Application Settings...") );
00116 action->setIcon( KIcon( "wizard" ) );
00117 action->setData( Options::ApplicationRulesOp );
00118
00119 action = popup->addMenu( advanced_popup );
00120 action->setText( i18n("Ad&vanced") );
00121
00122 trans_popup = 0;
00123 if (compositing()){
00124 trans_popup = new QMenu( popup );
00125 trans_popup->setFont(KGlobalSettings::menuFont());
00126 connect( trans_popup, SIGNAL( triggered(QAction*) ), this, SLOT( setPopupClientOpacity(QAction*)));
00127 const int levels[] = { 100, 90, 75, 50, 25, 10 };
00128 for( unsigned int i = 0;
00129 i < sizeof( levels ) / sizeof( levels[ 0 ] );
00130 ++i )
00131 {
00132 action = trans_popup->addAction( QString::number( levels[ i ] ) + "%" );
00133 action->setCheckable( true );
00134 action->setData( levels[ i ] );
00135 }
00136 action = popup->addMenu( trans_popup );
00137 action->setText( i18n("&Opacity") );
00138 }
00139
00140 mMoveOpAction = popup->addAction( i18n("&Move") );
00141 mMoveOpAction->setIcon( KIcon( "transform-move" ) );
00142 kaction = qobject_cast<KAction*>( keys->action("Window Move") );
00143 if ( kaction!=0 )
00144 mMoveOpAction->setShortcut( kaction->globalShortcut().primary() );
00145 mMoveOpAction->setData( Options::MoveOp );
00146
00147 mResizeOpAction = popup->addAction( i18n("Re&size") );
00148 kaction = qobject_cast<KAction*>( keys->action("Window Resize") );
00149 if ( kaction!=0 )
00150 mResizeOpAction->setShortcut( kaction->globalShortcut().primary() );
00151 mResizeOpAction->setData( Options::ResizeOp );
00152
00153 mMinimizeOpAction = popup->addAction( i18n("Mi&nimize") );
00154 kaction = qobject_cast<KAction*>( keys->action("Window Minimize") );
00155 if ( kaction!=0 )
00156 mMinimizeOpAction->setShortcut( kaction->globalShortcut().primary() );
00157 mMinimizeOpAction->setData( Options::MinimizeOp );
00158
00159 mMaximizeOpAction = popup->addAction( i18n("Ma&ximize") );
00160 kaction = qobject_cast<KAction*>( keys->action("Window Maximize") );
00161 if ( kaction!=0 )
00162 mMaximizeOpAction->setShortcut( kaction->globalShortcut().primary() );
00163 mMaximizeOpAction->setCheckable( true );
00164 mMaximizeOpAction->setData( Options::MaximizeOp );
00165
00166 mShadeOpAction = popup->addAction( i18n("Sh&ade") );
00167 kaction = qobject_cast<KAction*>( keys->action("Window Shade") );
00168 if ( kaction!=0 )
00169 mShadeOpAction->setShortcut( kaction->globalShortcut().primary() );
00170 mShadeOpAction->setCheckable( true );
00171 mShadeOpAction->setData( Options::ShadeOp );
00172
00173 popup->addSeparator();
00174
00175 if (!KGlobal::config()->isImmutable() &&
00176 !KAuthorized::authorizeControlModules(Workspace::configModules(true)).isEmpty())
00177 {
00178 action = popup->addAction( i18n("Configur&e Window Behavior...") );
00179 action->setIcon( KIcon( "configure" ) );
00180 connect( action, SIGNAL( triggered() ), this, SLOT( configureWM() ) );
00181 popup->addSeparator();
00182 }
00183
00184 mCloseOpAction = popup->addAction( i18n("&Close") );
00185 mCloseOpAction->setIcon( KIcon( "window-close" ) );
00186 kaction = qobject_cast<KAction*>( keys->action("Window Close") );
00187 if ( kaction!=0 )
00188 mCloseOpAction->setShortcut( kaction->globalShortcut().primary() );
00189 mCloseOpAction->setData( Options::CloseOp );
00190 }
00191 return popup;
00192 }
00193
00194 void Workspace::setPopupClientOpacity( QAction* action )
00195 {
00196 if( active_popup_client == NULL )
00197 return;
00198 int level = action->data().toInt();
00199 active_popup_client->setOpacity( level / 100.0 );
00200 }
00201
00207 void Workspace::clientPopupAboutToShow()
00208 {
00209 if ( !active_popup_client || !popup )
00210 return;
00211
00212 if ( numberOfDesktops() == 1 )
00213 {
00214 delete desk_popup;
00215 desk_popup = 0;
00216 }
00217 else
00218 {
00219 initDesktopPopup();
00220 }
00221
00222 mResizeOpAction->setEnabled( active_popup_client->isResizable() );
00223 mMoveOpAction->setEnabled( active_popup_client->isMovable() );
00224 mMaximizeOpAction->setEnabled( active_popup_client->isMaximizable() );
00225 mMaximizeOpAction->setChecked( active_popup_client->maximizeMode() == Client::MaximizeFull );
00226 mShadeOpAction->setEnabled( active_popup_client->isShadeable() );
00227 mShadeOpAction->setChecked( active_popup_client->shadeMode() != ShadeNone );
00228 mKeepAboveOpAction->setChecked( active_popup_client->keepAbove() );
00229 mKeepBelowOpAction->setChecked( active_popup_client->keepBelow() );
00230 mFullScreenOpAction->setEnabled( active_popup_client->userCanSetFullScreen() );
00231 mFullScreenOpAction->setChecked( active_popup_client->isFullScreen() );
00232 mNoBorderOpAction->setEnabled( active_popup_client->userCanSetNoBorder() );
00233 mNoBorderOpAction->setChecked( active_popup_client->noBorder() );
00234 mMinimizeOpAction->setEnabled( active_popup_client->isMinimizable() );
00235 mCloseOpAction->setEnabled( active_popup_client->isCloseable() );
00236 if( trans_popup != NULL )
00237 {
00238 foreach( QAction* action, trans_popup->actions())
00239 {
00240 if( action->data().toInt() == qRound( active_popup_client->opacity() * 100 ))
00241 action->setChecked( true );
00242 else
00243 action->setChecked( false );
00244 }
00245 }
00246 }
00247
00248
00249 void Workspace::initDesktopPopup()
00250 {
00251 if (desk_popup)
00252 return;
00253
00254 desk_popup = new QMenu( popup );
00255 desk_popup->setFont(KGlobalSettings::menuFont());
00256 connect( desk_popup, SIGNAL( triggered(QAction*) ),
00257 this, SLOT( slotSendToDesktop(QAction*) ) );
00258 connect( desk_popup, SIGNAL( aboutToShow() ),
00259 this, SLOT( desktopPopupAboutToShow() ) );
00260
00261 QAction *action = desk_popup->menuAction();
00262 popup->insertAction(advanced_popup->menuAction(), action);
00263 action->setText( i18n("To &Desktop") );
00264 }
00265
00270 void Workspace::desktopPopupAboutToShow()
00271 {
00272 if ( !desk_popup )
00273 return;
00274
00275 desk_popup->clear();
00276 QAction *action = desk_popup->addAction( i18n("&All Desktops") );
00277 action->setData( 0 );
00278 action->setCheckable( true );
00279
00280 if ( active_popup_client && active_popup_client->isOnAllDesktops() )
00281 action->setChecked( true );
00282 desk_popup->addSeparator();
00283
00284 const int BASE = 10;
00285 for ( int i = 1; i <= numberOfDesktops(); i++ ) {
00286 QString basic_name("%1 %2");
00287 if (i<BASE) {
00288 basic_name.prepend('&');
00289 }
00290 action = desk_popup->addAction( basic_name.arg(i).arg( desktopName(i).replace( '&', "&&" ) ) );
00291 action->setData( i );
00292 action->setCheckable( true );
00293
00294 if ( active_popup_client &&
00295 !active_popup_client->isOnAllDesktops() && active_popup_client->desktop() == i )
00296 action->setChecked( true );
00297 }
00298 }
00299
00300 void Workspace::closeActivePopup()
00301 {
00302 if( active_popup )
00303 {
00304 active_popup->close();
00305 active_popup = NULL;
00306 active_popup_client = NULL;
00307 }
00308 }
00309
00313 void Workspace::initShortcuts()
00314 {
00315 keys = new KActionCollection( this );
00316 KActionCollection* actionCollection = keys;
00317 QAction* a = 0L;
00318
00319
00320
00321 disable_shortcuts_keys = new KActionCollection( this );
00322 #ifdef __GNUC__
00323 #warning TODO PORT ME (KGlobalAccel related)
00324 #endif
00325
00326
00327 #define IN_KWIN
00328 #include "kwinbindings.cpp"
00329 readShortcuts();
00330 }
00331
00332 void Workspace::readShortcuts()
00333 {
00334 #ifdef __GNUC__
00335 #warning TODO PORT ME (KGlobalAccel related)
00336 #endif
00337
00338
00339 KAction *kaction = qobject_cast<KAction*>( keys->action("Walk Through Desktops") );
00340 if ( kaction!=0 )
00341 cutWalkThroughDesktops = kaction->globalShortcut();
00342
00343 kaction = qobject_cast<KAction*>( keys->action("Walk Through Desktops (Reverse)") );
00344 if ( kaction!=0 )
00345 cutWalkThroughDesktopsReverse = kaction->globalShortcut();
00346
00347 kaction = qobject_cast<KAction*>( keys->action("Walk Through Desktop List") );
00348 if ( kaction!=0 )
00349 cutWalkThroughDesktopList = kaction->globalShortcut();
00350
00351 kaction = qobject_cast<KAction*>( keys->action("Walk Through Desktop List (Reverse)") );
00352 if ( kaction!=0 )
00353 cutWalkThroughDesktopListReverse = kaction->globalShortcut();
00354
00355 kaction = qobject_cast<KAction*>( keys->action("Walk Through Windows") );
00356 if ( kaction!=0 )
00357 cutWalkThroughWindows = kaction->globalShortcut();
00358
00359 kaction = qobject_cast<KAction*>( keys->action("Walk Through Windows (Reverse)") );
00360 if ( kaction!=0 )
00361 cutWalkThroughWindowsReverse = kaction->globalShortcut();
00362
00363 delete popup;
00364 popup = NULL;
00365 desk_popup = NULL;
00366 }
00367
00368
00369 void Workspace::setupWindowShortcut( Client* c )
00370 {
00371 assert( client_keys_dialog == NULL );
00372 #ifdef __GNUC__
00373 #warning TODO PORT ME (KGlobalAccel related)
00374 #endif
00375
00376
00377
00378 client_keys_dialog = new ShortcutDialog( c->shortcut().primary());
00379 client_keys_client = c;
00380 connect( client_keys_dialog, SIGNAL( dialogDone( bool )), SLOT( setupWindowShortcutDone( bool )));
00381 QRect r = clientArea( ScreenArea, c );
00382 QSize size = client_keys_dialog->sizeHint();
00383 QPoint pos = c->pos() + c->clientPos();
00384 if( pos.x() + size.width() >= r.right())
00385 pos.setX( r.right() - size.width());
00386 if( pos.y() + size.height() >= r.bottom())
00387 pos.setY( r.bottom() - size.height());
00388 client_keys_dialog->move( pos );
00389 client_keys_dialog->show();
00390 active_popup = client_keys_dialog;
00391 active_popup_client = c;
00392 }
00393
00394 void Workspace::setupWindowShortcutDone( bool ok )
00395 {
00396
00397
00398
00399 if( ok )
00400 client_keys_client->setShortcut( KShortcut( client_keys_dialog->shortcut()).toString());
00401 closeActivePopup();
00402 client_keys_dialog->deleteLater();
00403 client_keys_dialog = NULL;
00404 client_keys_client = NULL;
00405 }
00406
00407 void Workspace::clientShortcutUpdated( Client* c )
00408 {
00409 QString key = QString::number( c->window());
00410 QAction* action = client_keys->action( key.toLatin1().constData() );
00411 if( !c->shortcut().isEmpty())
00412 {
00413 if( action == NULL )
00414 {
00415 action = client_keys->addAction( key );
00416 connect( action, SIGNAL(triggered(bool)), c, SLOT(shortcutActivated()));
00417 }
00418
00419
00420 qobject_cast< KAction* >( action )->setGlobalShortcut(
00421 c->shortcut(), KAction::ActiveShortcut, KAction::NoAutoloading );
00422 action->setEnabled( true );
00423 }
00424 else
00425 {
00426 delete action;
00427 }
00428 }
00429
00430 void Workspace::clientPopupActivated( QAction *action )
00431 {
00432 if ( !action->data().isValid() )
00433 return;
00434
00435 WindowOperation op = static_cast< WindowOperation >( action->data().toInt() );
00436 Client* c = active_popup_client ? active_popup_client : active_client;
00437 QString type;
00438 switch( op )
00439 {
00440 case FullScreenOp:
00441 if( !c->isFullScreen() && c->userCanSetFullScreen())
00442 type = "fullscreenaltf3";
00443 break;
00444 case NoBorderOp:
00445 if( !c->noBorder() && c->userCanSetNoBorder())
00446 type = "noborderaltf3";
00447 break;
00448 default:
00449 break;
00450 };
00451 if( !type.isEmpty())
00452 helperDialog( type, c );
00453 performWindowOperation( c, op );
00454 }
00455
00456
00457 void Workspace::performWindowOperation( Client* c, Options::WindowOperation op )
00458 {
00459 if ( !c )
00460 return;
00461
00462 if (op == Options::MoveOp || op == Options::UnrestrictedMoveOp )
00463 QCursor::setPos( c->geometry().center() );
00464 if (op == Options::ResizeOp || op == Options::UnrestrictedResizeOp )
00465 QCursor::setPos( c->geometry().bottomRight());
00466 switch ( op )
00467 {
00468 case Options::MoveOp:
00469 c->performMouseCommand( Options::MouseMove, cursorPos() );
00470 break;
00471 case Options::UnrestrictedMoveOp:
00472 c->performMouseCommand( Options::MouseUnrestrictedMove, cursorPos() );
00473 break;
00474 case Options::ResizeOp:
00475 c->performMouseCommand( Options::MouseResize, cursorPos() );
00476 break;
00477 case Options::UnrestrictedResizeOp:
00478 c->performMouseCommand( Options::MouseUnrestrictedResize, cursorPos() );
00479 break;
00480 case Options::CloseOp:
00481 c->closeWindow();
00482 break;
00483 case Options::MaximizeOp:
00484 c->maximize( c->maximizeMode() == Client::MaximizeFull
00485 ? Client::MaximizeRestore : Client::MaximizeFull );
00486 break;
00487 case Options::HMaximizeOp:
00488 c->maximize( c->maximizeMode() ^ Client::MaximizeHorizontal );
00489 break;
00490 case Options::VMaximizeOp:
00491 c->maximize( c->maximizeMode() ^ Client::MaximizeVertical );
00492 break;
00493 case Options::RestoreOp:
00494 c->maximize( Client::MaximizeRestore );
00495 break;
00496 case Options::MinimizeOp:
00497 c->minimize();
00498 break;
00499 case Options::ShadeOp:
00500 c->performMouseCommand( Options::MouseShade, cursorPos());
00501 break;
00502 case Options::OnAllDesktopsOp:
00503 c->setOnAllDesktops( !c->isOnAllDesktops() );
00504 break;
00505 case Options::FullScreenOp:
00506 c->setFullScreen( !c->isFullScreen(), true );
00507 break;
00508 case Options::NoBorderOp:
00509 c->setNoBorder( !c->noBorder());
00510 break;
00511 case Options::KeepAboveOp:
00512 {
00513 StackingUpdatesBlocker blocker( this );
00514 bool was = c->keepAbove();
00515 c->setKeepAbove( !c->keepAbove() );
00516 if( was && !c->keepAbove())
00517 raiseClient( c );
00518 break;
00519 }
00520 case Options::KeepBelowOp:
00521 {
00522 StackingUpdatesBlocker blocker( this );
00523 bool was = c->keepBelow();
00524 c->setKeepBelow( !c->keepBelow() );
00525 if( was && !c->keepBelow())
00526 lowerClient( c );
00527 break;
00528 }
00529 case Options::OperationsOp:
00530 c->performMouseCommand( Options::MouseShade, cursorPos());
00531 break;
00532 case Options::WindowRulesOp:
00533 editWindowRules( c, false );
00534 break;
00535 case Options::ApplicationRulesOp:
00536 editWindowRules( c, true );
00537 break;
00538 case Options::SetupWindowShortcutOp:
00539 setupWindowShortcut( c );
00540 break;
00541 case Options::LowerOp:
00542 lowerClient(c);
00543 break;
00544 case Options::NoOp:
00545 break;
00546 }
00547 }
00548
00552 bool Client::performMouseCommand( Options::MouseCommand command, const QPoint &globalPos, bool handled )
00553 {
00554 bool replay = false;
00555 switch (command)
00556 {
00557 case Options::MouseRaise:
00558 workspace()->raiseClient( this );
00559 break;
00560 case Options::MouseLower:
00561 workspace()->lowerClient( this );
00562 break;
00563 case Options::MouseShade :
00564 toggleShade();
00565 cancelShadeHover();
00566 break;
00567 case Options::MouseSetShade:
00568 setShade( ShadeNormal );
00569 cancelShadeHover();
00570 break;
00571 case Options::MouseUnsetShade:
00572 setShade( ShadeNone );
00573 cancelShadeHover();
00574 break;
00575 case Options::MouseOperationsMenu:
00576 if ( isActive() && options->clickRaise )
00577 autoRaise();
00578 workspace()->showWindowMenu( globalPos, this );
00579 break;
00580 case Options::MouseToggleRaiseAndLower:
00581 workspace()->raiseOrLowerClient( this );
00582 break;
00583 case Options::MouseActivateAndRaise:
00584 replay = isActive();
00585 workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled && replay );
00586 workspace()->setActiveScreenMouse( globalPos );
00587 break;
00588 case Options::MouseActivateAndLower:
00589 workspace()->requestFocus( this );
00590 workspace()->lowerClient( this );
00591 workspace()->setActiveScreenMouse( globalPos );
00592 break;
00593 case Options::MouseActivate:
00594 replay = isActive();
00595 workspace()->takeActivity( this, ActivityFocus, handled && replay );
00596 workspace()->setActiveScreenMouse( globalPos );
00597 break;
00598 case Options::MouseActivateRaiseAndPassClick:
00599 workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled );
00600 workspace()->setActiveScreenMouse( globalPos );
00601 replay = true;
00602 break;
00603 case Options::MouseActivateAndPassClick:
00604 workspace()->takeActivity( this, ActivityFocus, handled );
00605 workspace()->setActiveScreenMouse( globalPos );
00606 replay = true;
00607 break;
00608 case Options::MouseActivateRaiseAndMove:
00609 case Options::MouseActivateRaiseAndUnrestrictedMove:
00610 workspace()->raiseClient( this );
00611 workspace()->requestFocus( this );
00612 workspace()->setActiveScreenMouse( globalPos );
00613 if( options->moveMode == Options::Transparent && isMovable())
00614 move_faked_activity = workspace()->fakeRequestedActivity( this );
00615
00616 case Options::MouseMove:
00617 case Options::MouseUnrestrictedMove:
00618 {
00619 if (!isMovable())
00620 break;
00621 if( moveResizeMode )
00622 finishMoveResize( false );
00623 mode = PositionCenter;
00624 buttonDown = true;
00625 moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y());
00626 invertedMoveOffset = rect().bottomRight() - moveOffset;
00627 unrestrictedMoveResize = ( command == Options::MouseActivateRaiseAndUnrestrictedMove
00628 || command == Options::MouseUnrestrictedMove );
00629 if( !startMoveResize())
00630 buttonDown = false;
00631 updateCursor();
00632 break;
00633 }
00634 case Options::MouseResize:
00635 case Options::MouseUnrestrictedResize:
00636 {
00637 if (!isResizable() || isShade())
00638 break;
00639 if( moveResizeMode )
00640 finishMoveResize( false );
00641 buttonDown = true;
00642 moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y());
00643 int x = moveOffset.x(), y = moveOffset.y();
00644 bool left = x < width() / 3;
00645 bool right = x >= 2 * width() / 3;
00646 bool top = y < height() / 3;
00647 bool bot = y >= 2 * height() / 3;
00648 if (top)
00649 mode = left ? PositionTopLeft : (right ? PositionTopRight : PositionTop);
00650 else if (bot)
00651 mode = left ? PositionBottomLeft : (right ? PositionBottomRight : PositionBottom);
00652 else
00653 mode = (x < width() / 2) ? PositionLeft : PositionRight;
00654 invertedMoveOffset = rect().bottomRight() - moveOffset;
00655 unrestrictedMoveResize = ( command == Options::MouseUnrestrictedResize );
00656 if( !startMoveResize())
00657 buttonDown = false;
00658 updateCursor();
00659 break;
00660 }
00661 case Options::MouseMaximize:
00662 maximize( Client::MaximizeFull );
00663 break;
00664 case Options::MouseRestore:
00665 maximize( Client::MaximizeRestore );
00666 break;
00667 case Options::MouseMinimize:
00668 minimize();
00669 break;
00670 case Options::MouseAbove:
00671 {
00672 StackingUpdatesBlocker blocker( workspace());
00673 if( keepBelow())
00674 setKeepBelow( false );
00675 else
00676 setKeepAbove( true );
00677 break;
00678 }
00679 case Options::MouseBelow:
00680 {
00681 StackingUpdatesBlocker blocker( workspace());
00682 if( keepAbove())
00683 setKeepAbove( false );
00684 else
00685 setKeepBelow( true );
00686 break;
00687 }
00688 case Options::MousePreviousDesktop:
00689 workspace()->windowToPreviousDesktop( this );
00690 break;
00691 case Options::MouseNextDesktop:
00692 workspace()->windowToNextDesktop( this );
00693 break;
00694 case Options::MouseOpacityMore:
00695 setOpacity( qMin( opacity() + 0.1, 1.0 ));
00696 break;
00697 case Options::MouseOpacityLess:
00698 setOpacity( qMax( opacity() - 0.1, 0.0 ));
00699 break;
00700 case Options::MouseNothing:
00701 replay = true;
00702 break;
00703 }
00704 return replay;
00705 }
00706
00707
00708 void Workspace::showWindowMenuAt( unsigned long, int, int )
00709 {
00710 slotWindowOperations();
00711 }
00712
00713 void Workspace::loadEffect( const QString& name )
00714 {
00715 if( effects )
00716 static_cast<EffectsHandlerImpl*>(effects)->loadEffect( name );
00717 }
00718
00719 void Workspace::toggleEffect( const QString& name )
00720 {
00721 if( effects )
00722 static_cast<EffectsHandlerImpl*>(effects)->toggleEffect( name );
00723 }
00724
00725 void Workspace::unloadEffect( const QString& name )
00726 {
00727 if( effects )
00728 static_cast<EffectsHandlerImpl*>(effects)->unloadEffect( name );
00729 }
00730
00731 void Workspace::reloadEffect( const QString& name )
00732 {
00733 if( effects )
00734 static_cast<EffectsHandlerImpl*>(effects)->reloadEffect( name );
00735 }
00736
00737 QStringList Workspace::loadedEffects() const
00738 {
00739 QStringList listModulesLoaded;
00740 if ( effects )
00741 listModulesLoaded = static_cast<EffectsHandlerImpl*>(effects)->loadedEffects();
00742 return listModulesLoaded;
00743 }
00744
00745 QStringList Workspace::listOfEffects() const
00746 {
00747 QStringList listModules;
00748 if ( effects )
00749 listModules = static_cast<EffectsHandlerImpl*>(effects)->listOfEffects();
00750 return listModules;
00751 }
00752
00753 void Workspace::slotActivateAttentionWindow()
00754 {
00755 if( attention_chain.count() > 0 )
00756 activateClient( attention_chain.first());
00757 }
00758
00759 void Workspace::slotSwitchDesktopNext()
00760 {
00761 int d = currentDesktop() + 1;
00762 if ( d > numberOfDesktops() )
00763 {
00764 if ( options->rollOverDesktops )
00765 {
00766 d = 1;
00767 }
00768 else
00769 {
00770 return;
00771 }
00772 }
00773 setCurrentDesktop(d);
00774 }
00775
00776 void Workspace::slotSwitchDesktopPrevious()
00777 {
00778 int d = currentDesktop() - 1;
00779 if ( d <= 0 )
00780 {
00781 if ( options->rollOverDesktops )
00782 d = numberOfDesktops();
00783 else
00784 return;
00785 }
00786 setCurrentDesktop(d);
00787 }
00788
00789 void Workspace::slotSwitchDesktopRight()
00790 {
00791 int desktop = desktopToRight( currentDesktop(), options->rollOverDesktops);
00792 if( desktop == currentDesktop())
00793 return;
00794 setCurrentDesktop( desktop );
00795 }
00796
00797 void Workspace::slotSwitchDesktopLeft()
00798 {
00799 int desktop = desktopToLeft( currentDesktop(), options->rollOverDesktops);
00800 if( desktop == currentDesktop())
00801 return;
00802 setCurrentDesktop( desktop );
00803 }
00804
00805 void Workspace::slotSwitchDesktopUp()
00806 {
00807 int desktop = desktopUp( currentDesktop(), options->rollOverDesktops);
00808 if( desktop == currentDesktop())
00809 return;
00810 setCurrentDesktop( desktop );
00811 }
00812
00813 void Workspace::slotSwitchDesktopDown()
00814 {
00815 int desktop = desktopDown( currentDesktop(), options->rollOverDesktops);
00816 if( desktop == currentDesktop())
00817 return;
00818 setCurrentDesktop( desktop );
00819 }
00820
00821 void Workspace::slotSwitchToDesktop( int i )
00822 {
00823 setCurrentDesktop( i );
00824 }
00825
00826
00827 void Workspace::slotWindowToDesktop( int i )
00828 {
00829 Client* c = active_popup_client ? active_popup_client : active_client;
00830 if( i >= 1 && i <= numberOfDesktops() && c
00831 && !c->isDesktop()
00832 && !c->isDock()
00833 && !c->isTopMenu())
00834 sendClientToDesktop( c, i, true );
00835 }
00836
00837 void Workspace::slotSwitchToScreen( int i )
00838 {
00839 setCurrentScreen( i );
00840 }
00841
00842 void Workspace::slotSwitchToNextScreen()
00843 {
00844 slotSwitchToScreen(( activeScreen() + 1 ) % numScreens());
00845 }
00846
00847 void Workspace::slotWindowToScreen( int i )
00848 {
00849 Client* c = active_popup_client ? active_popup_client : active_client;
00850 if( i >= 0 && i <= numScreens() && c
00851 && !c->isDesktop()
00852 && !c->isDock()
00853 && !c->isTopMenu())
00854 {
00855 sendClientToScreen( c, i );
00856 }
00857 }
00858
00859 void Workspace::slotWindowToNextScreen()
00860 {
00861 Client* c = active_popup_client ? active_popup_client : active_client;
00862 if( c
00863 && !c->isDesktop()
00864 && !c->isDock()
00865 && !c->isTopMenu())
00866 {
00867 sendClientToScreen( c, ( c->screen() + 1 ) % numScreens());
00868 }
00869 }
00870
00874 void Workspace::slotWindowMaximize()
00875 {
00876 Client* c = active_popup_client ? active_popup_client : active_client;
00877 if ( c )
00878 performWindowOperation( c, Options::MaximizeOp );
00879 }
00880
00884 void Workspace::slotWindowMaximizeVertical()
00885 {
00886 Client* c = active_popup_client ? active_popup_client : active_client;
00887 if ( c )
00888 performWindowOperation( c, Options::VMaximizeOp );
00889 }
00890
00894 void Workspace::slotWindowMaximizeHorizontal()
00895 {
00896 Client* c = active_popup_client ? active_popup_client : active_client;
00897 if ( c )
00898 performWindowOperation( c, Options::HMaximizeOp );
00899 }
00900
00901
00905 void Workspace::slotWindowMinimize()
00906 {
00907 Client* c = active_popup_client ? active_popup_client : active_client;
00908 performWindowOperation( c, Options::MinimizeOp );
00909 }
00910
00914 void Workspace::slotWindowShade()
00915 {
00916 Client* c = active_popup_client ? active_popup_client : active_client;
00917 performWindowOperation( c, Options::ShadeOp );
00918 }
00919
00923 void Workspace::slotWindowRaise()
00924 {
00925 Client* c = active_popup_client ? active_popup_client : active_client;
00926 if ( c )
00927 raiseClient( c );
00928 }
00929
00933 void Workspace::slotWindowLower()
00934 {
00935 Client* c = active_popup_client ? active_popup_client : active_client;
00936 if ( c )
00937 lowerClient( c );
00938 }
00939
00943 void Workspace::slotWindowRaiseOrLower()
00944 {
00945 Client* c = active_popup_client ? active_popup_client : active_client;
00946 if ( c )
00947 raiseOrLowerClient( c );
00948 }
00949
00950 void Workspace::slotWindowOnAllDesktops()
00951 {
00952 Client* c = active_popup_client ? active_popup_client : active_client;
00953 if( c )
00954 c->setOnAllDesktops( !c->isOnAllDesktops());
00955 }
00956
00957 void Workspace::slotWindowFullScreen()
00958 {
00959 Client* c = active_popup_client ? active_popup_client : active_client;
00960 if( c )
00961 performWindowOperation( c, Options::FullScreenOp );
00962 }
00963
00964 void Workspace::slotWindowNoBorder()
00965 {
00966 Client* c = active_popup_client ? active_popup_client : active_client;
00967 if( c )
00968 performWindowOperation( c, Options::NoBorderOp );
00969 }
00970
00971 void Workspace::slotWindowAbove()
00972 {
00973 Client* c = active_popup_client ? active_popup_client : active_client;
00974 if( c )
00975 performWindowOperation( c, Options::KeepAboveOp );
00976 }
00977
00978 void Workspace::slotWindowBelow()
00979 {
00980 Client* c = active_popup_client ? active_popup_client : active_client;
00981 if( c )
00982 performWindowOperation( c, Options::KeepBelowOp );
00983 }
00984 void Workspace::slotSetupWindowShortcut()
00985 {
00986 Client* c = active_popup_client ? active_popup_client : active_client;
00987 if( c )
00988 performWindowOperation( c, Options::SetupWindowShortcutOp );
00989 }
00990
00994 void Workspace::slotWindowToNextDesktop()
00995 {
00996 windowToNextDesktop( active_popup_client ? active_popup_client : active_client );
00997 }
00998
00999 void Workspace::windowToNextDesktop( Client* c )
01000 {
01001 int d = currentDesktop() + 1;
01002 if ( d > numberOfDesktops() )
01003 d = 1;
01004 if (c && !c->isDesktop()
01005 && !c->isDock() && !c->isTopMenu())
01006 {
01007 setClientIsMoving( c );
01008 setCurrentDesktop( d );
01009 setClientIsMoving( NULL );
01010 }
01011 }
01012
01016 void Workspace::slotWindowToPreviousDesktop()
01017 {
01018 windowToPreviousDesktop( active_popup_client ? active_popup_client : active_client );
01019 }
01020
01021 void Workspace::windowToPreviousDesktop( Client* c )
01022 {
01023 int d = currentDesktop() - 1;
01024 if ( d <= 0 )
01025 d = numberOfDesktops();
01026 if (c && !c->isDesktop()
01027 && !c->isDock() && !c->isTopMenu())
01028 {
01029 setClientIsMoving( c );
01030 setCurrentDesktop( d );
01031 setClientIsMoving( NULL );
01032 }
01033 }
01034
01035 void Workspace::slotWindowToDesktopRight()
01036 {
01037 int d = desktopToRight( currentDesktop(), options->rollOverDesktops);
01038 if( d == currentDesktop())
01039 return;
01040 Client* c = active_popup_client ? active_popup_client : active_client;
01041 if (c && !c->isDesktop()
01042 && !c->isDock() && !c->isTopMenu())
01043 {
01044 setClientIsMoving( c );
01045 setCurrentDesktop( d );
01046 setClientIsMoving( NULL );
01047 }
01048 }
01049
01050 void Workspace::slotWindowToDesktopLeft()
01051 {
01052 int d = desktopToLeft( currentDesktop(), options->rollOverDesktops);
01053 if( d == currentDesktop())
01054 return;
01055 Client* c = active_popup_client ? active_popup_client : active_client;
01056 if (c && !c->isDesktop()
01057 && !c->isDock() && !c->isTopMenu())
01058 {
01059 setClientIsMoving( c );
01060 setCurrentDesktop( d );
01061 setClientIsMoving( NULL );
01062 }
01063 }
01064
01065 void Workspace::slotWindowToDesktopUp()
01066 {
01067 int d = desktopUp( currentDesktop(), options->rollOverDesktops);
01068 if( d == currentDesktop())
01069 return;
01070 Client* c = active_popup_client ? active_popup_client : active_client;
01071 if (c && !c->isDesktop()
01072 && !c->isDock() && !c->isTopMenu())
01073 {
01074 setClientIsMoving( c );
01075 setCurrentDesktop( d );
01076 setClientIsMoving( NULL );
01077 }
01078 }
01079
01080 void Workspace::slotWindowToDesktopDown()
01081 {
01082 int d = desktopDown( currentDesktop(), options->rollOverDesktops);
01083 if( d == currentDesktop())
01084 return;
01085 Client* c = active_popup_client ? active_popup_client : active_client;
01086 if (c && !c->isDesktop()
01087 && !c->isDock() && !c->isTopMenu())
01088 {
01089 setClientIsMoving( c );
01090 setCurrentDesktop( d );
01091 setClientIsMoving( NULL );
01092 }
01093 }
01094
01095
01099 void Workspace::slotKillWindow()
01100 {
01101 KillWindow kill( this );
01102 kill.start();
01103 }
01104
01110 void Workspace::slotSendToDesktop( QAction *action )
01111 {
01112 int desk = action->data().toInt();
01113 if ( !active_popup_client )
01114 return;
01115 if ( desk == 0 )
01116 {
01117 active_popup_client->setOnAllDesktops( !active_popup_client->isOnAllDesktops());
01118 return;
01119 }
01120
01121 sendClientToDesktop( active_popup_client, desk, false );
01122
01123 }
01124
01128 void Workspace::slotWindowOperations()
01129 {
01130 if ( !active_client )
01131 return;
01132 QPoint pos = active_client->pos() + active_client->clientPos();
01133 showWindowMenu( pos.x(), pos.y(), active_client );
01134 }
01135
01136 void Workspace::showWindowMenu( const QRect &pos, Client* cl )
01137 {
01138 if (!KAuthorized::authorizeKAction("kwin_rmb"))
01139 return;
01140 if( !cl )
01141 return;
01142 if( active_popup_client != NULL )
01143 return;
01144 if ( cl->isDesktop()
01145 || cl->isDock()
01146 || cl->isTopMenu())
01147 return;
01148
01149 active_popup_client = cl;
01150 QMenu* p = clientPopup();
01151 active_popup = p;
01152 int x = pos.left();
01153 int y = pos.bottom();
01154 if (y == pos.top())
01155 p->exec( QPoint( x, y ) );
01156 else
01157 {
01158 QRect area = clientArea(ScreenArea, QPoint(x, y), currentDesktop());
01159 clientPopupAboutToShow();
01160 int popupHeight = p->sizeHint().height();
01161 if (y + popupHeight < area.height())
01162 p->exec( QPoint( x, y ) );
01163 else
01164 p->exec( QPoint( x, pos.top() - popupHeight ) );
01165 }
01166
01167 if( active_popup == p )
01168 closeActivePopup();
01169 }
01170
01174 void Workspace::slotWindowClose()
01175 {
01176 if ( tab_box->isVisible())
01177 return;
01178 Client* c = active_popup_client ? active_popup_client : active_client;
01179 performWindowOperation( c, Options::CloseOp );
01180 }
01181
01185 void Workspace::slotWindowMove()
01186 {
01187 Client* c = active_popup_client ? active_popup_client : active_client;
01188 performWindowOperation( c, Options::UnrestrictedMoveOp );
01189 }
01190
01194 void Workspace::slotWindowResize()
01195 {
01196 Client* c = active_popup_client ? active_popup_client : active_client;
01197 performWindowOperation( c, Options::UnrestrictedResizeOp );
01198 }
01199
01200 void Client::setShortcut( const QString& _cut )
01201 {
01202 QString cut = rules()->checkShortcut( _cut );
01203 if( cut.isEmpty())
01204 return setShortcutInternal( KShortcut());
01205
01206
01207
01208 if( !cut.contains( '(' ) && !cut.contains( ')' ) && !cut.contains( ' ' ))
01209 {
01210 if( workspace()->shortcutAvailable( KShortcut( cut ), this ))
01211 setShortcutInternal( KShortcut( cut ));
01212 else
01213 setShortcutInternal( KShortcut());
01214 return;
01215 }
01216 QList< KShortcut > keys;
01217 QStringList groups = cut.split( ' ');
01218 for( QStringList::ConstIterator it = groups.begin();
01219 it != groups.end();
01220 ++it )
01221 {
01222 QRegExp reg( "(.*\\+)\\((.*)\\)" );
01223 if( reg.indexIn( *it ) > -1 )
01224 {
01225 QString base = reg.cap( 1 );
01226 QString list = reg.cap( 2 );
01227 for( int i = 0;
01228 i < list.length();
01229 ++i )
01230 {
01231 KShortcut c( base + list[ i ] );
01232 if( !c.isEmpty())
01233 keys.append( c );
01234 }
01235 }
01236 }
01237 for( QList< KShortcut >::ConstIterator it = keys.begin();
01238 it != keys.end();
01239 ++it )
01240 {
01241 if( _shortcut == *it )
01242 return;
01243 }
01244 for( QList< KShortcut >::ConstIterator it = keys.begin();
01245 it != keys.end();
01246 ++it )
01247 {
01248 if( workspace()->shortcutAvailable( *it, this ))
01249 {
01250 setShortcutInternal( *it );
01251 return;
01252 }
01253 }
01254 setShortcutInternal( KShortcut());
01255 }
01256
01257 void Client::setShortcutInternal( const KShortcut& cut )
01258 {
01259 if( _shortcut == cut )
01260 return;
01261 _shortcut = cut;
01262 updateCaption();
01263 workspace()->clientShortcutUpdated( this );
01264 }
01265
01266 bool Workspace::shortcutAvailable( const KShortcut& cut, Client* ignore ) const
01267 {
01268
01269 for( ClientList::ConstIterator it = clients.begin();
01270 it != clients.end();
01271 ++it )
01272 {
01273 if( (*it) != ignore && (*it)->shortcut() == cut )
01274 return false;
01275 }
01276 return true;
01277 }
01278
01279 }