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