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