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->setEnabled( false );
00285 disable_shortcuts_keys->setEnabled( false );
00286 client_keys->setEnabled( false );
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->setEnabled( true );
00306 disable_shortcuts_keys->setEnabled( true );
00307 client_keys->setEnabled( true );
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 case Options::MinimizeOp:
00395 c->minimize();
00396 break;
00397 case Options::ShadeOp:
00398 c->performMouseCommand( Options::MouseShade, QCursor::pos());
00399 break;
00400 case Options::OnAllDesktopsOp:
00401 c->setOnAllDesktops( !c->isOnAllDesktops() );
00402 break;
00403 case Options::FullScreenOp:
00404 c->setFullScreen( !c->isFullScreen(), true );
00405 break;
00406 case Options::NoBorderOp:
00407 c->setUserNoBorder( !c->isUserNoBorder());
00408 break;
00409 case Options::KeepAboveOp:
00410 {
00411 StackingUpdatesBlocker blocker( this );
00412 bool was = c->keepAbove();
00413 c->setKeepAbove( !c->keepAbove() );
00414 if( was && !c->keepAbove())
00415 raiseClient( c );
00416 break;
00417 }
00418 case Options::KeepBelowOp:
00419 {
00420 StackingUpdatesBlocker blocker( this );
00421 bool was = c->keepBelow();
00422 c->setKeepBelow( !c->keepBelow() );
00423 if( was && !c->keepBelow())
00424 lowerClient( c );
00425 break;
00426 }
00427 case Options::OperationsOp:
00428 c->performMouseCommand( Options::MouseShade, QCursor::pos());
00429 break;
00430 case Options::WindowRulesOp:
00431 editWindowRules( c, false );
00432 break;
00433 case Options::ApplicationRulesOp:
00434 editWindowRules( c, true );
00435 break;
00436 case Options::SetupWindowShortcutOp:
00437 setupWindowShortcut( c );
00438 break;
00439 case Options::LowerOp:
00440 lowerClient(c);
00441 break;
00442 case Options::NoOp:
00443 break;
00444 }
00445 }
00446
00450 bool Client::performMouseCommand( Options::MouseCommand command, QPoint globalPos, bool handled )
00451 {
00452 bool replay = FALSE;
00453 switch (command)
00454 {
00455 case Options::MouseRaise:
00456 workspace()->raiseClient( this );
00457 break;
00458 case Options::MouseLower:
00459 workspace()->lowerClient( this );
00460 break;
00461 case Options::MouseShade :
00462 toggleShade();
00463 cancelShadeHover();
00464 break;
00465 case Options::MouseSetShade:
00466 setShade( ShadeNormal );
00467 cancelShadeHover();
00468 break;
00469 case Options::MouseUnsetShade:
00470 setShade( ShadeNone );
00471 cancelShadeHover();
00472 break;
00473 case Options::MouseOperationsMenu:
00474 if ( isActive() & options->clickRaise )
00475 autoRaise();
00476 workspace()->showWindowMenu( globalPos, this );
00477 break;
00478 case Options::MouseToggleRaiseAndLower:
00479 workspace()->raiseOrLowerClient( this );
00480 break;
00481 case Options::MouseActivateAndRaise:
00482 replay = isActive();
00483 workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled && replay );
00484 break;
00485 case Options::MouseActivateAndLower:
00486 workspace()->requestFocus( this );
00487 workspace()->lowerClient( this );
00488 break;
00489 case Options::MouseActivate:
00490 replay = isActive();
00491 workspace()->takeActivity( this, ActivityFocus, handled && replay );
00492 break;
00493 case Options::MouseActivateRaiseAndPassClick:
00494 workspace()->takeActivity( this, ActivityFocus | ActivityRaise, handled );
00495 replay = TRUE;
00496 break;
00497 case Options::MouseActivateAndPassClick:
00498 workspace()->takeActivity( this, ActivityFocus, handled );
00499 replay = TRUE;
00500 break;
00501 case Options::MouseActivateRaiseAndMove:
00502 case Options::MouseActivateRaiseAndUnrestrictedMove:
00503 workspace()->raiseClient( this );
00504 workspace()->requestFocus( this );
00505 if( options->moveMode == Options::Transparent && isMovable())
00506 move_faked_activity = workspace()->fakeRequestedActivity( this );
00507
00508 case Options::MouseMove:
00509 case Options::MouseUnrestrictedMove:
00510 {
00511 if (!isMovable())
00512 break;
00513 if( moveResizeMode )
00514 finishMoveResize( false );
00515 mode = PositionCenter;
00516 buttonDown = TRUE;
00517 moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y());
00518 invertedMoveOffset = rect().bottomRight() - moveOffset;
00519 unrestrictedMoveResize = ( command == Options::MouseActivateRaiseAndUnrestrictedMove
00520 || command == Options::MouseUnrestrictedMove );
00521 setCursor( mode );
00522 if( !startMoveResize())
00523 {
00524 buttonDown = false;
00525 setCursor( mode );
00526 }
00527 break;
00528 }
00529 case Options::MouseResize:
00530 case Options::MouseUnrestrictedResize:
00531 {
00532 if (!isResizable() || isShade())
00533 break;
00534 if( moveResizeMode )
00535 finishMoveResize( false );
00536 buttonDown = TRUE;
00537 moveOffset = QPoint( globalPos.x() - x(), globalPos.y() - y());
00538 int x = moveOffset.x(), y = moveOffset.y();
00539 bool left = x < width() / 3;
00540 bool right = x >= 2 * width() / 3;
00541 bool top = y < height() / 3;
00542 bool bot = y >= 2 * height() / 3;
00543 if (top)
00544 mode = left ? PositionTopLeft : (right ? PositionTopRight : PositionTop);
00545 else if (bot)
00546 mode = left ? PositionBottomLeft : (right ? PositionBottomRight : PositionBottom);
00547 else
00548 mode = (x < width() / 2) ? PositionLeft : PositionRight;
00549 invertedMoveOffset = rect().bottomRight() - moveOffset;
00550 unrestrictedMoveResize = ( command == Options::MouseUnrestrictedResize );
00551 setCursor( mode );
00552 if( !startMoveResize())
00553 {
00554 buttonDown = false;
00555 setCursor( mode );
00556 }
00557 break;
00558 }
00559 case Options::MouseMaximize:
00560 maximize( Client::MaximizeFull );
00561 break;
00562 case Options::MouseRestore:
00563 maximize( Client::MaximizeRestore );
00564 break;
00565 case Options::MouseMinimize:
00566 minimize();
00567 break;
00568 case Options::MouseAbove:
00569 {
00570 StackingUpdatesBlocker blocker( workspace());
00571 if( keepBelow())
00572 setKeepBelow( false );
00573 else
00574 setKeepAbove( true );
00575 break;
00576 }
00577 case Options::MouseBelow:
00578 {
00579 StackingUpdatesBlocker blocker( workspace());
00580 if( keepAbove())
00581 setKeepAbove( false );
00582 else
00583 setKeepBelow( true );
00584 break;
00585 }
00586 case Options::MousePreviousDesktop:
00587 workspace()->windowToPreviousDesktop( this );
00588 break;
00589 case Options::MouseNextDesktop:
00590 workspace()->windowToNextDesktop( this );
00591 break;
00592 case Options::MouseOpacityMore:
00593 if (opacity_ < 0xFFFFFFFF)
00594 {
00595 if (opacity_ < 0xF3333333)
00596 {
00597 setOpacity(TRUE, opacity_ + 0xCCCCCCC);
00598 custom_opacity = true;
00599 }
00600 else
00601 {
00602 setOpacity(FALSE, 0xFFFFFFFF);
00603 custom_opacity = false;
00604 }
00605 }
00606 break;
00607 case Options::MouseOpacityLess:
00608 if (opacity_ > 0)
00609 {
00610 setOpacity(TRUE, (opacity_ > 0xCCCCCCC) ? opacity_ - 0xCCCCCCC : 0);
00611 custom_opacity = true;
00612 }
00613 break;
00614 case Options::MouseNothing:
00615 replay = TRUE;
00616 break;
00617 }
00618 return replay;
00619 }
00620
00621
00622 void Workspace::showWindowMenuAt( unsigned long, int, int )
00623 {
00624 slotWindowOperations();
00625 }
00626
00627 void Workspace::slotActivateAttentionWindow()
00628 {
00629 if( attention_chain.count() > 0 )
00630 activateClient( attention_chain.first());
00631 }
00632
00633 void Workspace::slotSwitchDesktopNext()
00634 {
00635 int d = currentDesktop() + 1;
00636 if ( d > numberOfDesktops() )
00637 {
00638 if ( options->rollOverDesktops )
00639 {
00640 d = 1;
00641 }
00642 else
00643 {
00644 return;
00645 }
00646 }
00647 setCurrentDesktop(d);
00648 }
00649
00650 void Workspace::slotSwitchDesktopPrevious()
00651 {
00652 int d = currentDesktop() - 1;
00653 if ( d <= 0 )
00654 {
00655 if ( options->rollOverDesktops )
00656 d = numberOfDesktops();
00657 else
00658 return;
00659 }
00660 setCurrentDesktop(d);
00661 }
00662
00663 void Workspace::slotSwitchDesktopRight()
00664 {
00665 int desktop = desktopToRight( currentDesktop());
00666 if( desktop == currentDesktop())
00667 return;
00668 setCurrentDesktop( desktop );
00669 }
00670
00671 void Workspace::slotSwitchDesktopLeft()
00672 {
00673 int desktop = desktopToLeft( currentDesktop());
00674 if( desktop == currentDesktop())
00675 return;
00676 setCurrentDesktop( desktop );
00677 }
00678
00679 void Workspace::slotSwitchDesktopUp()
00680 {
00681 int desktop = desktopUp( currentDesktop());
00682 if( desktop == currentDesktop())
00683 return;
00684 setCurrentDesktop( desktop );
00685 }
00686
00687 void Workspace::slotSwitchDesktopDown()
00688 {
00689 int desktop = desktopDown( currentDesktop());
00690 if( desktop == currentDesktop())
00691 return;
00692 setCurrentDesktop( desktop );
00693 }
00694
00695 void Workspace::slotSwitchToDesktop( int i )
00696 {
00697 setCurrentDesktop( i );
00698 }
00699
00700
00701 void Workspace::slotWindowToDesktop( int i )
00702 {
00703 Client* c = active_popup_client ? active_popup_client : active_client;
00704 if( i >= 1 && i <= numberOfDesktops() && c
00705 && !c->isDesktop()
00706 && !c->isDock()
00707 && !c->isTopMenu())
00708 sendClientToDesktop( c, i, true );
00709 }
00710
00714 void Workspace::slotWindowMaximize()
00715 {
00716 Client* c = active_popup_client ? active_popup_client : active_client;
00717 if ( c )
00718 performWindowOperation( c, Options::MaximizeOp );
00719 }
00720
00724 void Workspace::slotWindowMaximizeVertical()
00725 {
00726 Client* c = active_popup_client ? active_popup_client : active_client;
00727 if ( c )
00728 performWindowOperation( c, Options::VMaximizeOp );
00729 }
00730
00734 void Workspace::slotWindowMaximizeHorizontal()
00735 {
00736 Client* c = active_popup_client ? active_popup_client : active_client;
00737 if ( c )
00738 performWindowOperation( c, Options::HMaximizeOp );
00739 }
00740
00741
00745 void Workspace::slotWindowMinimize()
00746 {
00747 Client* c = active_popup_client ? active_popup_client : active_client;
00748 performWindowOperation( c, Options::MinimizeOp );
00749 }
00750
00754 void Workspace::slotWindowShade()
00755 {
00756 Client* c = active_popup_client ? active_popup_client : active_client;
00757 performWindowOperation( c, Options::ShadeOp );
00758 }
00759
00763 void Workspace::slotWindowRaise()
00764 {
00765 Client* c = active_popup_client ? active_popup_client : active_client;
00766 if ( c )
00767 raiseClient( c );
00768 }
00769
00773 void Workspace::slotWindowLower()
00774 {
00775 Client* c = active_popup_client ? active_popup_client : active_client;
00776 if ( c )
00777 lowerClient( c );
00778 }
00779
00783 void Workspace::slotWindowRaiseOrLower()
00784 {
00785 Client* c = active_popup_client ? active_popup_client : active_client;
00786 if ( c )
00787 raiseOrLowerClient( c );
00788 }
00789
00790 void Workspace::slotWindowOnAllDesktops()
00791 {
00792 Client* c = active_popup_client ? active_popup_client : active_client;
00793 if( c )
00794 c->setOnAllDesktops( !c->isOnAllDesktops());
00795 }
00796
00797 void Workspace::slotWindowFullScreen()
00798 {
00799 Client* c = active_popup_client ? active_popup_client : active_client;
00800 if( c )
00801 performWindowOperation( c, Options::FullScreenOp );
00802 }
00803
00804 void Workspace::slotWindowNoBorder()
00805 {
00806 Client* c = active_popup_client ? active_popup_client : active_client;
00807 if( c )
00808 performWindowOperation( c, Options::NoBorderOp );
00809 }
00810
00811 void Workspace::slotWindowAbove()
00812 {
00813 Client* c = active_popup_client ? active_popup_client : active_client;
00814 if( c )
00815 performWindowOperation( c, Options::KeepAboveOp );
00816 }
00817
00818 void Workspace::slotWindowBelow()
00819 {
00820 Client* c = active_popup_client ? active_popup_client : active_client;
00821 if( c )
00822 performWindowOperation( c, Options::KeepBelowOp );
00823 }
00824 void Workspace::slotSetupWindowShortcut()
00825 {
00826 Client* c = active_popup_client ? active_popup_client : active_client;
00827 if( c )
00828 performWindowOperation( c, Options::SetupWindowShortcutOp );
00829 }
00830
00834 void Workspace::slotWindowToNextDesktop()
00835 {
00836 windowToNextDesktop( active_popup_client ? active_popup_client : active_client );
00837 }
00838
00839 void Workspace::windowToNextDesktop( Client* c )
00840 {
00841 int d = currentDesktop() + 1;
00842 if ( d > numberOfDesktops() )
00843 d = 1;
00844 if (c && !c->isDesktop()
00845 && !c->isDock() && !c->isTopMenu())
00846 {
00847 setClientIsMoving( c );
00848 setCurrentDesktop( d );
00849 setClientIsMoving( NULL );
00850 }
00851 }
00852
00856 void Workspace::slotWindowToPreviousDesktop()
00857 {
00858 windowToPreviousDesktop( active_popup_client ? active_popup_client : active_client );
00859 }
00860
00861 void Workspace::windowToPreviousDesktop( Client* c )
00862 {
00863 int d = currentDesktop() - 1;
00864 if ( d <= 0 )
00865 d = numberOfDesktops();
00866 if (c && !c->isDesktop()
00867 && !c->isDock() && !c->isTopMenu())
00868 {
00869 setClientIsMoving( c );
00870 setCurrentDesktop( d );
00871 setClientIsMoving( NULL );
00872 }
00873 }
00874
00875 void Workspace::slotWindowToDesktopRight()
00876 {
00877 int d = desktopToRight( currentDesktop());
00878 if( d == currentDesktop())
00879 return;
00880 Client* c = active_popup_client ? active_popup_client : active_client;
00881 if (c && !c->isDesktop()
00882 && !c->isDock() && !c->isTopMenu())
00883 {
00884 setClientIsMoving( c );
00885 setCurrentDesktop( d );
00886 setClientIsMoving( NULL );
00887 }
00888 }
00889
00890 void Workspace::slotWindowToDesktopLeft()
00891 {
00892 int d = desktopToLeft( currentDesktop());
00893 if( d == currentDesktop())
00894 return;
00895 Client* c = active_popup_client ? active_popup_client : active_client;
00896 if (c && !c->isDesktop()
00897 && !c->isDock() && !c->isTopMenu())
00898 {
00899 setClientIsMoving( c );
00900 setCurrentDesktop( d );
00901 setClientIsMoving( NULL );
00902 }
00903 }
00904
00905 void Workspace::slotWindowToDesktopUp()
00906 {
00907 int d = desktopUp( currentDesktop());
00908 if( d == currentDesktop())
00909 return;
00910 Client* c = active_popup_client ? active_popup_client : active_client;
00911 if (c && !c->isDesktop()
00912 && !c->isDock() && !c->isTopMenu())
00913 {
00914 setClientIsMoving( c );
00915 setCurrentDesktop( d );
00916 setClientIsMoving( NULL );
00917 }
00918 }
00919
00920 void Workspace::slotWindowToDesktopDown()
00921 {
00922 int d = desktopDown( currentDesktop());
00923 if( d == currentDesktop())
00924 return;
00925 Client* c = active_popup_client ? active_popup_client : active_client;
00926 if (c && !c->isDesktop()
00927 && !c->isDock() && !c->isTopMenu())
00928 {
00929 setClientIsMoving( c );
00930 setCurrentDesktop( d );
00931 setClientIsMoving( NULL );
00932 }
00933 }
00934
00935
00939 void Workspace::slotKillWindow()
00940 {
00941 KillWindow kill( this );
00942 kill.start();
00943 }
00944
00950 void Workspace::slotSendToDesktop( int desk )
00951 {
00952 if ( !active_popup_client )
00953 return;
00954 if ( desk == 0 )
00955 {
00956 active_popup_client->setOnAllDesktops( !active_popup_client->isOnAllDesktops());
00957 return;
00958 }
00959
00960 sendClientToDesktop( active_popup_client, desk, false );
00961
00962 }
00963
00967 void Workspace::slotWindowOperations()
00968 {
00969 if ( !active_client )
00970 return;
00971 QPoint pos = active_client->pos() + active_client->clientPos();
00972 showWindowMenu( pos.x(), pos.y(), active_client );
00973 }
00974
00975 void Workspace::showWindowMenu( const QRect &pos, Client* cl )
00976 {
00977 if (!kapp->authorizeKAction("kwin_rmb"))
00978 return;
00979 if( !cl )
00980 return;
00981 if( active_popup_client != NULL )
00982 return;
00983 if ( cl->isDesktop()
00984 || cl->isDock()
00985 || cl->isTopMenu())
00986 return;
00987
00988 active_popup_client = cl;
00989 QPopupMenu* p = clientPopup();
00990 active_popup = p;
00991 int x = pos.left();
00992 int y = pos.bottom();
00993 if (y == pos.top())
00994 p->exec( QPoint( x, y ) );
00995 else
00996 {
00997 QRect area = clientArea(ScreenArea, QPoint(x, y), currentDesktop());
00998 clientPopupAboutToShow();
00999 int popupHeight = p->sizeHint().height();
01000 if (y + popupHeight < area.height())
01001 p->exec( QPoint( x, y ) );
01002 else
01003 p->exec( QPoint( x, pos.top() - popupHeight ) );
01004 }
01005
01006 if( active_popup == p )
01007 closeActivePopup();
01008 }
01009
01013 void Workspace::slotWindowClose()
01014 {
01015 if ( tab_box->isVisible())
01016 return;
01017 Client* c = active_popup_client ? active_popup_client : active_client;
01018 performWindowOperation( c, Options::CloseOp );
01019 }
01020
01024 void Workspace::slotWindowMove()
01025 {
01026 Client* c = active_popup_client ? active_popup_client : active_client;
01027 performWindowOperation( c, Options::UnrestrictedMoveOp );
01028 }
01029
01033 void Workspace::slotWindowResize()
01034 {
01035 Client* c = active_popup_client ? active_popup_client : active_client;
01036 performWindowOperation( c, Options::UnrestrictedResizeOp );
01037 }
01038
01039 void Client::setShortcut( const QString& _cut )
01040 {
01041 QString cut = rules()->checkShortcut( _cut );
01042 if( cut.isEmpty())
01043 return setShortcutInternal( KShortcut());
01044
01045
01046
01047 if( !cut.contains( '(' ) && !cut.contains( ')' ) && !cut.contains( ' ' ))
01048 {
01049 if( workspace()->shortcutAvailable( KShortcut( cut ), this ))
01050 setShortcutInternal( KShortcut( cut ));
01051 else
01052 setShortcutInternal( KShortcut());
01053 return;
01054 }
01055 QValueList< KShortcut > keys;
01056 QStringList groups = QStringList::split( ' ', cut );
01057 for( QStringList::ConstIterator it = groups.begin();
01058 it != groups.end();
01059 ++it )
01060 {
01061 QRegExp reg( "(.*\\+)\\((.*)\\)" );
01062 if( reg.search( *it ) > -1 )
01063 {
01064 QString base = reg.cap( 1 );
01065 QString list = reg.cap( 2 );
01066 for( unsigned int i = 0;
01067 i < list.length();
01068 ++i )
01069 {
01070 KShortcut c( base + list[ i ] );
01071 if( !c.isNull())
01072 keys.append( c );
01073 }
01074 }
01075 }
01076 for( QValueList< KShortcut >::ConstIterator it = keys.begin();
01077 it != keys.end();
01078 ++it )
01079 {
01080 if( _shortcut == *it )
01081 return;
01082 }
01083 for( QValueList< KShortcut >::ConstIterator it = keys.begin();
01084 it != keys.end();
01085 ++it )
01086 {
01087 if( workspace()->shortcutAvailable( *it, this ))
01088 {
01089 setShortcutInternal( *it );
01090 return;
01091 }
01092 }
01093 setShortcutInternal( KShortcut());
01094 }
01095
01096 void Client::setShortcutInternal( const KShortcut& cut )
01097 {
01098 if( _shortcut == cut )
01099 return;
01100 _shortcut = cut;
01101 updateCaption();
01102 workspace()->clientShortcutUpdated( this );
01103 }
01104
01105 bool Workspace::shortcutAvailable( const KShortcut& cut, Client* ignore ) const
01106 {
01107
01108 for( ClientList::ConstIterator it = clients.begin();
01109 it != clients.end();
01110 ++it )
01111 {
01112 if( (*it) != ignore && (*it)->shortcut() == cut )
01113 return false;
01114 }
01115 return true;
01116 }
01117
01118 }