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::discardPopup()
00195 {
00196 delete popup;
00197 popup = NULL;
00198 desk_popup = NULL;
00199 }
00200
00201 void Workspace::setPopupClientOpacity( QAction* action )
00202 {
00203 if( active_popup_client == NULL )
00204 return;
00205 int level = action->data().toInt();
00206 active_popup_client->setOpacity( level / 100.0 );
00207 }
00208
00214 void Workspace::clientPopupAboutToShow()
00215 {
00216 if ( !active_popup_client || !popup )
00217 return;
00218
00219 if ( numberOfDesktops() == 1 )
00220 {
00221 delete desk_popup;
00222 desk_popup = 0;
00223 }
00224 else
00225 {
00226 initDesktopPopup();
00227 }
00228
00229 mResizeOpAction->setEnabled( active_popup_client->isResizable() );
00230 mMoveOpAction->setEnabled( active_popup_client->isMovableAcrossScreens() );
00231 mMaximizeOpAction->setEnabled( active_popup_client->isMaximizable() );
00232 mMaximizeOpAction->setChecked( active_popup_client->maximizeMode() == Client::MaximizeFull );
00233 mShadeOpAction->setEnabled( active_popup_client->isShadeable() );
00234 mShadeOpAction->setChecked( active_popup_client->shadeMode() != ShadeNone );
00235 mKeepAboveOpAction->setChecked( active_popup_client->keepAbove() );
00236 mKeepBelowOpAction->setChecked( active_popup_client->keepBelow() );
00237 mFullScreenOpAction->setEnabled( active_popup_client->userCanSetFullScreen() );
00238 mFullScreenOpAction->setChecked( active_popup_client->isFullScreen() );
00239 mNoBorderOpAction->setEnabled( active_popup_client->userCanSetNoBorder() );
00240 mNoBorderOpAction->setChecked( active_popup_client->noBorder() );
00241 mMinimizeOpAction->setEnabled( active_popup_client->isMinimizable() );
00242 mCloseOpAction->setEnabled( active_popup_client->isCloseable() );
00243 if( trans_popup != NULL )
00244 {
00245 foreach( QAction* action, trans_popup->actions())
00246 {
00247 if( action->data().toInt() == qRound( active_popup_client->opacity() * 100 ))
00248 action->setChecked( true );
00249 else
00250 action->setChecked( false );
00251 }
00252 }
00253 }
00254
00255
00256 void Workspace::initDesktopPopup()
00257 {
00258 if (desk_popup)
00259 return;
00260
00261 desk_popup = new QMenu( popup );
00262 desk_popup->setFont(KGlobalSettings::menuFont());
00263 connect( desk_popup, SIGNAL( triggered(QAction*) ),
00264 this, SLOT( slotSendToDesktop(QAction*) ) );
00265 connect( desk_popup, SIGNAL( aboutToShow() ),
00266 this, SLOT( desktopPopupAboutToShow() ) );
00267
00268 QAction *action = desk_popup->menuAction();
00269 popup->insertAction(advanced_popup->menuAction(), action);
00270 action->setText( i18n("To &Desktop") );
00271 }
00272
00277 void Workspace::desktopPopupAboutToShow()
00278 {
00279 if ( !desk_popup )
00280 return;
00281
00282 desk_popup->clear();
00283 QAction *action = desk_popup->addAction( i18n("&All Desktops") );
00284 action->setData( 0 );
00285 action->setCheckable( true );
00286
00287 if ( active_popup_client && active_popup_client->isOnAllDesktops() )
00288 action->setChecked( true );
00289 desk_popup->addSeparator();
00290
00291 const int BASE = 10;
00292 for ( int i = 1; i <= numberOfDesktops(); i++ ) {
00293 QString basic_name("%1 %2");
00294 if (i<BASE) {
00295 basic_name.prepend('&');
00296 }
00297 action = desk_popup->addAction( basic_name.arg(i).arg( desktopName(i).replace( '&', "&&" ) ) );
00298 action->setData( i );
00299 action->setCheckable( true );
00300
00301 if ( active_popup_client &&
00302 !active_popup_client->isOnAllDesktops() && active_popup_client->desktop() == i )
00303 action->setChecked( true );
00304 }
00305 }
00306
00307 void Workspace::closeActivePopup()
00308 {
00309 if( active_popup )
00310 {
00311 active_popup->close();
00312 active_popup = NULL;
00313 active_popup_client = NULL;
00314 }
00315 }
00316
00320 void Workspace::initShortcuts()
00321 {
00322 keys = new KActionCollection( this );
00323 KActionCollection* actionCollection = keys;
00324 QAction* a = 0L;
00325
00326
00327
00328 disable_shortcuts_keys = new KActionCollection( this );
00329 #ifdef __GNUC__
00330 #warning TODO PORT ME (KGlobalAccel related)
00331 #endif
00332
00333
00334 #define IN_KWIN
00335 #include "kwinbindings.cpp"
00336 readShortcuts();
00337 }
00338
00339 void Workspace::readShortcuts()
00340 {
00341 #ifdef __GNUC__
00342 #warning TODO PORT ME (KGlobalAccel related)
00343 #endif
00344
00345
00346 KAction *kaction = qobject_cast<KAction*>( keys->action("Walk Through Desktops") );
00347 if ( kaction!=0 )
00348 cutWalkThroughDesktops = kaction->globalShortcut();
00349
00350 kaction = qobject_cast<KAction*>( keys->action("Walk Through Desktops (Reverse)") );
00351 if ( kaction!=0 )
00352 cutWalkThroughDesktopsReverse = kaction->globalShortcut();
00353
00354 kaction = qobject_cast<KAction*>( keys->action("Walk Through Desktop List") );
00355 if ( kaction!=0 )
00356 cutWalkThroughDesktopList = kaction->globalShortcut();
00357
00358 kaction = qobject_cast<KAction*>( keys->action("Walk Through Desktop List (Reverse)") );
00359 if ( kaction!=0 )
00360 cutWalkThroughDesktopListReverse = kaction->globalShortcut();
00361
00362 kaction = qobject_cast<KAction*>( keys->action("Walk Through Windows") );
00363 if ( kaction!=0 )
00364 cutWalkThroughWindows = kaction->globalShortcut();
00365
00366 kaction = qobject_cast<KAction*>( keys->action("Walk Through Windows (Reverse)") );
00367 if ( kaction!=0 )
00368 cutWalkThroughWindowsReverse = kaction->globalShortcut();
00369 discardPopup();
00370 }
00371
00372
00373 void Workspace::setupWindowShortcut( Client* c )
00374 {
00375 assert( client_keys_dialog == NULL );
00376 #ifdef __GNUC__
00377 #warning TODO PORT ME (KGlobalAccel related)
00378 #endif
00379
00380
00381
00382 client_keys_dialog = new ShortcutDialog( c->shortcut().primary());
00383 client_keys_client = c;
00384 connect( client_keys_dialog, SIGNAL( dialogDone( bool )), SLOT( setupWindowShortcutDone( bool )));
00385 QRect r = clientArea( ScreenArea, c );
00386 QSize size = client_keys_dialog->sizeHint();
00387 QPoint pos = c->pos() + c->clientPos();
00388 if( pos.x() + size.width() >= r.right())
00389 pos.setX( r.right() - size.width());
00390 if( pos.y() + size.height() >= r.bottom())
00391 pos.setY( r.bottom() - size.height());
00392 client_keys_dialog->move( pos );
00393 client_keys_dialog->show();
00394 active_popup = client_keys_dialog;
00395 active_popup_client = c;
00396 }
00397
00398 void Workspace::setupWindowShortcutDone( bool ok )
00399 {
00400
00401
00402
00403 if( ok )
00404 client_keys_client->setShortcut( KShortcut( client_keys_dialog->shortcut()).toString());
00405 closeActivePopup();
00406 client_keys_dialog->deleteLater();
00407 client_keys_dialog = NULL;
00408 client_keys_client = NULL;
00409 }
00410
00411 void Workspace::clientShortcutUpdated( Client* c )
00412 {
00413 QString key = QString( "_k_session:%1" ).arg(c->window());
00414 QAction* action = client_keys->action( key.toLatin1().constData() );
00415 if( !c->shortcut().isEmpty())
00416 {
00417 if( action == NULL )
00418 {
00419 action = client_keys->addAction(QString( key ));
00420 action->setText( i18n("Activate Window (%1)", c->caption()) );
00421 connect( action, SIGNAL(triggered(bool)), c, SLOT(shortcutActivated()) );
00422 }
00423
00424 KAction *kaction = qobject_cast<KAction*>( action );
00425
00426
00427 kaction->setGlobalShortcut(
00428 c->shortcut(), KAction::ActiveShortcut, KAction::NoAutoloading );
00429 kaction->setEnabled( true );
00430 }
00431 else
00432 {
00433 KAction *kaction = qobject_cast<KAction*>( action );
00434 if( kaction )
00435 {
00436 kaction->forgetGlobalShortcut();
00437 }
00438 delete action;
00439 }
00440 }
00441
00442 void Workspace::clientPopupActivated( QAction *action )
00443 {
00444 if ( !action->data().isValid() )
00445 return;
00446
00447 WindowOperation op = static_cast< WindowOperation >( action->data().toInt() );
00448 Client* c = active_popup_client ? active_popup_client : active_client;
00449 QString type;
00450 switch( op )
00451 {
00452 case FullScreenOp:
00453 if( !c->isFullScreen() && c->userCanSetFullScreen())
00454 type = "fullscreenaltf3";
00455 break;
00456 case NoBorderOp:
00457 if( !c->noBorder() && c->userCanSetNoBorder())
00458 type = "noborderaltf3";
00459 break;
00460 default:
00461 break;
00462 };
00463 if( !type.isEmpty())
00464 helperDialog( type, c );
00465 performWindowOperation( c, op );
00466 }
00467
00468
00469 void Workspace::performWindowOperation( Client* c, Options::WindowOperation op )
00470 {
00471 if ( !c )
00472 return;
00473
00474 if (op == Options::MoveOp || op == Options::UnrestrictedMoveOp )
00475 QCursor::setPos( c->geometry().center() );
00476 if (op == Options::ResizeOp || op == Options::UnrestrictedResizeOp )
00477 QCursor::setPos( c->geometry().bottomRight());
00478 switch ( op )
00479 {
00480 case Options::MoveOp:
00481 c->performMouseCommand( Options::MouseMove, cursorPos() );
00482 break;
00483 case Options::UnrestrictedMoveOp:
00484 c->performMouseCommand( Options::MouseUnrestrictedMove, cursorPos() );
00485 break;
00486 case Options::ResizeOp:
00487 c->performMouseCommand( Options::MouseResize, cursorPos() );
00488 break;
00489 case Options::UnrestrictedResizeOp:
00490 c->performMouseCommand( Options::MouseUnrestrictedResize, cursorPos() );
00491 break;
00492 case Options::CloseOp:
00493 c->closeWindow();
00494 break;
00495 case Options::MaximizeOp:
00496 c->maximize( c->maximizeMode() == Client::MaximizeFull
00497 ? Client::MaximizeRestore : Client::MaximizeFull );
00498 break;
00499 case Options::HMaximizeOp:
00500 c->maximize( c->maximizeMode() ^ Client::MaximizeHorizontal );
00501 break;
00502 case Options::VMaximizeOp:
00503 c->maximize( c->maximizeMode() ^ Client::MaximizeVertical );
00504 break;
00505 case Options::RestoreOp:
00506 c->maximize( Client::MaximizeRestore );
00507 break;
00508 case Options::MinimizeOp:
00509 c->minimize();
00510 break;
00511 case Options::ShadeOp:
00512 c->performMouseCommand( Options::MouseShade, cursorPos());
00513 break;
00514 case Options::OnAllDesktopsOp:
00515 c->setOnAllDesktops( !c->isOnAllDesktops() );
00516 break;
00517 case Options::FullScreenOp:
00518 c->setFullScreen( !c->isFullScreen(), true );
00519 break;
00520 case Options::NoBorderOp:
00521 c->setNoBorder( !c->noBorder());
00522 break;
00523 case Options::KeepAboveOp:
00524 {
00525 StackingUpdatesBlocker blocker( this );
00526 bool was = c->keepAbove();
00527 c->setKeepAbove( !c->keepAbove() );
00528 if( was && !c->keepAbove())
00529 raiseClient( c );
00530 break;
00531 }
00532 case Options::KeepBelowOp:
00533 {
00534 StackingUpdatesBlocker blocker( this );
00535 bool was = c->keepBelow();
00536 c->setKeepBelow( !c->keepBelow() );
00537 if( was && !c->keepBelow())
00538 lowerClient( c );
00539 break;
00540 }
00541 case Options::OperationsOp:
00542 c->performMouseCommand( Options::MouseShade, cursorPos());
00543 break;
00544 case Options::WindowRulesOp:
00545 editWindowRules( c, false );
00546 break;
00547 case Options::ApplicationRulesOp:
00548 editWindowRules( c, true );
00549 break;
00550 case Options::SetupWindowShortcutOp:
00551 setupWindowShortcut( c );
00552 break;
00553 case Options::LowerOp:
00554 lowerClient(c);
00555 break;
00556 case Options::NoOp:
00557 break;
00558 }
00559 }
00560
00564 bool Client::performMouseCommand( Options::MouseCommand command, const QPoint &globalPos, bool handled )
00565 {
00566 bool replay = false;
00567 switch (command)
00568 {
00569 case Options::MouseRaise:
00570 workspace()->raiseClient( this );
00571 break;
00572 case Options::MouseLower:
00573 workspace()->lowerClient( this );
00574 break;
00575 case Options::MouseShade :
00576 toggleShade();
00577 cancelShadeHoverTimer();
00578 break;
00579 case Options::MouseSetShade:
00580 setShade( ShadeNormal );
00581 cancelShadeHoverTimer();
00582 break;
00583 case Options::MouseUnsetShade:
00584 setShade( ShadeNone );
00585 cancelShadeHoverTimer();
00586 break;
00587 case Options::MouseOperationsMenu:
00588 if ( isActive() && options->clickRaise )
00589 autoRaise();
00590 workspace()->showWindowMenu( globalPos, this );
00591 break;
00592 case Options::MouseToggleRaiseAndLower:
00593 workspace()->raiseOrLowerClient( this );
00594 break;
00595 case Options::MouseActivateAndRaise:
00596 replay = isActive();
00597 workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled && replay );
00598 workspace()->setActiveScreenMouse( globalPos );
00599 break;
00600 case Options::MouseActivateAndLower:
00601 workspace()->requestFocus( this );
00602 workspace()->lowerClient( this );
00603 workspace()->setActiveScreenMouse( globalPos );
00604 break;
00605 case Options::MouseActivate:
00606 replay = isActive();
00607 workspace()->takeActivity( this, ActivityFocus, handled && replay );
00608 workspace()->setActiveScreenMouse( globalPos );
00609 break;
00610 case Options::MouseActivateRaiseAndPassClick:
00611 workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled );
00612 workspace()->setActiveScreenMouse( globalPos );
00613 replay = true;
00614 break;
00615 case Options::MouseActivateAndPassClick:
00616 workspace()->takeActivity( this, ActivityFocus, handled );
00617 workspace()->setActiveScreenMouse( globalPos );
00618 replay = true;
00619 break;
00620 case Options::MouseActivateRaiseAndMove:
00621 case Options::MouseActivateRaiseAndUnrestrictedMove:
00622 workspace()->raiseClient( this );
00623 workspace()->requestFocus( this );
00624 workspace()->setActiveScreenMouse( globalPos );
00625 if( options->moveMode == Options::Transparent && isMovableAcrossScreens())
00626 move_faked_activity = workspace()->fakeRequestedActivity( this );
00627
00628 case Options::MouseMove:
00629 case Options::MouseUnrestrictedMove:
00630 {
00631 if (!isMovableAcrossScreens())
00632 break;
00633 if( moveResizeMode )
00634 finishMoveResize( false );
00635 mode = PositionCenter;
00636 buttonDown = true;
00637 moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y());
00638 invertedMoveOffset = rect().bottomRight() - moveOffset;
00639 unrestrictedMoveResize = ( command == Options::MouseActivateRaiseAndUnrestrictedMove
00640 || command == Options::MouseUnrestrictedMove );
00641 if( !startMoveResize())
00642 buttonDown = false;
00643 updateCursor();
00644 break;
00645 }
00646 case Options::MouseResize:
00647 case Options::MouseUnrestrictedResize:
00648 {
00649 if (!isResizable() || isShade())
00650 break;
00651 if( moveResizeMode )
00652 finishMoveResize( false );
00653 buttonDown = true;
00654 moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y());
00655 int x = moveOffset.x(), y = moveOffset.y();
00656 bool left = x < width() / 3;
00657 bool right = x >= 2 * width() / 3;
00658 bool top = y < height() / 3;
00659 bool bot = y >= 2 * height() / 3;
00660 if (top)
00661 mode = left ? PositionTopLeft : (right ? PositionTopRight : PositionTop);
00662 else if (bot)
00663 mode = left ? PositionBottomLeft : (right ? PositionBottomRight : PositionBottom);
00664 else
00665 mode = (x < width() / 2) ? PositionLeft : PositionRight;
00666 invertedMoveOffset = rect().bottomRight() - moveOffset;
00667 unrestrictedMoveResize = ( command == Options::MouseUnrestrictedResize );
00668 if( !startMoveResize())
00669 buttonDown = false;
00670 updateCursor();
00671 break;
00672 }
00673 case Options::MouseMaximize:
00674 maximize( Client::MaximizeFull );
00675 break;
00676 case Options::MouseRestore:
00677 maximize( Client::MaximizeRestore );
00678 break;
00679 case Options::MouseMinimize:
00680 minimize();
00681 break;
00682 case Options::MouseAbove:
00683 {
00684 StackingUpdatesBlocker blocker( workspace());
00685 if( keepBelow())
00686 setKeepBelow( false );
00687 else
00688 setKeepAbove( true );
00689 break;
00690 }
00691 case Options::MouseBelow:
00692 {
00693 StackingUpdatesBlocker blocker( workspace());
00694 if( keepAbove())
00695 setKeepAbove( false );
00696 else
00697 setKeepBelow( true );
00698 break;
00699 }
00700 case Options::MousePreviousDesktop:
00701 workspace()->windowToPreviousDesktop( this );
00702 break;
00703 case Options::MouseNextDesktop:
00704 workspace()->windowToNextDesktop( this );
00705 break;
00706 case Options::MouseOpacityMore:
00707 if( !isDesktop() )
00708 setOpacity( qMin( opacity() + 0.1, 1.0 ));
00709 break;
00710 case Options::MouseOpacityLess:
00711 if( !isDesktop() )
00712 setOpacity( qMax( opacity() - 0.1, 0.0 ));
00713 break;
00714 case Options::MouseNothing:
00715 replay = true;
00716 break;
00717 }
00718 return replay;
00719 }
00720
00721
00722 void Workspace::showWindowMenuAt( unsigned long, int, int )
00723 {
00724 slotWindowOperations();
00725 }
00726
00727 void Workspace::loadEffect( const QString& name )
00728 {
00729 if( effects )
00730 static_cast<EffectsHandlerImpl*>(effects)->loadEffect( name );
00731 }
00732
00733 void Workspace::toggleEffect( const QString& name )
00734 {
00735 if( effects )
00736 static_cast<EffectsHandlerImpl*>(effects)->toggleEffect( name );
00737 }
00738
00739 void Workspace::unloadEffect( const QString& name )
00740 {
00741 if( effects )
00742 static_cast<EffectsHandlerImpl*>(effects)->unloadEffect( name );
00743 }
00744
00745 void Workspace::reconfigureEffect( const QString& name )
00746 {
00747 if( effects )
00748 static_cast<EffectsHandlerImpl*>(effects)->reconfigureEffect( name );
00749 }
00750
00751 QStringList Workspace::loadedEffects() const
00752 {
00753 QStringList listModulesLoaded;
00754 if ( effects )
00755 listModulesLoaded = static_cast<EffectsHandlerImpl*>(effects)->loadedEffects();
00756 return listModulesLoaded;
00757 }
00758
00759 QStringList Workspace::listOfEffects() const
00760 {
00761 QStringList listModules;
00762 if ( effects )
00763 listModules = static_cast<EffectsHandlerImpl*>(effects)->listOfEffects();
00764 return listModules;
00765 }
00766
00767 void Workspace::slotActivateAttentionWindow()
00768 {
00769 if( attention_chain.count() > 0 )
00770 activateClient( attention_chain.first());
00771 }
00772
00773 void Workspace::slotSwitchDesktopNext()
00774 {
00775 int d = currentDesktop() + 1;
00776 if ( d > numberOfDesktops() )
00777 {
00778 if ( options->rollOverDesktops )
00779 {
00780 d = 1;
00781 }
00782 else
00783 {
00784 return;
00785 }
00786 }
00787 setCurrentDesktop(d);
00788 }
00789
00790 void Workspace::slotSwitchDesktopPrevious()
00791 {
00792 int d = currentDesktop() - 1;
00793 if ( d <= 0 )
00794 {
00795 if ( options->rollOverDesktops )
00796 d = numberOfDesktops();
00797 else
00798 return;
00799 }
00800 setCurrentDesktop(d);
00801 }
00802
00803 void Workspace::slotSwitchDesktopRight()
00804 {
00805 int desktop = desktopToRight( currentDesktop(), options->rollOverDesktops);
00806 if( desktop == currentDesktop())
00807 return;
00808 setCurrentDesktop( desktop );
00809 }
00810
00811 void Workspace::slotSwitchDesktopLeft()
00812 {
00813 int desktop = desktopToLeft( currentDesktop(), options->rollOverDesktops);
00814 if( desktop == currentDesktop())
00815 return;
00816 setCurrentDesktop( desktop );
00817 }
00818
00819 void Workspace::slotSwitchDesktopUp()
00820 {
00821 int desktop = desktopUp( currentDesktop(), options->rollOverDesktops);
00822 if( desktop == currentDesktop())
00823 return;
00824 setCurrentDesktop( desktop );
00825 }
00826
00827 void Workspace::slotSwitchDesktopDown()
00828 {
00829 int desktop = desktopDown( currentDesktop(), options->rollOverDesktops);
00830 if( desktop == currentDesktop())
00831 return;
00832 setCurrentDesktop( desktop );
00833 }
00834
00835 void Workspace::slotSwitchToDesktop( int i )
00836 {
00837 setCurrentDesktop( i );
00838 }
00839
00840
00841 void Workspace::slotWindowToDesktop( int i )
00842 {
00843 Client* c = active_popup_client ? active_popup_client : active_client;
00844 if( i >= 1 && i <= numberOfDesktops() && c
00845 && !c->isDesktop()
00846 && !c->isDock()
00847 && !c->isTopMenu())
00848 sendClientToDesktop( c, i, true );
00849 }
00850
00851 void Workspace::slotSwitchToScreen( int i )
00852 {
00853 setCurrentScreen( i );
00854 }
00855
00856 void Workspace::slotSwitchToNextScreen()
00857 {
00858 slotSwitchToScreen(( activeScreen() + 1 ) % numScreens());
00859 }
00860
00861 void Workspace::slotWindowToScreen( int i )
00862 {
00863 Client* c = active_popup_client ? active_popup_client : active_client;
00864 if( i >= 0 && i <= numScreens() && c
00865 && !c->isDesktop()
00866 && !c->isDock()
00867 && !c->isTopMenu())
00868 {
00869 sendClientToScreen( c, i );
00870 }
00871 }
00872
00873 void Workspace::slotWindowToNextScreen()
00874 {
00875 Client* c = active_popup_client ? active_popup_client : active_client;
00876 if( c
00877 && !c->isDesktop()
00878 && !c->isDock()
00879 && !c->isTopMenu())
00880 {
00881 sendClientToScreen( c, ( c->screen() + 1 ) % numScreens());
00882 }
00883 }
00884
00888 void Workspace::slotWindowMaximize()
00889 {
00890 Client* c = active_popup_client ? active_popup_client : active_client;
00891 if ( c )
00892 performWindowOperation( c, Options::MaximizeOp );
00893 }
00894
00898 void Workspace::slotWindowMaximizeVertical()
00899 {
00900 Client* c = active_popup_client ? active_popup_client : active_client;
00901 if ( c )
00902 performWindowOperation( c, Options::VMaximizeOp );
00903 }
00904
00908 void Workspace::slotWindowMaximizeHorizontal()
00909 {
00910 Client* c = active_popup_client ? active_popup_client : active_client;
00911 if ( c )
00912 performWindowOperation( c, Options::HMaximizeOp );
00913 }
00914
00915
00919 void Workspace::slotWindowMinimize()
00920 {
00921 Client* c = active_popup_client ? active_popup_client : active_client;
00922 performWindowOperation( c, Options::MinimizeOp );
00923 }
00924
00928 void Workspace::slotWindowShade()
00929 {
00930 Client* c = active_popup_client ? active_popup_client : active_client;
00931 performWindowOperation( c, Options::ShadeOp );
00932 }
00933
00937 void Workspace::slotWindowRaise()
00938 {
00939 Client* c = active_popup_client ? active_popup_client : active_client;
00940 if ( c )
00941 raiseClient( c );
00942 }
00943
00947 void Workspace::slotWindowLower()
00948 {
00949 Client* c = active_popup_client ? active_popup_client : active_client;
00950 if ( c )
00951 lowerClient( c );
00952 }
00953
00957 void Workspace::slotWindowRaiseOrLower()
00958 {
00959 Client* c = active_popup_client ? active_popup_client : active_client;
00960 if ( c )
00961 raiseOrLowerClient( c );
00962 }
00963
00964 void Workspace::slotWindowOnAllDesktops()
00965 {
00966 Client* c = active_popup_client ? active_popup_client : active_client;
00967 if( c )
00968 c->setOnAllDesktops( !c->isOnAllDesktops());
00969 }
00970
00971 void Workspace::slotWindowFullScreen()
00972 {
00973 Client* c = active_popup_client ? active_popup_client : active_client;
00974 if( c )
00975 performWindowOperation( c, Options::FullScreenOp );
00976 }
00977
00978 void Workspace::slotWindowNoBorder()
00979 {
00980 Client* c = active_popup_client ? active_popup_client : active_client;
00981 if( c )
00982 performWindowOperation( c, Options::NoBorderOp );
00983 }
00984
00985 void Workspace::slotWindowAbove()
00986 {
00987 Client* c = active_popup_client ? active_popup_client : active_client;
00988 if( c )
00989 performWindowOperation( c, Options::KeepAboveOp );
00990 }
00991
00992 void Workspace::slotWindowBelow()
00993 {
00994 Client* c = active_popup_client ? active_popup_client : active_client;
00995 if( c )
00996 performWindowOperation( c, Options::KeepBelowOp );
00997 }
00998 void Workspace::slotSetupWindowShortcut()
00999 {
01000 Client* c = active_popup_client ? active_popup_client : active_client;
01001 if( c )
01002 performWindowOperation( c, Options::SetupWindowShortcutOp );
01003 }
01004
01008 void Workspace::slotWindowToNextDesktop()
01009 {
01010 windowToNextDesktop( active_popup_client ? active_popup_client : active_client );
01011 }
01012
01013 void Workspace::windowToNextDesktop( Client* c )
01014 {
01015 int d = currentDesktop() + 1;
01016 if ( d > numberOfDesktops() )
01017 d = 1;
01018 if (c && !c->isDesktop()
01019 && !c->isDock() && !c->isTopMenu())
01020 {
01021 setClientIsMoving( c );
01022 setCurrentDesktop( d );
01023 setClientIsMoving( NULL );
01024 }
01025 }
01026
01030 void Workspace::slotWindowToPreviousDesktop()
01031 {
01032 windowToPreviousDesktop( active_popup_client ? active_popup_client : active_client );
01033 }
01034
01035 void Workspace::windowToPreviousDesktop( Client* c )
01036 {
01037 int d = currentDesktop() - 1;
01038 if ( d <= 0 )
01039 d = numberOfDesktops();
01040 if (c && !c->isDesktop()
01041 && !c->isDock() && !c->isTopMenu())
01042 {
01043 setClientIsMoving( c );
01044 setCurrentDesktop( d );
01045 setClientIsMoving( NULL );
01046 }
01047 }
01048
01049 void Workspace::slotWindowToDesktopRight()
01050 {
01051 int d = desktopToRight( currentDesktop(), options->rollOverDesktops);
01052 if( d == currentDesktop())
01053 return;
01054 Client* c = active_popup_client ? active_popup_client : active_client;
01055 if (c && !c->isDesktop()
01056 && !c->isDock() && !c->isTopMenu())
01057 {
01058 setClientIsMoving( c );
01059 setCurrentDesktop( d );
01060 setClientIsMoving( NULL );
01061 }
01062 }
01063
01064 void Workspace::slotWindowToDesktopLeft()
01065 {
01066 int d = desktopToLeft( currentDesktop(), options->rollOverDesktops);
01067 if( d == currentDesktop())
01068 return;
01069 Client* c = active_popup_client ? active_popup_client : active_client;
01070 if (c && !c->isDesktop()
01071 && !c->isDock() && !c->isTopMenu())
01072 {
01073 setClientIsMoving( c );
01074 setCurrentDesktop( d );
01075 setClientIsMoving( NULL );
01076 }
01077 }
01078
01079 void Workspace::slotWindowToDesktopUp()
01080 {
01081 int d = desktopUp( currentDesktop(), options->rollOverDesktops);
01082 if( d == currentDesktop())
01083 return;
01084 Client* c = active_popup_client ? active_popup_client : active_client;
01085 if (c && !c->isDesktop()
01086 && !c->isDock() && !c->isTopMenu())
01087 {
01088 setClientIsMoving( c );
01089 setCurrentDesktop( d );
01090 setClientIsMoving( NULL );
01091 }
01092 }
01093
01094 void Workspace::slotWindowToDesktopDown()
01095 {
01096 int d = desktopDown( currentDesktop(), options->rollOverDesktops);
01097 if( d == currentDesktop())
01098 return;
01099 Client* c = active_popup_client ? active_popup_client : active_client;
01100 if (c && !c->isDesktop()
01101 && !c->isDock() && !c->isTopMenu())
01102 {
01103 setClientIsMoving( c );
01104 setCurrentDesktop( d );
01105 setClientIsMoving( NULL );
01106 }
01107 }
01108
01109
01113 void Workspace::slotKillWindow()
01114 {
01115 KillWindow kill( this );
01116 kill.start();
01117 }
01118
01124 void Workspace::slotSendToDesktop( QAction *action )
01125 {
01126 int desk = action->data().toInt();
01127 if ( !active_popup_client )
01128 return;
01129 if ( desk == 0 )
01130 {
01131 active_popup_client->setOnAllDesktops( !active_popup_client->isOnAllDesktops());
01132 return;
01133 }
01134
01135 sendClientToDesktop( active_popup_client, desk, false );
01136
01137 }
01138
01142 void Workspace::slotWindowOperations()
01143 {
01144 if ( !active_client )
01145 return;
01146 QPoint pos = active_client->pos() + active_client->clientPos();
01147 showWindowMenu( pos.x(), pos.y(), active_client );
01148 }
01149
01150 void Workspace::showWindowMenu( const QRect &pos, Client* cl )
01151 {
01152 if (!KAuthorized::authorizeKAction("kwin_rmb"))
01153 return;
01154 if( !cl )
01155 return;
01156 if( active_popup_client != NULL )
01157 return;
01158 if ( cl->isDesktop()
01159 || cl->isDock()
01160 || cl->isTopMenu())
01161 return;
01162
01163 active_popup_client = cl;
01164 QMenu* p = clientPopup();
01165 active_popup = p;
01166 int x = pos.left();
01167 int y = pos.bottom();
01168 if (y == pos.top())
01169 p->exec( QPoint( x, y ) );
01170 else
01171 {
01172 QRect area = clientArea(ScreenArea, QPoint(x, y), currentDesktop());
01173 clientPopupAboutToShow();
01174 int popupHeight = p->sizeHint().height();
01175 if (y + popupHeight < area.height())
01176 p->exec( QPoint( x, y ) );
01177 else
01178 p->exec( QPoint( x, pos.top() - popupHeight ) );
01179 }
01180
01181 if( active_popup == p )
01182 closeActivePopup();
01183 }
01184
01188 void Workspace::slotWindowClose()
01189 {
01190 if ( tab_box->isVisible())
01191 return;
01192 Client* c = active_popup_client ? active_popup_client : active_client;
01193 performWindowOperation( c, Options::CloseOp );
01194 }
01195
01199 void Workspace::slotWindowMove()
01200 {
01201 Client* c = active_popup_client ? active_popup_client : active_client;
01202 performWindowOperation( c, Options::UnrestrictedMoveOp );
01203 }
01204
01208 void Workspace::slotWindowResize()
01209 {
01210 Client* c = active_popup_client ? active_popup_client : active_client;
01211 performWindowOperation( c, Options::UnrestrictedResizeOp );
01212 }
01213
01214 void Client::setShortcut( const QString& _cut )
01215 {
01216 QString cut = rules()->checkShortcut( _cut );
01217 if( cut.isEmpty())
01218 return setShortcutInternal( KShortcut());
01219
01220
01221
01222 if( !cut.contains( '(' ) && !cut.contains( ')' ) && !cut.contains( ' ' ))
01223 {
01224 if( workspace()->shortcutAvailable( KShortcut( cut ), this ))
01225 setShortcutInternal( KShortcut( cut ));
01226 else
01227 setShortcutInternal( KShortcut());
01228 return;
01229 }
01230 QList< KShortcut > keys;
01231 QStringList groups = cut.split( ' ');
01232 for( QStringList::ConstIterator it = groups.constBegin();
01233 it != groups.constEnd();
01234 ++it )
01235 {
01236 QRegExp reg( "(.*\\+)\\((.*)\\)" );
01237 if( reg.indexIn( *it ) > -1 )
01238 {
01239 QString base = reg.cap( 1 );
01240 QString list = reg.cap( 2 );
01241 for( int i = 0;
01242 i < list.length();
01243 ++i )
01244 {
01245 KShortcut c( base + list[ i ] );
01246 if( !c.isEmpty())
01247 keys.append( c );
01248 }
01249 }
01250 }
01251 for( QList< KShortcut >::ConstIterator it = keys.constBegin();
01252 it != keys.constEnd();
01253 ++it )
01254 {
01255 if( _shortcut == *it )
01256 return;
01257 }
01258 for( QList< KShortcut >::ConstIterator it = keys.constBegin();
01259 it != keys.constEnd();
01260 ++it )
01261 {
01262 if( workspace()->shortcutAvailable( *it, this ))
01263 {
01264 setShortcutInternal( *it );
01265 return;
01266 }
01267 }
01268 setShortcutInternal( KShortcut());
01269 }
01270
01271 void Client::setShortcutInternal( const KShortcut& cut )
01272 {
01273 if( _shortcut == cut )
01274 return;
01275 _shortcut = cut;
01276 updateCaption();
01277 #if 0
01278 workspace()->clientShortcutUpdated( this );
01279 #else
01280
01281
01282
01283 QTimer::singleShot( 0, this, SLOT( delayedSetShortcut()));
01284 #endif
01285 }
01286
01287 void Client::delayedSetShortcut()
01288 {
01289 workspace()->clientShortcutUpdated( this );
01290 }
01291
01292 bool Workspace::shortcutAvailable( const KShortcut& cut, Client* ignore ) const
01293 {
01294
01295 for( ClientList::ConstIterator it = clients.constBegin();
01296 it != clients.constEnd();
01297 ++it )
01298 {
01299 if( (*it) != ignore && (*it)->shortcut() == cut )
01300 return false;
01301 }
01302 return true;
01303 }
01304
01305 }